diff --git a/kernel/branches/Kolibri-acpi/blkdev/bd_drv.inc b/kernel/branches/Kolibri-acpi/blkdev/bd_drv.inc index 92cfe7bb9b..427e2c8986 100644 --- a/kernel/branches/Kolibri-acpi/blkdev/bd_drv.inc +++ b/kernel/branches/Kolibri-acpi/blkdev/bd_drv.inc @@ -11,14 +11,14 @@ $Revision: 4420 $ iglobal align 4 bd_callbacks: - dd bd_callbacks.end - bd_callbacks ; strucsize - dd 0 ; no close function - dd 0 ; no closemedia function + dd bd_callbacks.end - bd_callbacks ; strucsize + dd 0 ; no close function + dd 0 ; no closemedia function dd bd_querymedia dd bd_read_interface dd bd_write_interface - dd 0 ; no flush function - dd 0 ; use default cache size + dd 0 ; no flush function + dd 0 ; use default cache size .end: endg @@ -238,9 +238,9 @@ int13_call: ; Because this code uses fixed addresses, ; it can not be run simultaniously by many threads. ; In current implementation it is protected by common mutex 'ide_status' - mov word [OS_BASE + 510h], 10h ; packet length - mov word [OS_BASE + 512h], cx ; number of sectors - mov dword [OS_BASE + 514h], 9A000000h ; buffer 9A00:0000 + mov word [OS_BASE + 510h], 10h ; packet length + mov word [OS_BASE + 512h], cx ; number of sectors + mov dword [OS_BASE + 514h], 9A000000h ; buffer 9A00:0000 mov dword [OS_BASE + 518h], eax and dword [OS_BASE + 51Ch], 0 push ebx ecx esi edi diff --git a/kernel/branches/Kolibri-acpi/blkdev/hd_drv.inc b/kernel/branches/Kolibri-acpi/blkdev/hd_drv.inc index 5e2e89c8e9..69a732a694 100644 --- a/kernel/branches/Kolibri-acpi/blkdev/hd_drv.inc +++ b/kernel/branches/Kolibri-acpi/blkdev/hd_drv.inc @@ -10,44 +10,45 @@ $Revision$ ; HDD driver struct HD_DATA -hdbase dd ? -hdid dd ? -hdpos dd ? +hdbase dw ? +hdid dw ? +hdpos dw ? +hd48 dw ? ends ;----------------------------------------------------------------- iglobal align 4 ide_callbacks: - dd ide_callbacks.end - ide_callbacks ; strucsize - dd 0 ; no close function - dd 0 ; no closemedia function - dd ide_querymedia - dd ide_read - dd ide_write - dd 0 ; no flush function - dd 0 ; use default cache size + dd ide_callbacks.end - ide_callbacks + dd 0 ; no close function + dd 0 ; no closemedia function + dd ide_querymedia + dd ide_read + dd ide_write + dd 0 ; no flush function + dd 0 ; use default cache size .end: -hd0_data HD_DATA ?, 0, 1 -hd1_data HD_DATA ?, 0x10, 2 -hd2_data HD_DATA ?, 0, 3 -hd3_data HD_DATA ?, 0x10, 4 -hd4_data HD_DATA ?, 0, 5 -hd5_data HD_DATA ?, 0x10, 6 -hd6_data HD_DATA ?, 0, 7 -hd7_data HD_DATA ?, 0x10, 8 -hd8_data HD_DATA ?, 0, 9 -hd9_data HD_DATA ?, 0x10, 10 -hd10_data HD_DATA ?, 0, 11 -hd11_data HD_DATA ?, 0x10, 12 +hd0_data HD_DATA ?, 0, 1, 0 +hd1_data HD_DATA ?, 16, 2, 0 +hd2_data HD_DATA ?, 0, 3, 0 +hd3_data HD_DATA ?, 16, 4, 0 +hd4_data HD_DATA ?, 0, 5, 0 +hd5_data HD_DATA ?, 16, 6, 0 +hd6_data HD_DATA ?, 0, 7, 0 +hd7_data HD_DATA ?, 16, 8, 0 +hd8_data HD_DATA ?, 0, 9, 0 +hd9_data HD_DATA ?, 16, 10, 0 +hd10_data HD_DATA ?, 0, 11, 0 +hd11_data HD_DATA ?, 16, 12, 0 ide_mutex_table: - dd ide_channel1_mutex - dd ide_channel2_mutex - dd ide_channel3_mutex - dd ide_channel4_mutex - dd ide_channel5_mutex - dd ide_channel6_mutex + dd ide_channel1_mutex + dd ide_channel2_mutex + dd ide_channel3_mutex + dd ide_channel4_mutex + dd ide_channel5_mutex + dd ide_channel6_mutex endg ;----------------------------------------------------------------- uglobal @@ -74,7 +75,6 @@ ide_read: ide_write: mov al, 35h ; WRITE DMA EXT -; fall through to ide_read_write proc ide_read_write stdcall uses esi edi ebx, \ hd_data, buffer, startsector:qword, numsectors @@ -86,9 +86,8 @@ proc ide_read_write stdcall uses esi edi ebx, \ locals sectors_todo dd ? channel_lock dd ? -operation db ? endl - mov [operation], al + mov bl, al ; get number of requested sectors and say that no sectors were read yet mov ecx, [numsectors] mov eax, [ecx] @@ -98,7 +97,7 @@ endl mov ecx, ide_mutex call mutex_lock mov ecx, [hd_data] - mov ecx, [ecx+HD_DATA.hdpos] + movzx ecx, [ecx+HD_DATA.hdpos] dec ecx shr ecx, 1 shl ecx, 2 @@ -106,21 +105,21 @@ endl mov [channel_lock], ecx call mutex_lock ; prepare worker procedures variables - mov ecx, [hd_data] - mov eax, [ecx+HD_DATA.hdbase] - mov [hdbase], eax - mov eax, [ecx+HD_DATA.hdid] - mov [hdid], eax - mov eax, [ecx+HD_DATA.hdpos] - mov [hdpos], eax - mov eax, dword [startsector] - mov [sector], eax - mov ax, word [startsector+4] - mov [sector+4], ax mov esi, [buffer] mov edi, esi - mov bl, [operation] - mov ecx, [hdpos] + mov ecx, [hd_data] + movzx eax, [ecx+HD_DATA.hdbase] + mov [hdbase], eax + mov ax, [ecx+HD_DATA.hdid] + mov [hdid], eax + mov eax, dword [startsector] + mov [sector], eax + cmp [ecx+HD_DATA.hd48], 0 + jz .LBA28 + mov ax, word [startsector+4] + mov [sector+4], ax + movzx ecx, [ecx+HD_DATA.hdpos] + mov [hdpos], ecx dec ecx shr ecx, 2 imul ecx, sizeof.IDE_DATA @@ -134,7 +133,7 @@ endl cmp [eax+IDE_DATA.dma_hdd_channel_1], 1 jz .next dec ebx ; READ/WRITE SECTOR(S) EXT -; worker procedures take max 8000h sectors per time +; LBA48 supports max 10000h sectors per time ; loop until all sectors will be processed .next: mov ecx, 8000h @@ -154,6 +153,30 @@ endl add [sector], ecx adc word [sector+4], 0 jmp .next +.LBA28: + add eax, [sectors_todo] + add eax, 0xF0000000 + jc .out + sub bl, 5 ; READ/WRITE SECTOR(S) +; LBA28 supports max 256 sectors per time +; loop until all sectors will be processed +.next28: + mov ecx, 256 + cmp ecx, [sectors_todo] + jbe @f + mov ecx, [sectors_todo] +@@: + mov [blockSize], ecx + push ecx + call IDE_transfer.LBA28 + pop ecx + jc .out + mov eax, [numsectors] + add [eax], ecx + sub [sectors_todo], ecx + jz .out + add [sector], ecx + jmp .next28 ; loop is done, either due to error or because everything is done ; release the global lock and return the corresponding status .out: @@ -360,6 +383,42 @@ IDE_transfer: cmp [eventPointer], 0 jz .hd_error ret + +.LBA28: + mov edx, [hdbase] + add edx, 6 + mov al, byte [hdid] + add al, 224 + out dx, al ; select the desired drive + call save_hd_wait_timeout + inc edx +@@: + call check_hd_wait_timeout + jc .hd_error + in al, dx + test al, 128 ; ready for command? + jnz @b + pushfd ; fill the ports + cli + mov edx, [hdbase] + inc edx + inc edx + mov al, [blockSize] + out dx, al ; Sector count (7:0) + inc edx + mov eax, [sector] + out dx, al ; LBA (7:0) + inc edx + shr eax, 8 + out dx, al ; LBA (15:8) + inc edx + shr eax, 8 + out dx, al ; LBA (23:16) + inc edx + shr eax, 8 + add al, byte [hdid] + add al, 224 + out dx, al ; LBA (27:24) .PIO: inc edx ; ATACommand mov al, bl @@ -387,8 +446,8 @@ IDE_transfer: cld mov ecx, 256 mov edx, [hdbase] - cmp bl, 34h - jz .write + cmp bl, 30h + jnc .write rep insw jmp @f .write: diff --git a/kernel/branches/Kolibri-acpi/boot/bootcode.inc b/kernel/branches/Kolibri-acpi/boot/bootcode.inc index 26f86bb5d5..1135ac88b7 100644 --- a/kernel/branches/Kolibri-acpi/boot/bootcode.inc +++ b/kernel/branches/Kolibri-acpi/boot/bootcode.inc @@ -59,7 +59,7 @@ getkey: ; Use BIOS INT 16h to read a key from the keyboa jb getkey ; ASCII code is below lowest accepted value => continue waiting for another key. cmp al, bh ; Compare 'al' (ASCII code of key pressed) with 'bh' (highest accepted char from the range). ja getkey ; ASCII code is above highest accepted value => continue waiting for another key. - push ax ; If the pressed key is in the accepted range, save it on the stack and echo to screen. + push ax ; If the pressed key is in the accepted range, save it on the stack and echo to screen. call putchar pop ax and ax, 0Fh ; Convert ASCII code to number: '1'->1, '2'->2, etc. 0Fh=1111b. @@ -159,7 +159,7 @@ FirstDataSector dw 0 ; begin of data ; ;========================================================================= -include 'bootvesa.inc' ;Include source for boot vesa +include 'bootvesa.inc' ;Include source for boot vesa if defined extended_primary_loader include 'parsers.inc' end if @@ -176,9 +176,9 @@ if defined extended_primary_loader mov [bootfs], bx ; set up stack - mov ax, 3000h + mov ax, (TMP_STACK_TOP and 0xF0000) shr 4 mov ss, ax - mov sp, 0EC00h + mov sp, TMP_STACK_TOP and 0xFFFF ; try to load configuration file mov ax, 1 @@ -293,9 +293,9 @@ else no_hd_load: ; set up stack - mov ax, 3000h + mov ax, (TMP_STACK_TOP and 0xF0000) shr 4 mov ss, ax - mov sp, 0EC00h + mov sp, TMP_STACK_TOP and 0xFFFF ; set up segment registers push cs pop ds @@ -534,7 +534,7 @@ end if cmp byte [di+preboot_dma-preboot_device], 1 adc byte [di+preboot_dma-preboot_device], 0 cmp byte [di+preboot_launcher-preboot_device], 1 ; Start LAUNCHER by default - adc byte [di+preboot_launcher-preboot_device], 0 + adc byte [di+preboot_launcher-preboot_device], 0 ; cmp byte [di+preboot_biosdisk-preboot_device], 1 ; adc byte [di+preboot_biosdisk-preboot_device], 0 ;; default value for VRR is OFF diff --git a/kernel/branches/Kolibri-acpi/build.bat b/kernel/branches/Kolibri-acpi/build.bat index 04a1cf230b..209bb93878 100644 --- a/kernel/branches/Kolibri-acpi/build.bat +++ b/kernel/branches/Kolibri-acpi/build.bat @@ -51,7 +51,6 @@ goto :eof echo lang fix %lang% > lang.inc fasm -m 65536 kernel.asm bin\kernel.mnt if not %errorlevel%==0 goto :Error_FasmFailed - erase lang.inc goto :eof @@ -63,7 +62,6 @@ goto :Exit_OK :Error_FasmFailed echo error: fasm execution failed -erase lang.inc >nul 2>&1 echo. pause exit 1 diff --git a/kernel/branches/Kolibri-acpi/const.inc b/kernel/branches/Kolibri-acpi/const.inc index 331d527138..368e4e6547 100644 --- a/kernel/branches/Kolibri-acpi/const.inc +++ b/kernel/branches/Kolibri-acpi/const.inc @@ -544,13 +544,17 @@ WSTATE_WNDDRAWN = 00000010b WSTYLE_HASCAPTION = 00010000b WSTYLE_CLIENTRELATIVE = 00100000b +ZPOS_DESKTOP = -2 +ZPOS_ALWAYS_BACK = -1 +ZPOS_NORMAL = 0 +ZPOS_ALWAYS_TOP = 1 ;ZPOS_ALWAYS_TOP is always last and has max number! ; structures definition struct WDATA box BOX cl_workarea dd ? cl_titlebar dd ? cl_frames dd ? - reserved db ? + z_modif db ? fl_wstate db ? fl_wdrawn db ? fl_redraw db ? diff --git a/kernel/branches/Kolibri-acpi/core/apic.inc b/kernel/branches/Kolibri-acpi/core/apic.inc index a073b65ec6..d060e5994e 100644 --- a/kernel/branches/Kolibri-acpi/core/apic.inc +++ b/kernel/branches/Kolibri-acpi/core/apic.inc @@ -447,6 +447,7 @@ get_clock_ns: jz .old_tics push ebx + push esi pushfd cli @@ -456,15 +457,24 @@ get_clock_ns: mov eax, [ebx+0xF0] mov ecx, [ebx+0xF4] cmp ecx, edx - jnz @B + jne @B - mov ecx, [hpet_period] - mov ebx, edx - imul ebx, ecx - mul ecx - add edx, ebx + mul [hpet_period] + shrd eax, edx, 10 + shr edx, 10 + + mov ebx, eax + mov esi, edx + + mov eax, ecx + mul [hpet_period] + shld edx, eax, 22 + shl eax, 22 + add eax, ebx + adc edx, esi popfd + pop esi pop ebx ret diff --git a/kernel/branches/Kolibri-acpi/core/sched.inc b/kernel/branches/Kolibri-acpi/core/sched.inc index d6f1c67087..91144d7ff2 100644 --- a/kernel/branches/Kolibri-acpi/core/sched.inc +++ b/kernel/branches/Kolibri-acpi/core/sched.inc @@ -285,7 +285,7 @@ proc find_next_task call [ebx+APPDATA.wait_test] mov [esp+28], eax popad - test eax, eax + or eax, eax jnz @f ; testing for timeout mov eax, [timer_ticks] diff --git a/kernel/branches/Kolibri-acpi/core/sys32.inc b/kernel/branches/Kolibri-acpi/core/sys32.inc index b703851282..f49562d0d5 100644 --- a/kernel/branches/Kolibri-acpi/core/sys32.inc +++ b/kernel/branches/Kolibri-acpi/core/sys32.inc @@ -263,7 +263,7 @@ show_error_parameters: call .check_ESP test eax, eax jnz .error_ESP - DEBUGF 1, " [ESP+08]: %x\n",[ebx] + DEBUGF 1, " [ESP+08]: %x\n",[ebx] add ebx, 4 call .check_ESP test eax, eax @@ -293,7 +293,7 @@ show_error_parameters: call .check_ESP test eax, eax jnz .error_ESP - DEBUGF 1, " [ESP+32]: %x\n",[ebx] + DEBUGF 1, " [ESP+32]: %x\n",[ebx] pop edx ecx ebx eax ret .error_ESP: @@ -315,11 +315,11 @@ show_error_parameters: mov eax, [page_tabs+ebx*4] test eax, 2 jz .fail ;address not reserved for use. error - - pop ebx + + pop ebx xor eax, eax - ret - + ret + .fail: pop ebx xor eax, eax @@ -581,7 +581,7 @@ destroy_thread: mov [esi+WDATA.cl_workarea], eax mov [esi+WDATA.cl_titlebar], eax mov [esi+WDATA.cl_frames], eax - mov dword [esi+WDATA.reserved], eax; clear all flags: wstate, redraw, wdrawn + mov dword [esi+WDATA.z_modif], eax; clear all flags: z_modif, wstate, redraw, wdrawn lea edi, [esi-window_data+draw_data] mov ecx, 32/4 rep stosd diff --git a/kernel/branches/Kolibri-acpi/core/taskman.inc b/kernel/branches/Kolibri-acpi/core/taskman.inc index 9855df53dd..f8b5f33c32 100644 --- a/kernel/branches/Kolibri-acpi/core/taskman.inc +++ b/kernel/branches/Kolibri-acpi/core/taskman.inc @@ -898,7 +898,7 @@ endp align 4 proc new_sys_threads locals - slot dd ? + slot dd ? flags dd ? app_cmdline dd ? ;0x00 app_path dd ? ;0x04 @@ -1164,7 +1164,7 @@ proc set_app_params stdcall,slot:dword, params:dword,\ mov [ebx+REG_ECX], eax mov [ebx+REG_EAX], eax - mov eax, [esi+0x08] ;app_eip + mov eax, [esi+0x08] ;app_eip mov [ebx+REG_EIP], eax ;app_entry mov [ebx+REG_CS], dword app_code mov ecx, USER_PRIORITY diff --git a/kernel/branches/Kolibri-acpi/detect/dev_hdcd.inc b/kernel/branches/Kolibri-acpi/detect/dev_hdcd.inc index 4f07f90ace..2e58f34d71 100644 --- a/kernel/branches/Kolibri-acpi/detect/dev_hdcd.inc +++ b/kernel/branches/Kolibri-acpi/detect/dev_hdcd.inc @@ -7,61 +7,44 @@ $Revision$ +; HDD and CD search -;****************************************************** -; поиск приводов HDD и CD -; автор исходного текста Кулаков Владимир Геннадьевич. -; адаптация и доработка Mario79 -;****************************************************** - -;**************************************************** -;* ПОИСК HDD и CD * -;**************************************************** cmp [ecx+IDE_DATA.ProgrammingInterface], 0 je EndFindHDD - FindHDD: push ecx - xor ebx, ebx inc ebx - - cmp ecx, IDE_controller_2 - jne @f - + mov [DeviceNumber], 0 + cmp ecx, IDE_controller_1 + jz .find add bl, 5 - jmp .find -@@: - cmp ecx, IDE_controller_3 - jne .find - - add bl, 10 -;-------------------------------------- + add [DeviceNumber], sizeof.HD_DATA*4 + cmp ecx, IDE_controller_2 + jz .find + add bl, 5 + add [DeviceNumber], sizeof.HD_DATA*4 .find: - mov [ChannelNumber], 1 mov [DiskNumber], 0 - call FindHDD_2 + call FindHDD_1 - mov [DiskNumber], 1 + inc [DiskNumber] call FindHDD_2 inc [ChannelNumber] - - mov [DiskNumber], 0 + dec [DiskNumber] call FindHDD_2 - mov [DiskNumber], 1 - call FindHDD_1 + inc [DiskNumber] + call FindHDD_2 pop ecx jmp EndFindHDD ;----------------------------------------------------------------------------- FindHDD_2: - call FindHDD_1 + add [DeviceNumber], sizeof.HD_DATA shl byte [ebx+DRIVE_DATA], 2 - ret -;----------------------------------------------------------------------------- FindHDD_1: DEBUGF 1, "K : Channel %d ",[ChannelNumber]:2 DEBUGF 1, "Disk %d\n",[DiskNumber]:1 @@ -80,6 +63,9 @@ FindHDD_1: ja .FindCD inc byte [ebx+DRIVE_DATA] + movzx eax, [DeviceNumber] + bt word [Sector512+166], 10 + adc [eax+hd0_data.hd48], 0 jmp .Print_Device_Name ;-------------------------------------- .FindCD: @@ -262,6 +248,7 @@ StandardATABases dw ?, ? ; 1F0h, 170h ChannelNumber dw ? ; Номер диска DiskNumber db ? +DeviceNumber db ? ; Базовый адрес группы портов контроллера ATA ATABasePortAddr dw ? ; Параметры ATA-команды diff --git a/kernel/branches/Kolibri-acpi/detect/sear_par.inc b/kernel/branches/Kolibri-acpi/detect/sear_par.inc index bb0f749848..0f675bae0f 100644 --- a/kernel/branches/Kolibri-acpi/detect/sear_par.inc +++ b/kernel/branches/Kolibri-acpi/detect/sear_par.inc @@ -13,27 +13,27 @@ search_partitions: xor eax, eax mov edx, IDE_controller_1 mov ax, [edx + IDE_DATA.BAR0_val] - mov [hd0_data.hdbase], eax - mov [hd1_data.hdbase], eax + mov [hd0_data.hdbase], ax + mov [hd1_data.hdbase], ax mov ax, [edx + IDE_DATA.BAR2_val] - mov [hd2_data.hdbase], eax - mov [hd3_data.hdbase], eax + mov [hd2_data.hdbase], ax + mov [hd3_data.hdbase], ax mov edx, IDE_controller_2 mov ax, [edx + IDE_DATA.BAR0_val] - mov [hd4_data.hdbase], eax - mov [hd5_data.hdbase], eax + mov [hd4_data.hdbase], ax + mov [hd5_data.hdbase], ax mov ax, [edx + IDE_DATA.BAR2_val] - mov [hd6_data.hdbase], eax - mov [hd7_data.hdbase], eax + mov [hd6_data.hdbase], ax + mov [hd7_data.hdbase], ax mov edx, IDE_controller_3 mov ax, [edx + IDE_DATA.BAR0_val] - mov [hd8_data.hdbase], eax - mov [hd9_data.hdbase], eax + mov [hd8_data.hdbase], ax + mov [hd9_data.hdbase], ax mov ax, [edx + IDE_DATA.BAR2_val] - mov [hd10_data.hdbase], eax - mov [hd11_data.hdbase], eax + mov [hd10_data.hdbase], ax + mov [hd11_data.hdbase], ax ; 2. Notify the system about /hd* disks. ; For every existing disk, call ide_disk_add with correct parameters. ; Generate name "hdN" on the stack; this is 4 bytes including terminating zero. diff --git a/kernel/branches/Kolibri-acpi/docs/sysfuncr.txt b/kernel/branches/Kolibri-acpi/docs/sysfuncr.txt index 5a9d50056c..0327b317e8 100644 --- a/kernel/branches/Kolibri-acpi/docs/sysfuncr.txt +++ b/kernel/branches/Kolibri-acpi/docs/sysfuncr.txt @@ -194,39 +194,41 @@ * Системное время можно установить функцией 22. ====================================================================== -============== Функция 4 - вывести строку текста в окно. ============= +================ Функция 4 - нарисовать строку текста. =============== ====================================================================== Параметры: * eax = 4 - номер функции - * ebx = [координата по оси x]*65536 + [координата по оси y] - * ecx = 0xXYRRGGBB, где + * ebx = X*65536+Y, координаты в окне или буфере + * ecx = 0xXXRRGGBB, где * RR, GG, BB задают цвет текста - * X=ABnn (биты): - * nn задает используемый шрифт: 0=системный моноширинный, - 1=системный шрифт переменной ширины - * A=0 - выводить esi символов, A=1 - выводить ASCIIZ-строку - * B=1 - закрашивать фон цветом edi - * Y=Cnnn (биты): - * C=1 перенаправить вывод в область пользователя, задано в edi - * nnn - не используется в текущем виде, должно быть 0 (zero) + * XX=ABFFCSSS (биты): + * A=1 - рисуемая строка заканчивается нулём + * B=1 - закрашивать фон (цвет = edi) + * FF задает шрифт и кодировку: + 0 = 6x9 cp866 + 1 = 8x16 cp866 + 2 = 8x16 UTF-16LE + 3 = 8x16 UTF-8 + * C=0 - рисовать в окно, + С=1 - рисовать в буфер (edi) + * SSS = (множитель размера)-1, то-есть 0 = x1, 7 = x8 * edx = указатель на начало строки - * esi = для A=0 длина строки, должна быть не больше 255; - для A=1 игнорируется - * edi = цвет для закраски фона, если B=1 - * edi = указатель на область пользователя, если C=1 + * esi = для A=0 длина строки, для A=1 игнорируется + * edi = если B=1 - цвет для закраски фона, + если C=1 - указатель на буфер + Возвращаемое значение: * функция не возвращает значения Замечания: - * Первый системный шрифт считывается при загрузке из файла char.mt, - второй - из char2.mt. - * Оба шрифта имеют высоту 9 пикселей, ширина моноширинного шрифта - равна 6 пикселей. - * C=1, глубина точки = 32 бита, область пользователя выглядит так: - dword Xsize - dword Ysize - остаток области = Xsize * Y size * 4 - * Нельзя одновременно использовать B=1 и C=1, поскольку в обоих - случаях использован регистр edi для разных целей. + * Нельзя одновременно использовать B=1 и C=1, + поскольку в обоих случаях используется регистр edi. + * Если SSS=0, шрифт может сглаживаться, + в зависимости от системной настройки. + * Структура буфера: +Xsize dd +Ysize dd +picture rb Xsize*Ysize*4 ; 32 бита + ====================================================================== ========================= Функция 5 - пауза. ========================= ====================================================================== @@ -243,38 +245,6 @@ (закончить текущий квант времени), используйте подфункцию 1 функции 68. -====================================================================== -=============== Функция 6 - прочитать файл с рамдиска. =============== -====================================================================== -Параметры: - * eax = 6 - номер функции - * ebx = указатель на имя файла - * ecx = номер стартового блока, считая с 1; - ecx=0 - читать с начала файла (то же самое, что и ecx=1) - * edx = число блоков для чтения; - edx=0 - читать один блок (то же самое, что и edx=1) - * esi = указатель на область памяти, куда будут записаны данные -Возвращаемое значение: - * eax = длина файла в байтах, если файл успешно прочитан - * eax = -1, если файл не найден -Замечания: - * Данная функция является устаревшей; функция 70 - позволяет выполнять те же действия с расширенными возможностями. - * Блок = 512 байт. - * Для чтения всего файла можно указать заведомо большое значение - в edx, например, edx = -1; но в этом случае будьте готовы к тому, - что программа "упадет", если файл окажется слишком большим - и "не влезет" в память программы. - * Имя файла должно быть либо в формате 8+3 символов - (первые 8 символов - собственно имя, последние 3 - расширение, - короткие имена и расширения дополняются пробелами), - либо в формате 8.3 символов "FILE.EXT"/"FILE.EX " - (имя не более 8 символов, точка, расширение 3 символа, - дополненное при необходимости пробелами). - Имя файла должно быть записано заглавными буквами. - Завершающий символ с кодом 0 не нужен (не ASCIIZ-строка). - * Эта функция не поддерживает папки на рамдиске. - ====================================================================== =============== Функция 7 - вывести изображение в окно. ============== ====================================================================== @@ -1004,20 +974,22 @@ dd 1675 Возвращаемое значение: * функция не возвращает значения -------------- Подподфункция 2 - получить задержку мыши. -------------- +Замечание: рекомендуемая скорость = 1, 0 = заблокировать курсор. + +------------- Подподфункция 2 - получить ускорение мыши. ------------- Параметры: * eax = 18 - номер функции * ebx = 19 - номер подфункции * ecx = 2 - номер подподфункции Возвращаемое значение: - * eax = текущая задержка мыши + * eax = 0 - выключить, 1 - слабое, 2 - среднее, 3 - сильное ------------- Подподфункция 3 - установить задержку мыши. ------------- +------------ Подподфункция 3 - установить ускорение мыши. ------------ Параметры: * eax = 18 - номер функции * ebx = 19 - номер подфункции * ecx = 3 - номер подподфункции - * edx = новое значение задержки мыши + * edx = 0 - выключить, 1 - слабое, 2 - среднее, 3 - сильное Возвращаемое значение: * функция не возвращает значения @@ -1044,21 +1016,25 @@ dd 1675 * бит 4 установлен = 5-я кнопка нажата Возвращаемое значение: * функция не возвращает значения -Замечания: - * Рекомендуемая скорость мыши (в подподфункции 1) от 1 до 9. - Устанавливаемая величина не проверяется кодом ядра, поэтому - используйте осторожно, при некорректном значении курсор может - "замёрзнуть". Скорость мыши можно регулировать в приложении SETUP. - * Рекомендуемая величина задержки (в подподфункции 3) = 10. - Меньшие значения не обрабатываются COM-мышами. При очень больших - значениях невозможно передвижение мыши на 1 пиксель и курсор будет - прыгать на величину установленной скорости (подподфункция 1). - Устанавливаемая величина не проверяется кодом ядра. - Величину задержки можно менять в приложении SETUP. - * Подподфункция 4 не проверяет переданное значение. Перед вызовом - необходимо узнать текущее разрешение экрана (подфункцией 14) - и проверить, что устанавливаемое положение не выходит за пределы - экрана. + +-------- Подподфункция 6 - получить задержку двойного щелчка. -------- +Параметры: + * eax = 18 - номер функции + * ebx = 19 - номер подфункции + * ecx = 6 - номер подподфункции +Возвращаемое значение: + * eax = текущая задержка двойного щелчка (100 = секунда) + +------- Подподфункция 7 - установить задержку двойного щелчка. ------- +Параметры: + * eax = 18 - номер функции + * ebx = 19 - номер подфункции + * ecx = 7 - номер подподфункции + * dl = новое значение задержки двойного щелчка (100 = секунда) +Возвращаемое значение: + * функция не возвращает значения + +Замечание: настройки мыши можно регулировать в приложении mouse_cfg. ====================================================================== ====================== Функция 18, подфункция 20 ===================== @@ -1145,6 +1121,37 @@ dd 1675 * Размеры указываемые в функции не должны превышать размеры текущего видеорежима, иначе функция ничего не изменит. +====================================================================== +===================== Функция 18, подфункция 25 ====================== +======== Управление положением окна относительно других окон. ======== +====================================================================== + +------------- Подподфункция 1 - получить положение ------------------ +Параметры: + * eax = 18 - номер функции + * ebx = 25 - номер подфункции + * ecx = 1 - номер подподфункции + * edx = -1(для текущего окна) или PID приложения +Возвращаемое значение: + * eax = одна из констант положения окна + +------------- Подподфункция 2 - установить положение ---------------- +Параметры: + * eax = 18 - номер функции + * ebx = 25 - номер подфункции + * ecx = 2 - номер подподфункции + * edx = -1(для текущего окна) или PID приложения + * esi = новое положение окна (одна из констант ниже) +Возвращаемое значение: + * eax = 0 - неудача + * eax = 1 - успех + +Константы положения окна относительно других окон: + ZPOS_DESKTOP = -2 - на самом заднем плане + ZPOS_ALWAYS_BACK = -1 - позади всех окон + ZPOS_NORMAL = 0 - обычное + ZPOS_ALWAYS_TOP = 1 - поверх всех окон + ====================================================================== ==================== Функция 20 - интерфейс MIDI. ==================== ====================================================================== @@ -1459,6 +1466,22 @@ dd 1675 497 суток. * Системное время можно получить функцией 3. +====================================================================== +===================== Функция 26, подфункция 10 ====================== +========== Получить значение высокоточного счётчика времени. ========= +====================================================================== +Parameters: + * eax = 26 - номер функции + * ebx = 10 - номер подфункции +Returned value: + * edx:eax = число наносекунд с момента загрузки ядра + * eax = младшее двойное слово + * edx = старшее двойное слово +Remarks: + * функция использует счётчик HPET, если HPET не доступен используется + счётчик PIT. В этом случае точность будет уменьшена до 10 000 000 + наносекунд. + ====================================================================== ====================== Функция 26, подфункция 11 ===================== =========== Узнать, разрешён ли низкоуровневый доступ к HD. ========== @@ -1619,18 +1642,41 @@ dir_path1 db 'HD0/1',0 и всё равно содержит относительную y-координату, а к старшему слову следует прибавить 1. ------------------ Подфункция 2 - нажатые кнопки мыши ----------------- +---------------- Подфункция 2 - состояния кнопок мыши ---------------- Параметры: * eax = 37 - номер функции * ebx = 2 - номер подфункции Возвращаемое значение: - * eax содержит информацию о нажатых кнопках мыши: - * бит 0 установлен = левая кнопка нажата - * бит 1 установлен = правая кнопка нажата - * бит 2 установлен = средняя кнопка нажата - * бит 3 установлен = 4-я кнопка нажата - * бит 4 установлен = 5-я кнопка нажата - * прочие биты сброшены + * eax = биты 0-4 соответствуют подфункции 3 + +----------- Подфункция 3 - состояния и события кнопок мыши ----------- +Параметры: + * eax = 37 - номер функции + * ebx = 3 - номер подфункции +Возвращаемое значение: + * eax содержит следующую информацию: + +состояния: + * бит 0 установлен = удерживается левая кнопка + * бит 1 установлен = удерживается правая кнопка + * бит 2 установлен = удерживается средняя кнопка + * бит 3 установлен = удерживается 4-я кнопка + * бит 4 установлен = удерживается 5-я кнопка + +события: + * бит 8 установлен = нажата левая кнопка + * бит 9 установлен = нажата правая кнопка + * бит 10 установлен = нажата средняя кнопка + + * бит 15 установлен = используется вертикальная прокрутка + + * бит 16 установлен = отпущена левая кнопка + * бит 17 установлен = отпущена правая кнопка + * бит 18 установлен = отпущена средняя кнопка + + * бит 23 установлен = используется горизонтальная прокрутка + + * бит 24 установлен = двойной щелчёк левой кнопкой ------------------ Подфункция 4 - загрузить курсор ------------------- Параметры: @@ -2085,6 +2131,40 @@ dword-значение цвета 0x00RRGGBB * Пользователь может изменять скин статически, создав свой default.skn, или динамически с помощью приложения desktop. +====================================================================== += Функция 48, подфункция 9 - получить настройку сглаживания шрифтов. = +====================================================================== +Параметры: + * eax = 48 - номер функции + * ebx = 9 - номер подфункции +Возвращаемое значение: + * eax = 2 - субпиксельное, 1 - обычное, 0 - выключить + +====================================================================== +===== Функция 48, подфункция 10 - настроить сглаживание шрифтов. ===== +====================================================================== +Параметры: + * eax = 48 - номер функции + * ebx = 10 - номер подфункции + * cl = 2 - субпиксельное, 1 - обычное, 0 - выключить + +====================================================================== +======== Функция 48, подфункция 11 - получить размер шрифтов. ======== +====================================================================== +Параметры: + * eax = 48 - номер функции + * ebx = 9 - номер подфункции +Возвращаемое значение: + * eax = текущая высота шрифта в пикселях + +====================================================================== +======= Функция 48, подфункция 12 - установить размер шрифтов. ======= +====================================================================== +Параметры: + * eax = 48 - номер функции + * ebx = 10 - номер подфункции + * cl = новая высота шрифта в пикселях + ====================================================================== ============ Функция 49 - Advanced Power Management (APM). =========== ====================================================================== @@ -3805,9 +3885,13 @@ Architecture Software Developer's Manual, Volume 3, Appendix B); Возвращаемое значение: * функция не возвращает значения Замечания: - * Строка заголовка должна быть в формате ASCIIZ. В заголовке - отображается не более 255 символов независимо от полной длины - строки. + * Строка заголовка должна заканчиваться нулём. + * Можно указать кодировку заголовка, + поместив в начале строки байт со значениями: + 1 = cp866 + 2 = UTF-16LE + 3 = UTF-8 + иначе будет использоваться cp866. * Чтобы убрать заголовок, передайте NULL в ecx. ====================================================================== @@ -3916,6 +4000,76 @@ Architecture Software Developer's Manual, Volume 3, Appendix B); Возвращаемое значение: * eax = -1 для ошибки +====================================================================== +===== Функция 74, подфункция 4, Получить указатель на устройство ===== +====================================================================== +Параметры: + * eax = 74 - номер функции + * bl = 4 - номер подфункции + * bh = номер устройства +Возвращаемое значение: + * eax = указатель, -1 для ошибки + +====================================================================== +=== Функция 74, подфункция 6, Получить количество посланых пакетов === +====================================================================== +Параметры: + * eax = 74 - номер функции + * bl = 6 - номер подфункции + * bh = номер устройства +Возвращаемое значение: + * eax = количество с момента старта устройства, -1 для ошибки + +====================================================================== +=== Функция 74, подфункция 7, Получить количество принятых пакетов === +====================================================================== +Параметры: + * eax = 74 - номер функции + * bl = 7 - номер подфункции + * bh = номер устройства +Возвращаемое значение: + * eax = количество с момента старта устройства, -1 для ошибки + +====================================================================== +==== Функция 74, подфункция 8, Получить количество посланых байт. ==== +====================================================================== +Параметры: + * eax = 74 - номер функции + * bl = 8 - номер подфункции + * bh = номер устройства +Возвращаемое значение: + * eax = количество с момента старта устройства, -1 для ошибки + * ebx = старшая часть + +====================================================================== +==== Функция 74, подфункция 9, Получить количество принятых байт. ==== +====================================================================== +Параметры: + * eax = 74 - номер функции + * bl = 9 - номер подфункции + * bh = номер устройства +Возвращаемое значение: + * eax = количество с момента старта устройства, -1 для ошибки + * ebx = старшая часть + +====================================================================== +======= Функция 74, подфункция 10, Получить статус соединения. ======= +====================================================================== +Параметры: + * eax = 74 - номер функции + * bl = 10 - номер подфункции + * bh = номер устройства +Возвращаемое значение: + * eax = статус соединения, -1 для ошибки + +Статусы: + 0 = нет соединения + 1 = неизвестное соединение + 4 = 10 Мбит + 8 = 100 Мбит + 12 = 1 Гбит + 10b = флаг полного дуплекса + ====================================================================== ======= Функция 75, подфункция 0, Open socket (Открыть сокет). ======= ====================================================================== diff --git a/kernel/branches/Kolibri-acpi/docs/sysfuncs.txt b/kernel/branches/Kolibri-acpi/docs/sysfuncs.txt index d43225b6a5..09f55297a2 100644 --- a/kernel/branches/Kolibri-acpi/docs/sysfuncs.txt +++ b/kernel/branches/Kolibri-acpi/docs/sysfuncs.txt @@ -192,40 +192,38 @@ Remarks: * System time can be set by function 22. ====================================================================== -============ Function 4 - draw text string in the window. ============ +=================== Function 4 - draw text string. =================== ====================================================================== Parameters: * eax = 4 - function number - * ebx = [coordinate on axis x]*65536 + [coordinate on axis y] - * ecx = 0xXYRRGGBB, where + * ebx = X*65536+Y, coordinates in the window or buffer + * ecx = 0xXXRRGGBB, where * RR, GG, BB specify text color - * X=ABnn (bits): - * nn specifies the used font: 0=system monospaced, - 1=system font of variable width - * A=0 - output esi characters, A=1 - output ASCIIZ-string - * B=1 - fill background with the color edi - * Y = Cnnn - * C=1 redirect the output to the user area, specified in edi - * nnn - not used in the current, must be 0 (zero) + * XX = ABFFCSSS (bits): + * A=1 - output zero terminated string + * B=1 - fill background (color = edi) + * FF specifies the font and encoding: + 0 = 6x9 cp866 + 1 = 8x16 cp866 + 2 = 8x16 UTF-16LE + 3 = 8x16 UTF-8 + * C=0 - draw to the window, + C=1 - draw to the user buffer (edi) + * SSS = (size multiplier)-1, so 0 = x1, 7 = x8 * edx = pointer to the beginning of the string - * esi = for A=0 length of the string, must not exceed 255; - for A=1 is ignored - * edi = color to fill background, if B=1 - * edi = pointer to user area, for redirect, if C=1 + * esi = for A=0 length of the string, for A=1 is ignored + * edi = for B=1 color to fill background, + for C=1 pointer to user buffer Returned value: * function does not return value Remarks: - * First system font is read out at loading from the file char.mt, - second - from char2.mt. - * Both fonts have height 9 pixels, width of the monospaced font - is equal to 6 pixels. - * C=1, pixel depth = 32 bits, user area is as follows: - dword Xsize - dword Ysize - rest of the area = Xsize * Y size * 4 - * You can not use B = 1 and C = 1, at the same time. Since in both - cases, the register edi is used for different purposes. + * You can not use B=1 and C=1 at the same time, since both use edi. + * When SSS=0, font may be smoothed, depending on system setting. + * User buffer structure: +Xsize dd +Ysize dd +picture rb Xsize*Ysize*4 ; 32 bpp ====================================================================== ========================= Function 5 - delay. ======================== @@ -242,38 +240,6 @@ Remarks: to transfer control to the next process (to complete a current time slice), use subfunction 1 of function 68. -====================================================================== -============== Function 6 - read the file from ramdisk. ============== -====================================================================== -Parameters: - * eax = 6 - function number - * ebx = pointer to the filename - * ecx = number of start block, beginning from 1; - ecx=0 - read from the beginning of the file (same as ecx=1) - * edx = number of blocks to read; - edx=0 - read one block (same as edx=1) - * esi = pointer to memory area for the data -Returned value: - * eax = file size in bytes, if the file was successfully read - * eax = -1, if the file was not found -Remarks: - * This function is out-of-date; function 70 allows - to fulfil the same operations with the extended possibilities. - * Block = 512 bytes. - * For reading all file you can specify the certainly large value - in edx, for example, edx = -1; but in this case be ready that - the program will "fall", if the file will appear too large and can - not be placed in the program memory. - * The filename must be either in the format 8+3 characters - (first 8 characters - name itself, last 3 - extension, - the short names and extensions are supplemented with spaces), - or in the format 8.3 characters "FILE.EXT"/"FILE.EX " - (name no more than 8 characters, dot, extension 3 characters - supplemented if necessary by spaces). - The filename must be written with capital letters. The terminating - character with code 0 is not necessary (not ASCIIZ-string). - * This function does not support folders on the ramdisk. - ====================================================================== =============== Function 7 - draw image in the window. =============== ====================================================================== @@ -1004,20 +970,22 @@ Parameters: Returned value: * function does not return value ----------------- Subsubfunction 2 - get mouse delay. ----------------- +Remark: recommended speed = 1, 0 = lock the cursor. + +------------- Subsubfunction 2 - get mouse acceleration. ------------- Parameters: * eax = 18 - function number * ebx = 19 - subfunction number * ecx = 2 - subsubfunction number Returned value: - * eax = current mouse delay + * eax = 0 - off, 1 - slight, 2 - medium, 3 - intense ----------------- Subsubfunction 3 - set mouse delay. ----------------- +------------- Subsubfunction 3 - set mouse acceleration. ------------- Parameters: * eax = 18 - function number * ebx = 19 - subfunction number * ecx = 3 - subsubfunction number - * edx = new value for mouse delay + * edx = 0 - off, 1 - slight, 2 - medium, 3 - intense Returned value: * function does not return value @@ -1044,22 +1012,25 @@ Parameters: * bit 4 is set = 5th button is pressed Returned value: * function does not return value -Remarks: - * It is recommended to set speed of the mouse (in subsubfunction 1) - from 1 up to 9. The installed value is not inspected by the kernel - code, so set it carefully, at incorrect value the cursor - can "freeze". Speed of the mouse can be regulated through the - application SETUP. - * Recommended delay of the mouse (in subsubfunction 3) = 10. Lower - value is not handled by COM mice. At the very large values the - movement of the mouse on 1 pixel is impossible and the cursor will - jump on the value of installed speed (subsubfunction 1). The - installed value is not inspected by the kernel code. - Mouse delay can be regulated through the application SETUP. - * The subsubfunction 4 does not check the passed value. Before - its call find out current screen resolution (with function 14) - and check that the value of position is inside the limits of the - screen. + +-------------- Subsubfunction 6 - get doubleclick delay. ------------- +Parameters: + * eax = 18 - function number + * ebx = 19 - subfunction number + * ecx = 6 - subsubfunction number +Returned value: + * eax = current doubleclick delay (100 = 1 second) + +-------------- Subsubfunction 7 - set doubleclick delay. ------------- +Parameters: + * eax = 18 - function number + * ebx = 19 - subfunction number + * ecx = 7 - subsubfunction number + * dl = new value for doubleclick delay (100 = 1 second) +Returned value: + * function does not return value + +Remark: mouse settings can be modified in the application mouse_cfg. ====================================================================== ======== Function 18, subfunction 20 - get information on RAM. ======= @@ -1148,6 +1119,37 @@ Remarks: of the current video mode, otherwise the function will not change anything. +====================================================================== +===================== Function 18, subfunction 25 ==================== +===== Control position of the window relative to other windows. ====== +====================================================================== + +------------- Subsubfunction 1 - get position ----------------------- +Parameters: + * eax = 18 - function number + * ebx = 25 - subfunction number + * ecx = 1 - subsubfunction number + * edx = -1(for current window) or PID application +Returned value: + * eax = one of the constants window position + +------------- Subsubfunction 2 - set position ----------------------- +Parameters: + * eax = 18 - function number + * ebx = 25 - subfunction number + * ecx = 2 - subsubfunction number + * edx = -1(for current window) or PID application + * esi = new window position (one of the constants below) +Returned value: + * eax = 0 - error + * eax = 1 - success + +Constant position of the window relative to other windows: + ZPOS_DESKTOP = -2 - on the background + ZPOS_ALWAYS_BACK = -1 - behind all the windows + ZPOS_NORMAL = 0 - normal + ZPOS_ALWAYS_TOP = 1 - on top of all windows + ====================================================================== ==================== Function 20 - MIDI interface. =================== ====================================================================== @@ -1451,7 +1453,21 @@ Returned value: Remarks: * Counter takes modulo 2^32, that correspond to a little more than 497 days. - * To get system time use function 3. + * To get system time use function 3. + +====================================================================== +===================== Function 26, subfunction 10 ==================== +========== Get the value of the high precision time counter. ========= +====================================================================== +Parameters: + * eax = 26 - function number + * ebx = 10 - subfunction number +Returned value: + * eax = number of nanoseconds since system boot time (lower DWORD) + * edx = number of nanoseconds since system boot time (high DWORD) +Remarks: + * The counter is based on HPET, if HPET is not available, resolution + will be reduced to 10 000 000 nanoseconds. ====================================================================== ===================== Function 26, subfunction 11 ==================== @@ -1611,18 +1627,41 @@ Remarks: contains relative y-coordinate, and to the high word 1 should be added. ------------- Subfunction 2 - pressed buttons of the mouse ------------ +------------- Subfunction 2 - states of the mouse buttons ------------ Parameters: * eax = 37 - function number * ebx = 2 - subfunction number Returned value: - * eax contains information on the pressed mouse buttons: - * bit 0 is set = left button is pressed - * bit 1 is set = right button is pressed - * bit 2 is set = middle button is pressed - * bit 3 is set = 4th button is pressed - * bit 4 is set = 5th button is pressed - * other bits are cleared + * eax = bits 0-4 equal to subfunction 3 + +------- Subfunction 3 - states and events of the mouse buttons ------- +Parameters: + * eax = 37 - function number + * ebx = 3 - subfunction number +Returned value: + * eax contains next information: + +states: + * bit 0 is set = left button is held + * bit 1 is set = right button is held + * bit 2 is set = middle button is held + * bit 3 is set = 4th button is held + * bit 4 is set = 5th button is held + +events: + * bit 8 is set = left button is pressed + * bit 9 is set = right button is pressed + * bit 10 is set = middle button is pressed + + * bit 15 is set = vertical scroll is used + + * bit 16 is set = left button is released + * bit 17 is set = right button is released + * bit 18 is set = middle button is released + + * bit 23 is set = horisontal scroll is used + + * bit 24 is set = doubleclick by left button -------------------- Subfunction 4 - load cursor --------------------- Parameters: @@ -1954,11 +1993,11 @@ Remarks: * Structure of the color table is described in the standard include file 'macros.inc' as 'system_colors'; for example, it is possible to write: - sc system_colors ; variable declaration - ... ; somewhere one must call - ; this function with ecx=sc - mov ecx, [sc.work_button_text] ; read text color on - ; buttin in working area + sc system_colors ; variable declaration + ... ; somewhere one must call + ; this function with ecx=sc + mov ecx, [sc.work_button_text] ; read text color on + ; buttin in working area * A program itself desides to use or not to use color table. For usage program must simply at calls to drawing functions select color taken from the table. @@ -2073,6 +2112,40 @@ Remarks: * User can change the skin statically by creating hisself 'default.skn' or dynamically with the application 'desktop'. +====================================================================== +====== Function 48, subfunction 9 - get font smoothing setting. ====== +====================================================================== +Parameters: + * eax = 48 - function number + * ebx = 9 - subfunction number +Returned value: + * eax = 2 - subpixel, 1 - anti-aliasing, 0 - off + +====================================================================== +========== Function 48, subfunction 10 - set font smoothing. ========= +====================================================================== +Parameters: + * eax = 48 - function number + * ebx = 10 - subfunction number + * cl = 2 - subpixel, 1 - anti-aliasing, 0 - off + +====================================================================== +============ Function 48, subfunction 11 - get font size. ============ +====================================================================== +Parameters: + * eax = 48 - function number + * ebx = 9 - subfunction number +Returned value: + * eax = current font height in pixels + +====================================================================== +============ Function 48, subfunction 12 - set font size. ============ +====================================================================== +Parameters: + * eax = 48 - function number + * ebx = 10 - subfunction number + * cl = new font height in pixels + ====================================================================== =========== Function 49 - Advanced Power Management (APM). =========== ====================================================================== @@ -2324,11 +2397,11 @@ Remarks: The data of the graphics screen (the memory area which displays screen contents) are accessible to a program directly, without any system calls, through the selector gs: - mov eax, [gs:0] + mov eax, [gs:0] places in eax the first dword of the buffer, which contains information on color of the left upper point (and, possibly, colors of several following). - mov [gs:0], eax + mov [gs:0], eax by work in VESA modes with LFB sets color of the left upper point (and, possibly, colors of several following). To interpret the data of graphics screen program needs to know @@ -3056,7 +3129,7 @@ Remarks: FPU and/or SSE. ====================================================================== -====== Function 68, subfunction 25 - set FPU exception handler. ====== +======== Function 68, subfunction 25 - set exception activity ======== ====================================================================== Parameters: * eax = 68 - function number @@ -3161,7 +3234,7 @@ Remarks: and at arrival of new message the system will wait. For synchronization frame all work with the buffer by operations lock/unlock - neg [bufsize] + neg [bufsize] * Data in the buffer are considered as array of items with variable length - messages. Format of a message is explained in general description. @@ -3772,12 +3845,16 @@ Remarks: Parameters: * eax = 71 - function number * ebx = 1 - subfunction number - * ecx = pointer to caption string + * ecx = pointer to zero terminated string Returned value: * function does not return value Remarks: - * String must be in the ASCIIZ-format. Disregarding real string - length, no more than 255 characters are drawn. + * You may set the caption string encoding by putting + at the start of the string a byte with next values: + 1 = cp866 + 2 = UTF-16LE + 3 = UTF-8 + otherwise will be used cp866. * Pass NULL in ecx to remove caption. ====================================================================== @@ -3834,11 +3911,11 @@ Returned value: * function does not return value ====================================================================== -= Function 74, Subfunction -1, Get number of active network devices. = += Function 74, Subfunction 255, Get number of active network devices. = ====================================================================== Parameters: * eax = 74 - function number - * bl = -1 - subfunction number + * bl = 255 - subfunction number Returned value: * eax = number of active network devices @@ -3850,7 +3927,7 @@ Parameters: * bl = 0 - subfunction number * bh = device number Returned value: - * eax = device type + * eax = device type number ====================================================================== ======== Function 74, Subfunction 1, Get network device name. ======== @@ -3884,6 +3961,78 @@ Parameters: Returned value: * eax = -1 on error +====================================================================== +=========== Function 74, Subfunction 4, Get device pointer. ========== +====================================================================== +Parameters: + * eax = 74 - function number + * bl = 4 - subfunction number + * bh = device number +Returned value: + * eax = device pointer, -1 on error + +====================================================================== +========= Function 74, Subfunction 6, Get packet TX counter. ========= +====================================================================== +Parameters: + * eax = 74 - function number + * bl = 6 - subfunction number + * bh = device number +Returned value: + * eax = Number of packets sent since device start, -1 on error + +====================================================================== +========= Function 74, Subfunction 7, Get packet RX counter. ========= +====================================================================== +Parameters: + * eax = 74 - function number + * bl = 7 - subfunction number + * bh = device number +Returned value: + * eax = Number of packets received since device start, -1 on error + +====================================================================== +========== Function 74, Subfunction 8, Get TX byte counter. ========== +====================================================================== +Parameters: + * eax = 74 - function number + * bl = 8 - subfunction number + * bh = device number +Returned value: + * eax = Number of bytes sent since device start (lower dword) + -1 on error + * ebx = Number of bytes sent since device start (higher dword) + +====================================================================== +========== Function 74, Subfunction 9, Get RX byte counter. ========== +====================================================================== +Parameters: + * eax = 74 - function number + * bl = 9 - subfunction number + * bh = device number +Returned value: + * eax = Number of bytes received since device start (lower dword) + -1 on error + * ebx = Number of bytes received since device start (higher dword) + +====================================================================== +========== Function 74, Subfunction 10, Get link status. ============= +====================================================================== +Parameters: + * eax = 74 - function number + * bl = 10 - subfunction number + * bh = device number +Returned value: + * eax = link status, -1 on error + + Link status: + ETH_LINK_DOWN = 0b ; Link is down + ETH_LINK_UNKNOWN= 1b ; There could be an active link + ETH_LINK_FD = 10b ; full duplex flag + ETH_LINK_10M = 100b ; 10 mbit + ETH_LINK_100M = 1000b ; 100 mbit + ETH_LINK_1G = 1100b ; gigabit + ====================================================================== ============== Function 75, Subfunction 0, Open socket. ============== ====================================================================== @@ -4000,10 +4149,11 @@ Returned value: * ebx = errorcode Remarks: - Optstruct: dd level - dd optionname - dd optlength - db options... + Optstruct: + dd level + dd optionname + dd optlength + db options... ====================================================================== =========== Function 75, Subfunction 9, Get socket options. ========== @@ -4018,10 +4168,11 @@ Returned value: * ebx = errorcode Remarks: - Optstruct: dd level - dd optionname - dd optlength - db options... + Optstruct: + dd level + dd optionname + dd optlength + db options... ====================================================================== ============ Function 75, Subfunction 10, Get socketpair. =========== @@ -4032,6 +4183,53 @@ Parameters: Returned value: * eax = socketnum1, -1 on error * ebx = socketnum2, errorcode on error + +====================================================================== +============ Function 76, Network options and statistics. ============ +====================================================================== +Parameters: + * eax = 76 - function number + * high half of ebx = protocol number + * bh = device number + * bl = subfunction number + +Ethernet (0) + 0 - Read MAC + +IPv4 (1) + 0 - Read # IP packets send + 1 - Read # IP packets received + 2 - Read IP + 3 - Write IP + 4 - Read DNS + 5 - Write DNS + 6 - Read subnet + 7 - Write subnet + 8 - Read gateway + 9 - Write gateway + +ICMP (2) + 0 - Read # ICMP packets send + 1 - Read # ICMP packets received + 3 - enable/disable ICMP echo reply + +UDP (3) + 0 - Read # UDP packets send + 1 - Read # UDP packets received + +TCP (4) + 0 - Read # TCP packets send + 1 - Read # TCP packets received + +ARP (5) + 0 - Read # ARP packets send + 1 - Read # ARP packets received + 2 - Read # ARP entry's + 3 - Read ARP entry + 4 - Add static ARP entry + 5 - Remove ARP entry (-1 = remove all) + 6 - Send ARP announce on specified interface + 7 - Read # ARP conflicts (IP address conflicts) ====================================================================== =============== Function -1 - terminate thread/process =============== diff --git a/kernel/branches/Kolibri-acpi/encoding.inc b/kernel/branches/Kolibri-acpi/encoding.inc index 0df097a29a..38097b201b 100644 --- a/kernel/branches/Kolibri-acpi/encoding.inc +++ b/kernel/branches/Kolibri-acpi/encoding.inc @@ -10,37 +10,37 @@ $Revision: 5082 $ ; fetch the UTF-8 character in addrspace:offs to char macro fetch_utf8_char addrspace, offs, char { local first_byte, b - ; fetch first byte + ; fetch first byte load first_byte byte from addrspace:offs - if first_byte < 0x80 - char = first_byte - offs = offs + 1 - else if first_byte < 0xC0 + if first_byte < 0x80 + char = first_byte + offs = offs + 1 + else if first_byte < 0xC0 err Invalid UTF-8 string - else if first_byte < 0xE0 - char = first_byte and 0x1F + else if first_byte < 0xE0 + char = first_byte and 0x1F load b byte from addrspace:offs + 1 - char = (char shl 6) + (b and 0x3F) - offs = offs + 2 - else if first_byte < 0xF0 - char = first_byte and 0xF + char = (char shl 6) + (b and 0x3F) + offs = offs + 2 + else if first_byte < 0xF0 + char = first_byte and 0xF load b byte from addrspace:offs + 1 - char = (char shl 6) + (b and 0x3F) + char = (char shl 6) + (b and 0x3F) load b byte from addrspace:offs + 2 - char = (char shl 6) + (b and 0x3F) - offs = offs + 3 - else if first_byte < 0xF8 - char = first_byte and 0x7 + char = (char shl 6) + (b and 0x3F) + offs = offs + 3 + else if first_byte < 0xF8 + char = first_byte and 0x7 load b byte from addrspace:offs + 1 - char = (char shl 6) + (b and 0x3F) + char = (char shl 6) + (b and 0x3F) load b byte from addrspace:offs + 2 - char = (char shl 6) + (b and 0x3F) + char = (char shl 6) + (b and 0x3F) load b byte from addrspace:offs + 3 - char = (char shl 6) + (b and 0x3F) - offs = offs + 4 - else + char = (char shl 6) + (b and 0x3F) + offs = offs + 4 + else err Invalid UTF-8 string - end if + end if } ; Worker macro for all encodings. @@ -59,29 +59,29 @@ macro convert_utf8 encoding, [arg] end virtual while offs < ..addrspace#.size fetch_utf8_char ..addrspace, offs, char - if char = 0x2500 + if char = 0x2500 db 0xC4 - else if char = 0x2502 + else if char = 0x2502 db 0xB3 - else if char = 0x250C + else if char = 0x250C db 0xDA - else if char = 0x2510 + else if char = 0x2510 db 0xBF - else if char = 0x2514 + else if char = 0x2514 db 0xC0 - else if char = 0x2518 + else if char = 0x2518 db 0xD9 - else if char = 0x252C + else if char = 0x252C db 0xC2 - else if char = 0x2534 + else if char = 0x2534 db 0xC1 - else if char = 0x2551 + else if char = 0x2551 db 0xBA else if char < 0x80 db char - else + else encoding char - end if + end if end while } @@ -101,16 +101,16 @@ macro declare_encoding encoding declare_encoding cp866 { if char = 0x401 - db 0xF0 - else if char = 0x451 - db 0xF1 - else if (char < 0x410) | (char > 0x44F) + db 0xF0 + else if char = 0x451 + db 0xF1 + else if (char < 0x410) | (char > 0x44F) err Failed to convert to CP866 - else if char < 0x440 - db char - 0x410 + 0x80 - else - db char - 0x440 + 0xE0 - end if + else if char < 0x440 + db char - 0x410 + 0x80 + else + db char - 0x440 + 0xE0 + end if } ; Latin-1 encoding @@ -118,28 +118,28 @@ declare_encoding cp866 declare_encoding latin1 { if char < 0x100 - db char - else + db char + else err Failed to convert to Latin-1 - end if + end if } ; CP850 encoding declare_encoding cp850 { if char = 0xBF - db 0xA8 - else if char = 0xE1 - db 0xA0 - else if char = 0xE9 - db 0x82 - else if char = 0xED - db 0xA1 - else if char = 0xF3 - db 0xA2 - else if char = 0xFA - db 0xA3 - else - err Failed to convert to CP850 - end if + db 0xA8 + else if char = 0xE1 + db 0xA0 + else if char = 0xE9 + db 0x82 + else if char = 0xED + db 0xA1 + else if char = 0xF3 + db 0xA2 + else if char = 0xFA + db 0xA3 + else + err Failed to convert to CP850 + end if } diff --git a/kernel/branches/Kolibri-acpi/fs/fat.inc b/kernel/branches/Kolibri-acpi/fs/fat.inc index 0d51e43657..8836e37ff6 100644 --- a/kernel/branches/Kolibri-acpi/fs/fat.inc +++ b/kernel/branches/Kolibri-acpi/fs/fat.inc @@ -1843,6 +1843,9 @@ fat_Read: shr edi, 9 add eax, edi and edx, 511 + cmp ecx, 512 + jc .sectorPiece + test edx, edx jz .alignedSector .sectorPiece: push eax ebx @@ -1870,8 +1873,6 @@ fat_Read: test ecx, ecx jz .done .alignedSector: - cmp ecx, 512 - jc .sectorPiece shl edi, 9 add ecx, edi mov edi, [ebp+FAT.SECTORS_PER_CLUSTER] @@ -1899,15 +1900,19 @@ fat_Read: dec eax imul eax, [ebp+FAT.SECTORS_PER_CLUSTER] add eax, [ebp+FAT.DATA_START] - sub eax, edx -.readFragment: push ecx mov ecx, eax + mov eax, esi + dec eax + dec eax + imul eax, [ebp+FAT.SECTORS_PER_CLUSTER] + add eax, [ebp+FAT.DATA_START] + push eax +.readFragment: + sub ecx, edx mov eax, edx xor edx, edx - push eax call fs_read64_app - add [esp], ecx shl ecx, 9 add ebx, ecx test eax, eax @@ -1916,13 +1921,6 @@ fat_Read: pop ecx xor edx, edx jcxz .done - cmp ecx, 512 - jc .sectorPiece - mov eax, esi - dec eax - dec eax - imul eax, [ebp+FAT.SECTORS_PER_CLUSTER] - add eax, [ebp+FAT.DATA_START] jmp .alignedCluster .readEnd: add ecx, edi @@ -1933,8 +1931,10 @@ fat_Read: dec eax imul eax, [ebp+FAT.SECTORS_PER_CLUSTER] add eax, [ebp+FAT.DATA_START] - sub eax, edx add eax, edi + push ecx + push eax + mov ecx, eax jmp .readFragment .noaccess3: pop eax diff --git a/kernel/branches/Kolibri-acpi/fs/ntfs.inc b/kernel/branches/Kolibri-acpi/fs/ntfs.inc index 7510d275f8..26fff1cf68 100644 --- a/kernel/branches/Kolibri-acpi/fs/ntfs.inc +++ b/kernel/branches/Kolibri-acpi/fs/ntfs.inc @@ -7,55 +7,142 @@ $Revision$ +; NTFS driver + +; Basic concepts: +; File is a FileRecord in the $MFT. +; $MFT is a file, that consists of FileRecords and starts with FileRecord of itself. +; FileRecord (FILE) consists of a header and attributes. +; Attribute consists of a header and a body. +; Attribute's body can be inside (resident) or outside of FileRecord. +; File's data is a body of $Data (80h) attribute. +; FileRecords is a data of the $MFT file. +; Directory is a file, that consists of index nodes. +; Resident index node is always located in a body of $IndexRoot (90h) attribute. +; Body of $IndexAllocation (A0h) attribute is always non resident +; and consists of IndexRecords. +; IndexRecord (INDX) consists of a header and an index node. +; Index node consists of a header and indexes. +; Index consists of a header and a copy of indexed attribute's body. +; Directories index $Filename (30h) attribute of all existing files. +; $IndexRoot and $IndexAllocation attributes of a directory has a name — $I30. + +; Offsets: + ; record header +updateSequenceOffset = 4 +updateSequenceSize = 6 +reuseCounter = 16 +hardLinkCounter = 12h +attributeOffset = 14h +recordFlags = 16h +recordRealSize = 18h +recordAllocatedSize = 1ch +newAttributeID = 28h + ; attribute header +attributeType = 0 +sizeWithHeader = 4 +nonResidentFlag = 8 +nameLength = 9 +nameOffset = 10 +attributeID = 14 +sizeWithoutHeader = 16 +attributeFlags = 16h + ; non resident attribute header +lastVCN = 18h +dataRunsOffset = 20h +attributeAllocatedSize = 28h +attributeRealSize = 30h +initialDataSize = 38h + ; $IndexRoot +collationRule = 4 +indexRecordSize = 8 +indexRecordSizeClus = 12 + ; node header +indexOffset = 0 +nodeRealSize = 4 +nodeAllocatedSize = 8 + ; $Filename index +fileRecordReference = 0 +fileReferenceReuse = 6 +indexAllocatedSize = 8 +indexRawSize = 10 +indexFlags = 12 +directoryRecordReference = 16 +directoryReferenceReuse = 16h +fileAllocatedSize = 38h +fileRealSize = 40h +fileFlags = 48h +fileNameLength = 50h + struct NTFS PARTITION -Lock MUTEX ? ; currently operations with one partition - ; can not be executed in parallel since the - ; legacy code is not ready; this mutex guards - ; all operations -sectors_per_cluster dd ? -mft_cluster dd ? -mftmirr_cluster dd ? -frs_size dd ? ; FRS size in bytes -iab_size dd ? ; IndexAllocationBuffer size in bytes -frs_buffer dd ? -iab_buffer dd ? -mft_retrieval dd ? -mft_retrieval_size dd ? -mft_retrieval_alloc dd ? -mft_retrieval_end dd ? -cur_index_size dd ? -cur_index_buf dd ? +Lock MUTEX ? ; Currently operations with one partition +; can not be executed in parallel since the legacy code is not ready. +sectors_per_cluster dd ? +mft_cluster dd ? ; location +mftmirr_cluster dd ? ; location +frs_size dd ? ; in bytes +frs_buffer dd ? ; MFT fileRecord buffer +mft_retrieval dd ? +mft_retrieval_size dd ? +mft_retrieval_alloc dd ? +mft_retrieval_end dd ? +cur_index_size dd ? ; in sectors +cur_index_buf dd ? ; index node buffer +BitmapBuffer dd ? +BitmapTotalSize dd ? ; bytes reserved +BitmapSize dd ? ; bytes readen +BitmapLocation dd ? ; starting sector +BitmapStart dd ? ; first byte after area, reserved for MFT +mftBitmapBuffer dd ? ; one cluster +mftBitmapSize dd ? ; bytes readen +mftBitmapLocation dd ? ; starting sector -ntfs_cur_attr dd ? -ntfs_cur_iRecord dd ? -ntfs_cur_offs dd ? ; in sectors -ntfs_cur_size dd ? ; in sectors -ntfs_cur_buf dd ? -ntfs_cur_read dd ? ; [output] -ntfs_bCanContinue db ? - rb 3 +ntfs_cur_attr dd ? ; attribute type +ntfs_cur_iRecord dd ? ; number of fileRecord in MFT +ntfs_cur_offs dd ? ; attribute VCN in sectors +ntfs_cur_size dd ? ; max sectors to read +ntfs_cur_buf dd ? +ntfs_cur_read dd ? ; bytes readen +ntfsLastRead dd ? ; last readen block of sectors +newMftRecord dd ? ; number of fileRecord in MFT +fileDataStart dd ? ; starting cluster +fileDataSize dd ? ; in clusters +fileRealSize dd ? ; in bytes +indexOffset dd ? +nodeLastRead dd ? +ntfs_bCanContinue db ? +ntfsNotFound db ? +ntfsFolder db ? +ntfsFragmentCount db ? -cur_subnode_size dd ? -ntfs_attr_iRecord dd ? -ntfs_attr_iBaseRecord dd ? -ntfs_attr_offs dd ? -ntfs_attr_list dd ? -ntfs_attr_size dq ? -ntfs_cur_tail dd ? +cur_subnode_size dd ? +ntfs_attr_iRecord dd ? +ntfs_attr_iBaseRecord dd ? +ntfs_attr_offs dd ? +ntfs_attr_list dd ? +ntfs_attr_size dq ? +ntfs_cur_tail dd ? -ntfs_attrlist_buf rb 0x400 -ntfs_attrlist_mft_buf rb 0x400 -ntfs_bitmap_buf rb 0x400 +ntfs_attrlist_buf rb 0x400 +ntfs_attrlist_mft_buf rb 0x400 +ntfs_bitmap_buf rb 0x400 ends +; NTFS external functions +; in: +; ebx -> parameter structure of sysfunc 70 +; ebp -> NTFS structure +; [esi]+[esp+4] = name +; out: +; eax, ebx = return values for sysfunc 70 iglobal align 4 ntfs_user_functions: dd ntfs_free dd (ntfs_user_functions_end - ntfs_user_functions - 4) / 4 - dd ntfs_Read + dd ntfs_ReadFile dd ntfs_ReadFolder - dd ntfs_Rewrite + dd ntfs_CreateFile dd ntfs_Write dd ntfs_SetFileEnd dd ntfs_GetFileInfo @@ -67,8 +154,8 @@ ntfs_user_functions_end: endg ntfs_test_bootsec: -; in: ebx->buffer, edx=size of partition -; out: CF set <=> invalid +; in: ebx -> buffer, edx = size of partition +; out: CF=1 -> invalid ; 1. Name=='NTFS ' cmp dword [ebx+3], 'NTFS' jnz .no @@ -121,7 +208,7 @@ ntfs_test_bootsec: jnz .no cmp eax, edx ja .no -; 7. Clusters per FRS must be either negative and in [-31,-9] or positive and power of 2 +; 7. Clusters per FRS must be either power of 2 or between -31 and -9 movsx eax, byte [ebx+0x40] cmp al, -31 jl .no @@ -131,8 +218,7 @@ ntfs_test_bootsec: js .no test [ebx+0x40], al jnz .no -@@: -; 8. Same for clusters per IndexAllocationBuffer +@@: ; 8. Same for clusters per IndexAllocationBuffer movsx eax, byte [ebx+0x44] cmp al, -31 jl .no @@ -142,16 +228,14 @@ ntfs_test_bootsec: js .no test [ebx+0x44], al jnz .no -@@: -; OK, this is correct NTFS bootsector +@@: ; OK, this is correct NTFS bootsector clc ret -.no: -; No, this bootsector isn't NTFS +.no: ; No, this bootsector isn't NTFS stc ret -proc ntfs_create_partition +ntfs_create_partition: cmp dword [esi+DISK.MediaInfo.SectorSize], 512 jnz .nope mov edx, dword [ebp+PARTITION.Length] @@ -169,16 +253,15 @@ proc ntfs_create_partition shr eax, 1 call fs_read32_sys test eax, eax - jnz .nope ; no chance... + jnz .nope .boot_read_ok: call ntfs_test_bootsec jnc .ntfs_setup .nope: xor eax, eax jmp .exit - -.ntfs_setup: ; By given bootsector, initialize some NTFS variables +.ntfs_setup: movi eax, sizeof.NTFS call malloc test eax, eax @@ -194,12 +277,11 @@ proc ntfs_create_partition mov ecx, [ebp+PARTITION.Disk] mov [eax+NTFS.Disk], ecx mov [eax+NTFS.FSUserFunctions], ntfs_user_functions + push ebx ebp esi mov ebp, eax - lea ecx, [ebp+NTFS.Lock] call mutex_init - movzx eax, byte [ebx+13] mov [ebp+NTFS.sectors_per_cluster], eax mov eax, [ebx+0x28] @@ -211,39 +293,21 @@ proc ntfs_create_partition mov [ebp+NTFS.mftmirr_cluster], eax movsx eax, byte [ebx+0x40] test eax, eax - js .1 + js @f mul [ebp+NTFS.sectors_per_cluster] shl eax, 9 - jmp .2 + jmp .1 +@@: + neg eax + mov ecx, eax + mov eax, 1 + shl eax, cl .1: - neg eax - mov ecx, eax - mov eax, 1 - shl eax, cl -.2: mov [ebp+NTFS.frs_size], eax - movsx eax, byte [ebx+0x44] - test eax, eax - js .3 - mul [ebp+NTFS.sectors_per_cluster] - shl eax, 9 - jmp .4 -.3: - neg eax - mov ecx, eax - mov eax, 1 - shl eax, cl -.4: - mov [ebp+NTFS.iab_size], eax -; allocate space for buffers - add eax, [ebp+NTFS.frs_size] - push eax - call kernel_alloc + stdcall kernel_alloc, eax test eax, eax jz .fail_free mov [ebp+NTFS.frs_buffer], eax - add eax, [ebp+NTFS.frs_size] - mov [ebp+NTFS.iab_buffer], eax ; read $MFT disposition mov eax, [ebp+NTFS.mft_cluster] mul [ebp+NTFS.sectors_per_cluster] @@ -259,38 +323,16 @@ proc ntfs_create_partition mul [ebp+NTFS.sectors_per_cluster] call ntfs_read_frs_sector test eax, eax - jnz @f + jnz .fail_free_frs cmp dword [ebx], 'FILE' - jnz @f + jnz .fail_free_frs call ntfs_restore_usa_frs - jnc .mftok -@@: -; $MFT and $MFTMirr invalid! -.fail_free_frs: - push [ebp+NTFS.frs_buffer] - call kernel_free -.fail_free: - mov eax, ebp - call free - xor eax, eax -.pop_exit: - pop esi ebp ebx -.exit: - cmp dword [esp+4], 0 - jz @f - sub ebx, 512 -@@: - ret -.fail_free_mft: - push [ebp+NTFS.mft_retrieval] - call kernel_free - jmp .fail_free_frs + jc .fail_free_frs .mftok: ; read $MFT table retrieval information ; start with one page, increase if not enough (when MFT too fragmented) push ebx - push 0x1000 - call kernel_alloc + stdcall kernel_alloc, 0x1000 pop ebx test eax, eax jz .fail_free_frs @@ -334,17 +376,98 @@ proc ntfs_create_partition add esp, 10h ; there may be other portions of $DATA attribute in auxiliary records; ; if they will be needed, they will be loaded later - mov [ebp+NTFS.cur_index_size], 0x1000/0x200 - push 0x1000 - call kernel_alloc + stdcall kernel_alloc, 0x1000 test eax, eax jz .fail_free_mft mov [ebp+NTFS.cur_index_buf], eax +; reserve adress space for bitmap buffer and load some part of bitmap + mov eax, dword [ebp+NTFS.Length] + xor edx, edx + div [ebp+NTFS.sectors_per_cluster] + shr eax, 3 + mov [ebp+NTFS.BitmapTotalSize], eax + add eax, 7FFFh + and eax, not 7FFFh + push eax + call alloc_kernel_space + test eax, eax + jz .failFreeIndex + mov [ebp+NTFS.BitmapBuffer], eax + mov [ebp+NTFS.ntfs_cur_buf], eax + mov eax, [ebp+NTFS.BitmapTotalSize] + add eax, [ebp+NTFS.mft_cluster] + shr eax, 3+2 ; reserve 1/8 of partition for $MFT + shl eax, 2 + mov [ebp+NTFS.BitmapStart], eax + shr eax, 15 + inc eax + shl eax, 3 + push eax + push eax + shl eax, 3 + mov [ebp+NTFS.ntfs_cur_size], eax + call alloc_pages + test eax, eax + pop ecx + jz .failFreeBitmap + add eax, 3 + mov ebx, [ebp+NTFS.BitmapBuffer] + call commit_pages + mov [ebp+NTFS.ntfs_cur_iRecord], 6 + mov [ebp+NTFS.ntfs_cur_attr], 0x80 + mov [ebp+NTFS.ntfs_cur_offs], 0 + call ntfs_read_attr + jc .failFreeBitmap + mov eax, [ebp+NTFS.ntfs_cur_read] + mov [ebp+NTFS.BitmapSize], eax + mov eax, [ebp+NTFS.ntfsLastRead] + mov [ebp+NTFS.BitmapLocation], eax +; read MFT $BITMAP attribute + mov eax, [ebp+NTFS.sectors_per_cluster] + mov [ebp+NTFS.ntfs_cur_size], eax + shl eax, 9 + stdcall kernel_alloc, eax + test eax, eax + jz .failFreeBitmap + mov [ebp+NTFS.mftBitmapBuffer], eax + mov [ebp+NTFS.ntfs_cur_buf], eax + mov [ebp+NTFS.ntfs_cur_iRecord], 0 + mov [ebp+NTFS.ntfs_cur_attr], 0xB0 + mov [ebp+NTFS.ntfs_cur_offs], 0 + call ntfs_read_attr + mov eax, [ebp+NTFS.ntfs_cur_read] + cmp eax, 4 + jc .failFreeBitmapMFT + mov [ebp+NTFS.mftBitmapSize], eax + mov eax, [ebp+NTFS.ntfsLastRead] + mov [ebp+NTFS.mftBitmapLocation], eax mov eax, ebp +.pop_exit: + pop esi ebp ebx +.exit: + cmp dword [esp+4], 0 + jz @f + sub ebx, 512 +@@: + ret + +.failFreeBitmapMFT: + stdcall kernel_free, [ebx+NTFS.mftBitmapBuffer] +.failFreeBitmap: + stdcall kernel_free, [ebx+NTFS.BitmapBuffer] +.failFreeIndex: + stdcall kernel_free, [ebp+NTFS.cur_index_buf] +.fail_free_mft: + stdcall kernel_free, [ebp+NTFS.mft_retrieval] +.fail_free_frs: + stdcall kernel_free, [ebp+NTFS.frs_buffer] +.fail_free: + mov eax, ebp + call free + xor eax, eax jmp .pop_exit -endp .get_mft_retrieval_ptr: pushad @@ -354,8 +477,7 @@ endp add eax, 0x1000/8 mov [ebp+NTFS.mft_retrieval_alloc], eax shl eax, 3 - push eax - call kernel_alloc + stdcall kernel_alloc, eax test eax, eax jnz @f popad @@ -378,27 +500,25 @@ endp popad ret -proc ntfs_free +ntfs_free: push ebx - xchg ebx, eax + mov ebx, eax stdcall kernel_free, [ebx+NTFS.frs_buffer] stdcall kernel_free, [ebx+NTFS.mft_retrieval] stdcall kernel_free, [ebx+NTFS.cur_index_buf] - xchg ebx, eax - call free + stdcall kernel_free, [ebx+NTFS.mftBitmapBuffer] + stdcall kernel_free, [ebx+NTFS.BitmapBuffer] + mov eax, ebx pop ebx - ret -endp + jmp free -proc ntfs_lock +ntfs_lock: lea ecx, [ebp+NTFS.Lock] jmp mutex_lock -endp -proc ntfs_unlock +ntfs_unlock: lea ecx, [ebp+NTFS.Lock] jmp mutex_unlock -endp ntfs_read_frs_sector: push ecx @@ -424,9 +544,15 @@ ntfs_read_frs_sector: ret ntfs_read_attr: -; in: variables in ebp+NTFS.* -; out: [ebp+NTFS.ntfs_cur_read] -; out: CF=1 => notfound, in this case eax=0 => disk ok, otherwise eax=disk error code +; in: +; [ebp+NTFS.ntfs_cur_iRecord] = number of fileRecord +; [ebp+NTFS.ntfs_cur_attr] = attribute type +; [ebp+NTFS.ntfs_cur_offs] = attribute VCN in sectors +; [ebp+NTFS.ntfs_cur_buf] -> buffer for data +; [ebp+NTFS.ntfs_cur_size] = max sectors to read +; out: +; [ebp+NTFS.ntfs_cur_read] = bytes readen +; CF=1 -> failed, eax = disk error code, eax=0 -> something with FS xor eax, eax pushad and [ebp+NTFS.ntfs_cur_read], 0 @@ -475,6 +601,7 @@ ntfs_read_attr: neg ecx imul ecx, [ebp+NTFS.sectors_per_cluster] sub ecx, edx + mov [ebp+NTFS.ntfsLastRead], eax cmp ecx, [ebp+NTFS.ntfs_cur_size] jb @f mov ecx, [ebp+NTFS.ntfs_cur_size] @@ -869,6 +996,7 @@ ntfs_read_attr: movzx esi, word [ecx+20h] ; mcb_info_ofs add esi, ecx xor edi, edi + mov [ebp+NTFS.ntfsFragmentCount], 0 .readloop: call ntfs_decode_mcb_entry jnc .break @@ -890,27 +1018,27 @@ ntfs_read_attr: mov ecx, [ebp+NTFS.ntfs_cur_size] @@: mov ebx, [ebp+NTFS.ntfs_cur_buf] -@@: - push eax + mov [ebp+NTFS.ntfsLastRead], eax + push ecx + xor edx, edx cmp [ebp+NTFS.ntfs_cur_attr], 0x80 jnz .sys cmp [ebp+NTFS.ntfs_cur_iRecord], 0 jz .sys - call fs_read32_app + call fs_read64_app jmp .appsys .sys: - call fs_read32_sys + call fs_read64_sys .appsys: - pop edx + pop ecx test eax, eax jnz .errread2 - add ebx, 0x200 - mov [ebp+NTFS.ntfs_cur_buf], ebx - lea eax, [edx+1] - add [ebp+NTFS.ntfs_cur_read], 0x200 - dec [ebp+NTFS.ntfs_cur_size] - inc [ebp+NTFS.ntfs_cur_offs] - loop @b + sub [ebp+NTFS.ntfs_cur_size], ecx + add [ebp+NTFS.ntfs_cur_offs], ecx + shl ecx, 9 + add [ebp+NTFS.ntfs_cur_read], ecx + add [ebp+NTFS.ntfs_cur_buf], ecx + inc [ebp+NTFS.ntfsFragmentCount] pop ecx xor eax, eax xor edx, edx @@ -936,10 +1064,10 @@ ntfs_read_attr: ret ntfs_read_file_record: -; in: eax=iRecord -; out: [ebp+NTFS.frs_buffer] contains information -; CF=1 - failed, in this case eax=0 => something with FS, eax nonzero => disk error -; Read attr $DATA of $Mft, starting from eax*[ebp+NTFS.frs_size] +; in: eax = iRecord +; out: [ebp+NTFS.frs_buffer] = record data +; CF=1 -> failed, eax = disk error code, eax=0 -> something with FS + ; Read attr $DATA of $Mft, starting from eax*[ebp+NTFS.frs_size] push ecx edx mov ecx, [ebp+NTFS.frs_size] mul ecx @@ -1080,9 +1208,11 @@ unichar_toupper: ret ntfs_find_lfn: -; in: esi+[esp+4] -> name -; out: CF=1 - file not found -; else CF=0, [ebp+NTFS.ntfs_cur_iRecord] valid, eax->record in parent directory +; in: [esi]+[esp+4] = name +; out: +; [ebp+NTFS.ntfs_cur_iRecord] = number of MFT fileRecord +; eax = pointer in parent index node +; CF=1 -> file not found (or just error) mov [ebp+NTFS.ntfs_cur_iRecord], 5 ; start parse from root cluster .doit2: mov [ebp+NTFS.ntfs_cur_attr], 0x90 ; $INDEX_ROOT @@ -1116,12 +1246,10 @@ ntfs_find_lfn: @@: ; reallocate push eax - push [ebp+NTFS.cur_index_buf] - call kernel_free + stdcall kernel_free, [ebp+NTFS.cur_index_buf] pop eax mov [ebp+NTFS.cur_index_size], eax - push eax - call kernel_alloc + stdcall kernel_alloc, eax test eax, eax jnz @f and [ebp+NTFS.cur_index_size], 0 @@ -1137,8 +1265,7 @@ ntfs_find_lfn: cmp edx, [ebp+NTFS.cur_index_size] jbe .ok2 push esi edx - push edx - call kernel_alloc + stdcall kernel_alloc, edx pop edx esi test eax, eax jz .stc_ret @@ -1149,8 +1276,7 @@ ntfs_find_lfn: mov esi, eax mov [ebp+NTFS.cur_index_size], edx push esi edx - push [ebp+NTFS.cur_index_buf] - call kernel_free + stdcall kernel_free, [ebp+NTFS.cur_index_buf] pop edx esi mov [ebp+NTFS.cur_index_buf], esi .ok2: @@ -1209,15 +1335,19 @@ ntfs_find_lfn: mov eax, edx shl eax, 9 cmp [ebp+NTFS.ntfs_cur_read], eax - jnz .notfound + jnz .err cmp dword [esi], 'INDX' - jnz .notfound + jnz .err + mov [ebp+NTFS.ntfs_cur_buf], esi mov ebx, esi call ntfs_restore_usa - jc .notfound + jc .err add esi, 0x18 jmp .scanloop .notfound: + mov [ebp+NTFS.ntfsNotFound], 1 + mov [esp+1Ch], esi +.err: popad stc ret 4 @@ -1250,13 +1380,7 @@ ntfs_find_lfn: ret 4 ;---------------------------------------------------------------- -; ntfs_Read - NTFS implementation of reading a file -; in: ebp = pointer to NTFS structure -; in: esi+[esp+4] = name -; in: ebx = pointer to parameters from sysfunc 70 -; out: eax, ebx = return values for sysfunc 70 -;---------------------------------------------------------------- -ntfs_Read: +ntfs_ReadFile: cmp byte [esi], 0 jnz @f or ebx, -1 @@ -1290,8 +1414,7 @@ ntfs_Read: popad xor ebx, ebx .eof: - movi eax, ERROR_END_OF_FILE - push eax + push ERROR_END_OF_FILE call ntfs_unlock pop eax ret @@ -1391,12 +1514,6 @@ ntfs_Read: popad ret -;---------------------------------------------------------------- -; ntfs_ReadFolder - NTFS implementation of reading a folder -; in: ebp = pointer to NTFS structure -; in: esi+[esp+4] = name -; in: ebx = pointer to parameters from sysfunc 70 -; out: eax, ebx = return values for sysfunc 70 ;---------------------------------------------------------------- ntfs_ReadFolder: call ntfs_lock @@ -1458,12 +1575,10 @@ ntfs_ReadFolder: @@: ; reallocate push eax - push [ebp+NTFS.cur_index_buf] - call kernel_free + stdcall kernel_free, [ebp+NTFS.cur_index_buf] pop eax mov [ebp+NTFS.cur_index_size], eax - push eax - call kernel_alloc + stdcall kernel_alloc, eax test eax, eax jnz @f and [ebp+NTFS.cur_index_size], 0 @@ -1485,8 +1600,7 @@ ntfs_ReadFolder: cmp edx, [ebp+NTFS.cur_index_size] jbe .ok2 push esi edx - push edx - call kernel_alloc + stdcall kernel_alloc, edx pop edx esi test eax, eax jz .nomem @@ -1496,8 +1610,7 @@ ntfs_ReadFolder: rep movsd mov esi, eax mov [ebp+NTFS.cur_index_size], edx - push [ebp+NTFS.cur_index_buf] - call kernel_free + stdcall kernel_free, [ebp+NTFS.cur_index_buf] mov [ebp+NTFS.cur_index_buf], esi .ok2: add esi, 10h @@ -1760,8 +1873,8 @@ days400year dd 365*400+100-4+1 days100year dd 365*100+25-1 days4year dd 365*4+1 days1year dd 365 -months dd 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 -months2 dd 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 +months dd 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 +months2 dd 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 _400 dd 400 _100 dd 100 endg @@ -1860,42 +1973,704 @@ ntfs_datetime_to_bdfe: ret ;---------------------------------------------------------------- -; ntfs_Rewrite - NTFS implementation of creating a new file -; in: ebp = pointer to NTFS structure -; in: esi+[esp+4] = name -; in: ebx = pointer to parameters from sysfunc 70 -; out: eax, ebx = return values for sysfunc 70 -;---------------------------------------------------------------- -ntfs_Rewrite: ntfs_CreateFolder: + mov [ebp+NTFS.ntfsFolder], 1 + jmp @f +ntfs_CreateFile: + mov [ebp+NTFS.ntfsFolder], 0 +@@: + cmp byte [esi], 0 + jnz @f xor ebx, ebx - mov eax, ERROR_UNSUPPORTED_FS + movi eax, ERROR_ACCESS_DENIED ; root directory itself + ret +@@: ; 1. Search file + call ntfs_lock + mov [ebp+NTFS.ntfsNotFound], 0 + stdcall ntfs_find_lfn, [esp+4] + jnc @f ; found; rewrite + cmp [ebp+NTFS.ntfsFragmentCount], 1 + jnz @f ; record fragmented + cmp [ebp+NTFS.ntfsNotFound], 1 + jz .notFound + push ERROR_FS_FAIL + jmp ntfsError +@@: + push ERROR_UNSUPPORTED_FS + jmp ntfsError +.notFound: ; create; check name + cmp dword [esp+4], 0 + jnz .bad + cmp byte [esi], 0 + jnz @f +.bad: ; path folder not found + push ERROR_FILE_NOT_FOUND + jmp ntfsError +@@: ; 2. Prepair directory record + mov ecx, esi +@@: ; count characters + inc ecx + cmp byte [ecx], '/' + jz .bad + cmp byte [ecx], 0 + jnz @b + sub ecx, esi + push ecx + lea ecx, [ecx*2+52h] ; precalculate index length + add ecx, 7 ; align 8 + and ecx, not 7 + mov edi, [ebp+NTFS.cur_index_buf] + push esi + push ecx + cmp dword [edi], 'INDX' ; where are we? + jz .indexRecord + mov esi, [ebp+NTFS.frs_buffer] ; mftRecord + mov edx, [esi+recordRealSize] + add edx, ecx + cmp [esi+recordAllocatedSize], edx + jnc @f + add esp, 12 + push ERROR_UNSUPPORTED_FS ; indexAllocation required + jmp ntfsError +@@: ; index fits in the indexRoot + mov [esi+recordRealSize], edx + mov ecx, edx + shr ecx, 2 + rep movsd + mov edi, [ebp+NTFS.ntfs_attr_offs] + sub edi, [ebp+NTFS.frs_buffer] + add edi, [ebp+NTFS.cur_index_buf] + mov esi, [esp] + add [edi+sizeWithHeader], esi + add [edi+sizeWithoutHeader], esi + mov cx, [edi+attributeOffset] + add edi, ecx + add [edi+16+nodeRealSize], esi + add [edi+16+nodeAllocatedSize], esi + sub eax, [ebp+NTFS.cur_index_buf] + add eax, edi + mov edi, [ebp+NTFS.cur_index_buf] + add edi, edx + sub edi, 4 + jmp .common + +.indexRecord: + mov edx, [edi+1ch] + add edx, ecx + cmp [edi+20h], edx + jnc @f + add esp, 12 + push ERROR_UNSUPPORTED_FS ; new node required + jmp ntfsError +@@: ; index fits in the node + mov [edi+1ch], edx + lea edi, [edi+edx+14h] +.common: + mov esi, edi + sub esi, [esp] + mov ecx, esi + sub ecx, eax ; eax = pointer in the node + shr ecx, 2 + inc ecx + std + rep movsd ; move forward, make space + mov ecx, [esp] + shr ecx, 2 + xor eax, eax + rep stosd + cld + add edi, 4 + pop eax + pop esi + mov [edi+indexAllocatedSize], ax ; fill index with data + mov eax, [esp] + lea eax, [eax*2+42h] + mov [edi+indexRawSize], ax + mov eax, [ebp+NTFS.ntfs_attr_iRecord] + mov [edi+directoryRecordReference], eax + mov eax, [ebp+NTFS.frs_buffer] + mov eax, [eax+reuseCounter] + mov [edi+directoryReferenceReuse], ax + mov eax, [ebx+12] + mov [ebp+NTFS.fileRealSize], eax + mov [edi+fileRealSize], eax + mov ecx, [ebp+NTFS.sectors_per_cluster] + shl ecx, 9 + add eax, ecx + dec eax + xor edx, edx + div ecx + mov [ebp+NTFS.fileDataSize], eax + mul ecx + mov [edi+fileAllocatedSize], eax + pop ecx + mov [ebp+NTFS.indexOffset], edi + mov [edi+fileNameLength], cl + add edi, 52h +@@: ; record filename + lodsb + call ansi2uni_char + stosw + dec ecx + jnz @b + mov eax, [ebp+NTFS.ntfsLastRead] + mov [ebp+NTFS.nodeLastRead], eax + cmp [ebp+NTFS.ntfsFolder], 0 + jz @f + mov edi, [ebp+NTFS.indexOffset] + mov byte [edi+fileFlags+3], 16 + jmp .mftBitmap + +@@: ; 3. File data + cmp [ebp+NTFS.fileRealSize], 0 + jz .mftBitmap + ; One piece free space bitmap search engine + mov edi, [ebp+NTFS.BitmapBuffer] + add edi, [ebp+NTFS.BitmapStart] + mov eax, [ebp+NTFS.fileDataSize] + shr eax, 5 + jz .small + push eax ; bitmap dwords + add edi, 4 + xor edx, edx +.start: + mov ecx, [ebp+NTFS.BitmapSize] + mov eax, edi + sub eax, [ebp+NTFS.BitmapBuffer] + sub ecx, eax + shr ecx, 2 +@@: + xor eax, eax + repnz scasd ; search for empty dword + jz @f + call bitmapBuffering + jmp @b +@@: + cmp ecx, [esp] + jnc @f + call bitmapBuffering + jmp @b +@@: + sub edi, 4 + mov ecx, [esp] + mov esi, edi + xor eax, eax + repz scasd ; check following dwords + jnz .start + sub esi, 4 + mov eax, [esi] + bsr edx, eax + inc edx + push edx ; starting bit + push esi ; starting dword + add esi, 4 + neg edx + add edx, 32 + mov eax, [ebp+NTFS.fileDataSize] + sub eax, edx + mov edx, eax + shr eax, 5 + shl eax, 2 + add esi, eax + mov eax, [esi] + bsf ecx, eax ; last dword + jz .done + and edx, 31 + cmp ecx, edx + jnc .done + add esp, 8 + jmp .start + +.small: ; less than 32 clusters + mov ecx, [ebp+NTFS.BitmapSize] + sub ecx, [ebp+NTFS.BitmapStart] + shr ecx, 2 +.smStart: + mov eax, -1 + repz scasd ; search for zero bits + push ecx + test ecx, ecx + jnz @f + call bitmapBuffering + pop eax + jmp .smStart +@@: + sub edi, 4 + mov eax, [edi] + not eax +@@: + bsf ecx, eax ; first 0 + jz .again + not eax + shr eax, cl + shl eax, cl + bsf edx, eax ; next 1 + jz @f + sub edx, ecx + cmp edx, [ebp+NTFS.fileDataSize] + jnc .got ; fits inside + bsf ecx, eax + not eax + shr eax, cl + shl eax, cl + jmp @b +@@: ; next dword + mov eax, [edi+4] + bsf edx, eax + jz .got ; empty + add edx, 32 + sub edx, ecx + cmp edx, [ebp+NTFS.fileDataSize] + jnc .got ; share between dwords +.again: + add edi, 4 + pop ecx + jmp .smStart + +.got: + push ecx ; starting bit + push edi ; starting dword +.done: ; mark space + mov ecx, [esp+4] + cmp ecx, 32 + jc @f + xor ecx, ecx + add dword [esp], 4 + mov [esp+4], ecx +@@: + mov edi, [esp] + mov esi, [ebp+NTFS.fileDataSize] + mov edx, [edi] + ror edx, cl + neg ecx + add ecx, 32 + mov eax, -1 + sub esi, ecx + jnc @f + mov esi, ecx ; fits inside + mov ecx, [ebp+NTFS.fileDataSize] + shrd edx, eax, cl + sub esi, ecx + mov ecx, esi + ror edx, cl + mov [edi], edx + jmp .writeData + +@@: + shrd edx, eax, cl + mov [edi], edx + mov ecx, esi + shr ecx, 5 + add edi, 4 + rep stosd + mov ecx, esi + and ecx, 31 + mov edx, [edi] + shr edx, cl + shld edx, eax, cl + mov [edi], edx +.writeData: + pop edx + sub edx, [ebp+NTFS.BitmapBuffer] + shl edx, 3 + pop eax + add eax, edx + pop edx + mov [ebp+NTFS.fileDataStart], eax + mul [ebp+NTFS.sectors_per_cluster] + mov ecx, [ebp+NTFS.fileRealSize] + add ecx, 511 + shr ecx, 9 + mov ebx, [ebx+16] + call fs_write64_app + test eax, eax + jz .mftBitmap + push 11 + jmp ntfsError + + ; 4. MFT record +.mftBitmap: ; search for free record + mov edi, [ebp+NTFS.mftBitmapBuffer] + mov ecx, [ebp+NTFS.mftBitmapSize] + mov al, -1 + add edi, 3 + sub ecx, 3 + repz scasb + dec edi + movzx eax, byte [edi] + not al + bsf ecx, eax + jnz @f + push ERROR_UNSUPPORTED_FS ; no free records + jmp ntfsError +@@: ; mark record + mov al, [edi] + bts eax, ecx + mov [edi], al + ; get record location + sub edi, [ebp+NTFS.mftBitmapBuffer] + shl edi, 3 + add edi, ecx + mov [ebp+NTFS.newMftRecord], edi + mov eax, [ebp+NTFS.frs_size] + shr eax, 9 + mul edi + mov [ebp+NTFS.ntfs_cur_iRecord], 0 + mov [ebp+NTFS.ntfs_cur_attr], 0x80 + mov [ebp+NTFS.ntfs_cur_offs], eax + mov [ebp+NTFS.ntfs_cur_size], 1 + mov eax, [ebp+NTFS.frs_buffer] + mov [ebp+NTFS.ntfs_cur_buf], eax + call ntfs_read_attr + cmp [ebp+NTFS.ntfs_cur_read], 0 + jnz .mftRecord + ; extend MFT $DATA + mov eax, [ebp+NTFS.mft_cluster] + mul [ebp+NTFS.sectors_per_cluster] + push ERROR_UNSUPPORTED_FS + cmp eax, [ebp+NTFS.ntfsLastRead] + jnz ntfsError ; auxiliary record + mov edi, [ebp+NTFS.ntfs_attr_offs] + mov ebx, [ebp+NTFS.sectors_per_cluster] + shl ebx, 9+3 + add dword [edi+lastVCN], 8 + add [edi+attributeAllocatedSize], ebx + add [edi+attributeRealSize], ebx + add [edi+initialDataSize], ebx + add edi, [edi+dataRunsOffset] + movzx eax, byte [edi] + inc edi + shl eax, 4 + shr al, 4 + mov cl, 4 + sub cl, al + shl cl, 3 + add ah, al + shr eax, 8 + cmp byte [edi+eax], 0 + jnz ntfsError ; $MFT fragmented + mov al, 8 + mov edx, [edi] + rol eax, cl + rol edx, cl + add eax, edx + jc ntfsError + ror eax, cl + shr edx, cl + mov [edi], eax + add edx, [ebp+NTFS.mft_cluster] + mov esi, edx + mov ecx, edx + and ecx, 7 + shr edx, 3 + add edx, [ebp+NTFS.BitmapBuffer] + movzx eax, word [edx] + shr eax, cl + jnz ntfsError + mov al, -1 + xchg [edx], al + mov [edx+1], al + pop eax + push 12 + stdcall kernel_alloc, ebx + test eax, eax + jz ntfsError + mov ecx, ebx + shr ecx, 2 + mov edi, eax + push ebx + mov ebx, eax + xor eax, eax + rep stosd + mov eax, esi + mul [ebp+NTFS.sectors_per_cluster] + pop ecx + shr ecx, 9 + call fs_write64_sys ; clear new records + stdcall kernel_free, ebx + pop eax + push 11 + mov eax, esi + shr eax, 3+9 + mov ebx, eax + shl ebx, 9 + add ebx, [ebp+NTFS.BitmapBuffer] + add eax, [ebp+NTFS.BitmapLocation] + mov ecx, 1 + xor edx, edx + call fs_write64_app ; partition bitmap + test eax, eax + jnz ntfsError + mov eax, [ebp+NTFS.frs_buffer] + mov [ebp+NTFS.ntfs_cur_buf], eax + call writeRecord ; $MFT + test eax, eax + jnz ntfsError + mov eax, [ebp+NTFS.mftmirr_cluster] + mul [ebp+NTFS.sectors_per_cluster] + mov ebx, [ebp+NTFS.frs_buffer] + movzx ecx, word [ebx+updateSequenceSize] + dec ecx + call fs_write64_sys ; $MFTMirr + test eax, eax + jnz ntfsError + pop eax + mov eax, [ebp+NTFS.ntfs_cur_offs] + add [ebp+NTFS.ntfsLastRead], eax +.mftRecord: + mov esi, [ebp+NTFS.indexOffset] + mov edi, [ebp+NTFS.frs_buffer] + xor eax, eax + movzx ecx, word [esi+indexAllocatedSize] + add ecx, 8+30h+48h+50h+8 + push ecx + shr ecx, 2 + rep stosd + mov edi, [ebp+NTFS.frs_buffer] + ; record header + mov dword[edi], 'FILE' + mov byte [edi+updateSequenceOffset], 2ah + mov byte [edi+updateSequenceSize], 3 + mov byte [edi+hardLinkCounter], 1 + mov byte [edi+attributeOffset], 30h + pop dword[edi+recordRealSize] + mov word [edi+recordAllocatedSize], 1024 + mov byte [edi+newAttributeID], 3 + rdtsc + mov [edi+2ah], ax + add edi, 30h + ; $StandardInformation + mov byte [edi+attributeType], 10h + mov byte [edi+sizeWithHeader], 48h + mov byte [edi+sizeWithoutHeader], 30h + mov byte [edi+attributeOffset], 18h + add edi, 48h + ; $FileName + mov byte [edi+attributeType], 30h + mov byte [edi+attributeID], 1 + mov cx, [esi+indexRawSize] + mov [edi+sizeWithoutHeader], ecx + mov cx, [esi+indexAllocatedSize] + add ecx, 8 + mov [edi+sizeWithHeader], ecx + mov byte [edi+attributeOffset], 18h + mov byte [edi+attributeFlags], 1 + add edi, 18h + add esi, 16 + sub ecx, 18h + shr ecx, 2 + rep movsd + cmp [ebp+NTFS.ntfsFolder], 0 + jnz @f + ; $Data + mov byte [edi+attributeType], 80h + cmp [ebp+NTFS.fileRealSize], 0 + jz .zeroSize + mov esi, [ebp+NTFS.indexOffset] + mov byte [edi+nonResidentFlag], 1 + mov byte [edi+dataRunsOffset], 40h + mov eax, [esi+fileAllocatedSize] + mov [edi+attributeAllocatedSize], eax + mov eax, [esi+fileRealSize] + mov [edi+attributeRealSize], eax + mov [edi+initialDataSize], eax + mov byte [edi+40h], 44h + mov eax, [ebp+NTFS.fileDataSize] + mov [edi+41h], eax + dec eax + mov [edi+lastVCN], eax + mov eax, [ebp+NTFS.fileDataStart] + mov [edi+45h], eax + mov al, 1 + jmp .writeMftRecord + +.zeroSize: + mov byte [edi+attributeOffset], 18h + mov al, 1 + jmp .writeMftRecord + +@@: ; $IndexRoot + mov byte [edi+attributeType], 90h + mov byte [edi+nameLength], 4 + mov byte [edi+nameOffset], 18h + mov byte [edi+sizeWithoutHeader], 30h + mov byte [edi+attributeOffset], 20h + mov dword[edi+18h], 490024h ; unicode $I30 + mov dword[edi+18h+4], 300033h + add edi, 20h + mov byte [edi+attributeType], 30h + mov byte [edi+collationRule], 1 + mov eax, [ebp+NTFS.sectors_per_cluster] + shl eax, 9 + mov [edi+indexRecordSize], eax + mov byte [edi+indexRecordSizeClus], 1 + mov byte [edi+16+indexOffset], 16 + mov byte [edi+16+nodeRealSize], 32 + mov byte [edi+16+nodeAllocatedSize], 32 + mov byte [edi+32+indexAllocatedSize], 16 + mov byte [edi+32+indexFlags], 2 + sub edi, 20h + mov al, 3 +.writeMftRecord: + mov byte [edi+sizeWithHeader], 50h + mov byte [edi+attributeID], 2 + mov dword[edi+50h], -1 ; $End + mov edi, [ebp+NTFS.frs_buffer] + mov [edi+recordFlags], al + mov [ebp+NTFS.ntfs_cur_buf], edi + call writeRecord + test eax, eax + jz @f + push 11 + jmp ntfsError +@@: + mov esi, [ebp+PARTITION.Disk] + call disk_sync + ; write MFT bitmap + mov eax, [ebp+NTFS.newMftRecord] + shr eax, 3+9 + mov ebx, eax + shl ebx, 9 + add eax, [ebp+NTFS.mftBitmapLocation] + add ebx, [ebp+NTFS.mftBitmapBuffer] + mov ecx, 1 + xor edx, edx + call fs_write64_sys + test eax, eax + jz @f + push 11 + jmp ntfsError +@@: ; 5. Write partition bitmap + cmp [ebp+NTFS.ntfsFolder], 0 + jnz @f + cmp [ebp+NTFS.fileRealSize], 0 + jz @f + mov ecx, [ebp+NTFS.fileDataStart] + mov eax, ecx + add ecx, [ebp+NTFS.fileDataSize] + add ecx, 4095 + shr ecx, 3+9 + shr eax, 3+9 + sub ecx, eax + mov ebx, eax + shl ebx, 9 + add eax, [ebp+NTFS.BitmapLocation] + add ebx, [ebp+NTFS.BitmapBuffer] + xor edx, edx + call fs_write64_app + test eax, eax + jz @f + push 11 + jmp ntfsError +@@: + mov esi, [ebp+PARTITION.Disk] + call disk_sync + mov edi, [ebp+NTFS.indexOffset] + mov eax, [ebp+NTFS.newMftRecord] + mov [edi+fileRecordReference], eax + ; 6. Write directory node + mov eax, [ebp+NTFS.nodeLastRead] + mov [ebp+NTFS.ntfsLastRead], eax + mov eax, [ebp+NTFS.cur_index_buf] + mov [ebp+NTFS.ntfs_cur_buf], eax + call writeRecord + push eax + mov esi, [ebp+PARTITION.Disk] + call disk_sync + call ntfs_unlock + pop eax + mov ebx, [ebp+NTFS.fileRealSize] ret -;---------------------------------------------------------------- -; ntfs_Write - NTFS implementation of writing to file -; in: ebp = pointer to NTFS structure -; in: esi+[esp+4] = name -; in: ebx = pointer to parameters from sysfunc 70 -; out: eax, ebx = return values for sysfunc 70 +writeRecord: +; in: +; [ebp+NTFS.ntfs_cur_buf] = record +; [ebp+NTFS.ntfsLastRead] = partition sector + ; making updateSequence + mov esi, [ebp+NTFS.ntfs_cur_buf] + mov edi, esi + movzx ecx, word [esi+updateSequenceOffset] + add edi, ecx + mov ax, [edi] + add edi, 2 + mov cx, [esi+updateSequenceSize] + dec ecx + push ecx +@@: + add esi, 510 + movsw + mov [esi-2], ax + dec ecx + jnz @b + ; writing to disk + mov eax, [ebp+NTFS.ntfsLastRead] + mov ebx, [ebp+NTFS.ntfs_cur_buf] + pop ecx + xor edx, edx + jmp fs_write64_sys + +bitmapBuffering: +; Extend BitmapBuffer and read next 32kb of bitmap +; Warning: $Bitmap fragmentation is not foreseen + push ebx + mov eax, [ebp+NTFS.BitmapTotalSize] + cmp eax, [ebp+NTFS.BitmapSize] + jz .end + stdcall alloc_pages, 8 + test eax, eax + jz .end + add eax, 3 + mov ebx, [ebp+NTFS.BitmapBuffer] + add ebx, [ebp+NTFS.BitmapSize] + push ebx + mov ecx, 8 + call commit_pages + mov eax, [ebp+NTFS.BitmapSize] + shr eax, 9 + add eax, [ebp+NTFS.BitmapLocation] + pop ebx + mov ecx, 64 + xor edx, edx + call fs_read64_app + test eax, eax + jnz .err + add [ebp+NTFS.BitmapSize], 8000h + mov eax, [ebp+NTFS.BitmapTotalSize] + cmp eax, [ebp+NTFS.BitmapSize] + jnc @f + mov [ebp+NTFS.BitmapSize], eax +@@: + mov ecx, [ebp+NTFS.BitmapSize] + mov eax, edi + sub eax, [ebp+NTFS.BitmapBuffer] + sub ecx, eax + shr ecx, 2 + pop ebx + ret + +.err: + mov eax, [ebp+NTFS.BitmapBuffer] + add eax, [ebp+NTFS.BitmapSize] + mov ecx, 8 + call release_pages +.end: + add esp, 12 ; double ret + push ERROR_DISK_FULL + jmp ntfsError + ;---------------------------------------------------------------- ntfs_Write: xor ebx, ebx mov eax, ERROR_UNSUPPORTED_FS ret +;---------------------------------------------------------------- ntfs_SetFileEnd: ntfs_SetFileInfo: ntfs_Delete: mov eax, ERROR_UNSUPPORTED_FS ret -;---------------------------------------------------------------- -; ntfs_GetFileInfo - NTFS implementation of getting file info -; in: ebp = pointer to NTFS structure -; in: esi+[esp+4] = name -; in: ebx = pointer to parameters from sysfunc 70 -; out: eax, ebx = return values for sysfunc 70 ;---------------------------------------------------------------- ntfs_GetFileInfo: cmp byte [esi], 0 @@ -1907,14 +2682,11 @@ ntfs_GetFileInfo: stdcall ntfs_find_lfn, [esp+4] jnc .doit test eax, eax - movi eax, ERROR_FILE_NOT_FOUND - jz @f - mov al, 11 -@@: - push eax - call ntfs_unlock + push ERROR_FILE_NOT_FOUND + jz ntfsError pop eax - ret + push 11 + jmp ntfsError .doit: push esi edi mov esi, eax @@ -1926,3 +2698,8 @@ ntfs_GetFileInfo: xor eax, eax ret +ntfsError: + call ntfs_unlock + xor ebx, ebx + pop eax + ret diff --git a/kernel/branches/Kolibri-acpi/gui/char.mt b/kernel/branches/Kolibri-acpi/gui/char.mt index 1663b817dc..6d7aae7b93 100644 Binary files a/kernel/branches/Kolibri-acpi/gui/char.mt and b/kernel/branches/Kolibri-acpi/gui/char.mt differ diff --git a/kernel/branches/Kolibri-acpi/gui/char2.mt b/kernel/branches/Kolibri-acpi/gui/char2.mt deleted file mode 100644 index d275251663..0000000000 Binary files a/kernel/branches/Kolibri-acpi/gui/char2.mt and /dev/null differ diff --git a/kernel/branches/Kolibri-acpi/gui/char2_et.mt b/kernel/branches/Kolibri-acpi/gui/char2_et.mt deleted file mode 100644 index 73993dde9d..0000000000 Binary files a/kernel/branches/Kolibri-acpi/gui/char2_et.mt and /dev/null differ diff --git a/kernel/branches/Kolibri-acpi/gui/char2_sp.mt b/kernel/branches/Kolibri-acpi/gui/char2_sp.mt deleted file mode 100644 index d275251663..0000000000 Binary files a/kernel/branches/Kolibri-acpi/gui/char2_sp.mt and /dev/null differ diff --git a/kernel/branches/Kolibri-acpi/gui/charUni.mt b/kernel/branches/Kolibri-acpi/gui/charUni.mt new file mode 100644 index 0000000000..df5ca5c41d Binary files /dev/null and b/kernel/branches/Kolibri-acpi/gui/charUni.mt differ diff --git a/kernel/branches/Kolibri-acpi/gui/font.inc b/kernel/branches/Kolibri-acpi/gui/font.inc index 60dfad86a5..e15e4905c2 100644 --- a/kernel/branches/Kolibri-acpi/gui/font.inc +++ b/kernel/branches/Kolibri-acpi/gui/font.inc @@ -7,230 +7,823 @@ $Revision$ -;------------------------------------------------------------------------------ -align 4 -dtext_asciiz_esi: ; for skins title out - push eax - xor eax, eax - inc eax - jmp dtext.1 -;------------------------------------------------------------------------------ -align 4 dtext: -; ebx x & y -; ecx style ( 0xX0000000 ) & color ( 0x00RRGGBB ) -; X = ABnnb: -; nn = font -; A = 0 <=> output esi characters; otherwise output ASCIIZ string -; B = 1 <=> fill background with color eax -; edx start of text -; edi 1 force or user area for redirect - push eax +; edx -> string +; esi = number of characters +; ebx = output coordinates XXXXYYYY h +; ecx = char color and flags flRRGGBB h +; fl = ZBFFRSSS b +; Z=1: edx -> zero terminated string, esi = ? +; B=1: fill background with color eax +; R=1: edi -> user area for redirect +; FF=3: UTF-8 8x16, FF=2: UTF-16LE 8x16 +; FF=1: cp866 8x16, FF=0: cp866 6x9 +; SSS = (font multiplier)-1 +; edi=1: force output + and eax, 0xFFFFFF + bt ecx, 30 + jc @f xor eax, eax -;-------------------------------------- -align 4 -.1: - pushad - movsx eax, bx ; eax=y - sar ebx, 16 ; ebx=x - xchg eax, ebx ; eax=x, ebx=y - cmp esi, 255 - jb .loop - - mov esi, 255 -;-------------------------------------- -align 4 -.loop: - test ecx, ecx - js .test_asciiz - - dec esi - js .end - + dec eax +@@: + pushd 0 0 0 eax + movsx eax, bx + sar ebx, 16 + push eax ebx edi + bt ecx, 27 + jc .redirect + mov ebp, [_display.width] + xor edi, edi jmp @f -;-------------------------------------- -align 4 -.test_asciiz: - cmp byte [edx], 0 - jz .end - - cmp byte [esp+28], 1 - jne @f - - dec esi - js .end -;-------------------------------------- -align 4 -@@: - inc edx - pushad - movzx edx, byte [edx-1] - test ecx, 0x10000000 - jnz .font2 - - mov esi, 9 - lea ebp, [FONT_I+8*edx+edx] -;-------------------------------------- -align 4 -.symloop1: - mov dl, byte [ebp] - or dl, 1 shl 6 -;-------------------------------------- -align 4 -.pixloop1: - shr dl, 1 - jz .pixloop1end - - jnc .nopix - - test ecx, 0x08000000 ; redirect the output to the user area - jz @f - - call draw_text_to_user_area - jmp .pixloop1cont -;-------------------------------------- -align 4 -@@: - and ecx, 0xFBFFFFFF ;negate 0x04000000 save to mouseunder area -; call [putpixel] - call __sys_putpixel - jmp .pixloop1cont -;-------------------------------------- -align 4 -.nopix: - test ecx, 0x40000000 - jz .pixloop1cont - - push ecx - mov ecx, [esp+4+20h+20h] - - test ecx, 0x08000000 ; redirect the output to the user area - jz @f - - call draw_text_to_user_area - pop ecx - jmp .pixloop1cont -;-------------------------------------- -align 4 -@@: - and ecx, 0xFBFFFFFF ;negate 0x04000000 save to mouseunder area -; call [putpixel] - call __sys_putpixel - pop ecx -;-------------------------------------- -align 4 -.pixloop1cont: - inc eax - jmp .pixloop1 -;-------------------------------------- -align 4 -.pixloop1end: - sub eax, 6 - inc ebx - inc ebp - dec esi - jnz .symloop1 - - popad - add eax, 6 - jmp .loop -;-------------------------------------- -align 4 -.font2: - add edx, edx - lea ebp, [FONT_II+4*edx+edx+1] - push 9 - movzx esi, byte [ebp-1] -;-------------------------------------- -align 4 -.symloop2: - mov dl, byte [ebp] - push esi -;-------------------------------------- -align 4 -.pixloop2: - shr dl, 1 - jnc .nopix2 - - test ecx, 0x08000000 ; redirect the output to the user area - jz @f - - call draw_text_to_user_area - jmp .pixloop2cont -;-------------------------------------- -align 4 -@@: - and ecx, 0xFBFFFFFF ;negate 0x04000000 save to mouseunder area -; call [putpixel] - call __sys_putpixel - jmp .pixloop2cont -;-------------------------------------- -align 4 -.nopix2: - test ecx, 0x40000000 - jz .pixloop2cont - - push ecx - mov ecx, [esp+12+20h+20h] - - test ecx, 0x08000000 ; redirect the output to the user area - jz @f - - call draw_text_to_user_area - pop ecx - jmp .pixloop2cont -;-------------------------------------- -align 4 -@@: - and ecx, 0xFBFFFFFF ;negate 0x04000000 save to mouseunder area -; call [putpixel] - call __sys_putpixel - pop ecx -;-------------------------------------- -align 4 -.pixloop2cont: - inc eax - dec esi - jnz .pixloop2 - - pop esi - sub eax, esi - inc ebx - inc ebp - dec dword [esp] - jnz .symloop2 - - pop eax - add dword [esp+28], esi - popad - jmp .loop -;-------------------------------------- -align 4 -.end: - popad - pop eax +.ret: + add esp, 28 ret -;------------------------------------------------------------------------------ -; eax = x coordinate -; ebx = y coordinate -; ecx = ?? RR GG BB -; edi = user area -align 4 -draw_text_to_user_area: - pushad - imul ebx, [edi+0] +.redirect: + mov ebp, [edi] + add edi, 8 +@@: + shl ebp, 2 + imul eax, ebp + shl ebx, 2 add eax, ebx - shl eax, 2 - add eax, edi - add eax, 8 - and ecx, 0xffffff - or ecx, 0xff000000 ; not transparent - mov [eax], ecx ; store pixel - popad + js .ret + add edi, eax + mov eax, ecx + mov ebx, ecx + test ecx, ecx + jns @f + mov esi, 256 +@@: + shr ecx, 24 + and cl, 7 + inc ecx + push ebp ecx esi + mov esi, edx + or eax, 0xFF000000 + bt ebx, 27 + jc .bufferReady + mov eax, 9 + test ebx, 0x30000000 + jz @f + add eax, 7 +@@: + imul eax, ecx + mov [esp+32], eax + imul ebp, eax + stdcall kernel_alloc, ebp + mov ecx, ebp + shr ecx, 2 + mov [esp+36], eax + sub edi, eax + mov edx, eax + mov eax, [esp+24] + cmp eax, -1 + jnz @f + mov [esp+28], edi +@@: + mov edi, edx + rep stosd + mov edi, edx + mov eax, ebx + and eax, 0xFFFFFF +.bufferReady: + mov ebp, eax + xor edx, edx + bt ebx, 29 + jc @f + bt ebx, 28 + jc .draw866toUni + jmp .draw866 +@@: + bt ebx, 28 + jc .drawUTF8 + +; ebp = font color +; esi -> string +; edi -> buffer + +; Stack map: +; char counter +0 +fontMultiplier = 4 +widthX = 8 +; edi +12 +; X +16 +; Y +20 +; background +24 +deltaToScreen = 28 +; temp buffer height +32 +; temp buffer pointer +36 + +.drawUTF16: + dec dword [esp] + js .done + movzx ebx, word [esi] + test ebx, ebx + jz .done + inc esi + inc esi + cmp bx, 1419 + jc @f + xor ebx, ebx +@@: + pushd esi edi 16 + shl ebx, 4 + add ebx, fontUni + mov esi, [esp+12+fontMultiplier] + call drawChar + imul esi, 8*4 + pop edi + pop edi + add edi, esi + pop esi + jmp .drawUTF16 + +.drawUTF8: + dec dword [esp] + js .done +@@: + movzx ebx, byte [esi] + inc esi + test bl, bl + jz .done + jns .valid + shl bx, 10 + jnc @b + mov bl, [esi] + test bl, bl + jns @b + shl bl, 2 + jc @b + shr bh, 2 + shr bx, 2 + inc esi + cmp bx, 1419 + jc .valid + shl bh, 4 + jns @f +.tail: + mov bl, [esi] + shl bl, 1 + jnc @b + js @b + inc esi + shl bh, 1 + js .tail +@@: + xor ebx, ebx +.valid: + pushd esi edi 16 + shl ebx, 4 + add ebx, fontUni + mov esi, [esp+12+fontMultiplier] + call drawChar + imul esi, 8*4 + pop edi + pop edi + add edi, esi + pop esi + jmp .drawUTF8 + +.draw866: + dec dword [esp] + js .done + movzx ebx, byte [esi] + test ebx, ebx + jz .done + inc esi + pushd esi edi 9 + lea ebx, [ebx*8+ebx+font1] + mov esi, [esp+12+fontMultiplier] + call drawChar + imul esi, 6*4 + pop edi + pop edi + add edi, esi + pop esi + jmp .draw866 + +.draw866toUni: + dec dword [esp] + js .done + movzx eax, byte [esi] + test eax, eax + jz .done + call ansi2uni_char + shl eax, 4 + lea ebx, [eax+fontUni] + inc esi + pushd esi edi 16 + mov esi, [esp+12+fontMultiplier] + call drawChar + imul esi, 8*4 + pop edi + pop edi + add edi, esi + pop esi + jmp .draw866toUni + +.done: + mov ecx, edi + pop eax eax eax esi edx ebx ebp ebp ebp + mov edi, [esp] + test edi, edi + jnz @f + pop eax ret -;------------------------------------------------------------------------------ -align 4 -FONT_I: +@@: ; redraw from buffer to screen + push eax + sub ecx, edi + shr ecx, 2 + add edx, ecx + inc ecx + push ecx + push edi +.drawPicture: + mov eax, -1 + repz scasd + jcxz @f + mov eax, edx + sub eax, ecx + push ecx + mov ecx, [edi-4] + xchg esi, edi + call __sys_putpixel + xchg esi, edi + pop ecx + jmp .drawPicture +@@: + pop edi + mov ecx, [esp] + add edi, [esp+4] + inc ebx + push edi + dec ebp + jnz .drawPicture + add esp, 12 + call kernel_free + ret + +; scaling/smoothing algorithm +drawChar: +; ebp = font color +; esi = font multiplier +; edi -> buffer +; ebx -> char data + mov dl, [ebx] +.raw: + bsf eax, edx + jz .nextRaw + imul eax, esi + shl eax, 2 + push edi + add edi, eax + mov ecx, esi + dec esi + jnz .square + mov [edi], ebp + inc esi + cmp [fontSmoothing], 0 + jz .nextPixel +.checkLeftSM: ; smoothing + bsf eax, edx + dec eax + js .checkRightSM + bt [ebx], eax + jc .checkRightSM + dec eax + js .checkLeftDownSM + bt [ebx], eax + jc .checkRightSM +.checkLeftDownSM: + inc eax + bt [ebx+1], eax + jnc .checkLeftUpSM + inc eax + bt [ebx+1], eax + jnc @f + bt [ebx-1], eax + jc .checkRightSM + dec eax + dec eax + js @f + bt [ebx+1], eax + jnc @f + inc eax +.checkLeftUpSM: + bt [ebx-1], eax + jnc .checkRightSM + inc eax + bt [ebx-1], eax + jnc @f + bt [ebx+1], eax + jc .checkRightSM + dec eax + dec eax + js @f + bt [ebx-1], eax + jc .checkRightSM +@@: + mov ecx, [esp+20+deltaToScreen] + mov eax, [edi-4] + test ecx, ecx + jz @f + pusha + lea ebx, [edi+ecx-4] + shr ebx, 2 + call syscall_getpixel + popa +@@: + push ebx edx + mov ebx, ebp + xor ecx, ecx + cmp [fontSmoothing], 1 + jnz .subpixelLeft + call antiAliasing + jmp @f +.subpixelLeft: + mov cl, bl + lea edx, [ecx*8+ecx] + lea edx, [ecx*2+edx] + mov cl, al + lea ecx, [ecx*4+ecx] + add edx, ecx + shr edx, 4 + mov al, dl + + xor ecx, ecx + mov cl, ah + lea edx, [ecx*8+ecx] + lea edx, [ecx*2+edx] + mov cl, bh + lea ecx, [ecx*4+ecx] + add edx, ecx + shr edx, 4 + mov ah, dl + + rol eax, 16 + rol ebx, 16 + xor ecx, ecx + mov cl, al + mov edx, ecx + shl ecx, 3 + sub ecx, edx + mov dl, bl + add ecx, edx + shr ecx, 3 + mov al, cl + rol eax, 16 +@@: + mov [edi-4], eax + pop edx ebx +.checkRightSM: + bsf eax, edx + inc eax + bt [ebx], eax + jc .nextPixel + inc eax + bt [ebx], eax + jc .nextPixel + dec eax +.checkRightDownSM: + bt [ebx+1], eax + jnc .checkRightUpSM + dec eax + bt [ebx+1], eax + jnc @f + bt [ebx-1], eax + jc .nextPixel + inc eax + inc eax + bt [ebx+1], eax + jnc @f + dec eax +.checkRightUpSM: + bt [ebx-1], eax + jnc .nextPixel + dec eax + bt [ebx-1], eax + jnc @f + bt [ebx+1], eax + jc .nextPixel + inc eax + inc eax + bt [ebx-1], eax + jc .nextPixel +@@: + mov ecx, [esp+20+deltaToScreen] + mov eax, [edi+4] + test ecx, ecx + jz @f + pusha + lea ebx, [edi+ecx+4] + shr ebx, 2 + call syscall_getpixel + popa +@@: + push ebx edx + mov ebx, ebp + xor ecx, ecx + cmp [fontSmoothing], 1 + jnz .subpixelRight + call antiAliasing + jmp @f +.subpixelRight: + mov cl, al + mov edx, ecx + shl ecx, 3 + sub ecx, edx + mov dl, bl + add ecx, edx + shr ecx, 3 + mov al, cl + + xor ecx, ecx + mov cl, ah + lea edx, [ecx*8+ecx] + lea edx, [ecx*2+edx] + mov cl, bh + lea ecx, [ecx*4+ecx] + add edx, ecx + shr edx, 4 + mov ah, dl + + rol ebx, 16 + rol eax, 16 + xor ecx, ecx + mov cl, bl + lea edx, [ecx*8+ecx] + lea edx, [ecx*2+edx] + mov cl, al + lea ecx, [ecx*4+ecx] + add edx, ecx + shr edx, 4 + mov al, dl + rol eax, 16 +@@: + mov [edi+4], eax + pop edx ebx + jmp .nextPixel + +.square: ; scaling + mov eax, esi +@@: + mov [edi+eax*4], ebp + dec eax + jns @b + add edi, [esp+20+widthX] + dec ecx + jnz .square + inc esi + mov edi, [esp] +.checkLeft: + bsf eax, edx + dec eax + js .checkRight + bt [ebx], eax + jc .checkRight +.checkLeftDown: + bt [ebx+1], eax + jnc .checkLeftUp + mov ecx, eax + inc eax + bt [ebx+1], eax + jc @f + bt [ebx-1], eax + jnc .downRightLow + bt [ebx-2], eax + jc .downRightLow + dec eax + bt [ebx-1], eax + jc .downRightLow + dec eax + js .downRightHigh + bt [ebx-2], eax + jc .downRightLow + jmp .downRightHigh + +@@: + bt [ebx-1], eax + jc .checkLeftUp + dec eax + dec eax + js .downRightLow + bt [ebx+1], eax + jc .checkLeftUp +.downRightLow: + imul ecx, esi + shl ecx, 2 + add edi, ecx + dec esi + mov eax, [esp+20+widthX] + imul eax, esi + add edi, eax + add edi, 4 + mov ecx, esi + dec ecx +.drawDownRight: + mov eax, ecx +@@: + mov [edi+eax*4], ebp + dec eax + jns @b + sub edi, [esp+20+widthX] + add edi, 4 + dec ecx + jns .drawDownRight + inc esi + mov edi, [esp] + jmp .checkLeftUp + +.downRightHigh: + imul ecx, esi + shl ecx, 2 + add edi, ecx + dec esi + mov eax, [esp+20+widthX] + imul eax, esi + add edi, eax + add edi, 4 + mov ecx, esi + dec ecx +.drawDownRightHigh: + mov eax, ecx +@@: + mov [edi+eax*4], ebp + dec eax + jns @b + sub edi, [esp+20+widthX] + mov eax, ecx +@@: + mov [edi+eax*4], ebp + dec eax + jns @b + sub edi, [esp+20+widthX] + add edi, 4 + dec ecx + jns .drawDownRightHigh + inc esi + mov edi, [esp] +.checkLeftUp: + bsf eax, edx + dec eax + bt [ebx-1], eax + jnc .checkRight + mov ecx, eax + inc eax + bt [ebx-1], eax + jc @f + bt [ebx+1], eax + jnc .upRightLow + bt [ebx+2], eax + jc .upRightLow + dec eax + bt [ebx+1], eax + jc .upRightLow + dec eax + js .upRightHigh + bt [ebx+2], eax + jc .upRightLow + jmp .upRightHigh + +@@: + bt [ebx+1], eax + jc .checkRight + dec eax + dec eax + js .upRightLow + bt [ebx-1], eax + jc .checkRight +.upRightLow: + imul ecx, esi + shl ecx, 2 + add edi, ecx + add edi, 4 + mov ecx, esi + dec ecx + dec ecx +.drawUpRight: + mov eax, ecx +@@: + mov [edi+eax*4], ebp + dec eax + jns @b + add edi, [esp+20+widthX] + add edi, 4 + dec ecx + jns .drawUpRight + mov edi, [esp] + jmp .checkRight + +.upRightHigh: + imul ecx, esi + shl ecx, 2 + add edi, ecx + add edi, 4 + mov ecx, esi + dec ecx + dec ecx +.drawUpRightHigh: + mov eax, ecx +@@: + mov [edi+eax*4], ebp + dec eax + jns @b + add edi, [esp+20+widthX] + mov eax, ecx +@@: + mov [edi+eax*4], ebp + dec eax + jns @b + add edi, [esp+20+widthX] + add edi, 4 + dec ecx + jns .drawUpRightHigh + mov edi, [esp] +.checkRight: + bsf eax, edx + inc eax + bt [ebx], eax + jc .nextPixel +.checkRightDown: + bt [ebx+1], eax + jnc .checkRightUp + mov ecx, eax + dec eax + bt [ebx+1], eax + jc @f + bt [ebx-1], eax + jnc .downLeftLow + bt [ebx-2], eax + jc .downLeftLow + inc eax + bt [ebx-1], eax + jc .downLeftLow + inc eax + bt [ebx-2], eax + jc .downLeftLow + jmp .downLeftHigh + +@@: + bt [ebx-1], eax + jc .checkRightUp + inc eax + inc eax + bt [ebx+1], eax + jc .checkRightUp +.downLeftLow: + imul ecx, esi + shl ecx, 2 + add edi, ecx + dec esi + mov eax, [esp+20+widthX] + imul eax, esi + add edi, eax + mov ecx, esi + dec ecx +.drawDownLeft: + mov eax, ecx +@@: + mov [edi+eax*4], ebp + dec eax + jns @b + sub edi, [esp+20+widthX] + dec ecx + jns .drawDownLeft + inc esi + mov edi, [esp] + jmp .checkRightUp + +.downLeftHigh: + imul ecx, esi + shl ecx, 2 + add edi, ecx + dec esi + mov eax, [esp+20+widthX] + imul eax, esi + add edi, eax + mov ecx, esi + dec ecx +.drawDownLeftHigh: + mov eax, ecx +@@: + mov [edi+eax*4], ebp + dec eax + jns @b + sub edi, [esp+20+widthX] + mov eax, ecx +@@: + mov [edi+eax*4], ebp + dec eax + jns @b + sub edi, [esp+20+widthX] + dec ecx + jns .drawDownLeftHigh + inc esi + mov edi, [esp] +.checkRightUp: + bsf eax, edx + inc eax + bt [ebx-1], eax + jnc .nextPixel + mov ecx, eax + dec eax + bt [ebx-1], eax + jc @f + bt [ebx+1], eax + jnc .upLeftLow + bt [ebx+2], eax + jc .upLeftLow + inc eax + bt [ebx+1], eax + jc .upLeftLow + inc eax + bt [ebx+2], eax + jc .upLeftLow + jmp .upLeftHigh + +@@: + bt [ebx+1], eax + jc .nextPixel + inc eax + inc eax + bt [ebx-1], eax + jc .nextPixel +.upLeftLow: + imul ecx, esi + shl ecx, 2 + add edi, ecx + mov ecx, esi + dec ecx + dec ecx +.drawUpLeft: + mov eax, ecx +@@: + mov [edi+eax*4], ebp + dec eax + jns @b + add edi, [esp+20+widthX] + dec ecx + jns .drawUpLeft + jmp .nextPixel + +.upLeftHigh: + imul ecx, esi + shl ecx, 2 + add edi, ecx + mov ecx, esi + dec ecx + dec ecx +.drawUpLeftHigh: + mov eax, ecx +@@: + mov [edi+eax*4], ebp + dec eax + jns @b + add edi, [esp+20+widthX] + mov eax, ecx +@@: + mov [edi+eax*4], ebp + dec eax + jns @b + add edi, [esp+20+widthX] + dec ecx + jns .drawUpLeftHigh +.nextPixel: + bsf eax, edx + btr edx, eax + pop edi + jmp .raw + +.nextRaw: + inc ebx + mov eax, [esp+16+widthX] + imul eax, esi + add edi, eax + dec dword [esp+4] + jnz drawChar + ret + +antiAliasing: + mov bp, 3 +@@: + mov cl, al + mov dl, bl + lea ecx, [ecx*2+ecx] + add ecx, edx + shr ecx, 2 + mov al, cl + ror eax, 8 + ror ebx, 8 + dec bp + jnz @b + ror eax, 8 + ror ebx, 8 + mov ebp, ebx + ret + +fontSmoothing db 2 ; = 0, 1 or 2 +fontSize db 0 ; user mode setting +font1: if lang eq sp file 'char_sp.mt' else if lang eq et @@ -238,14 +831,5 @@ FONT_I: else file 'char.mt' end if -;------------------------------------------------------------------------------ -align 4 -FONT_II: - if lang eq sp - file 'char2_sp.mt' - else if lang eq et - file 'char2_et.mt' - else - file 'char2.mt' - end if -;------------------------------------------------------------------------------ +fontUni: +file 'charUni.mt' diff --git a/kernel/branches/Kolibri-acpi/gui/mouse.inc b/kernel/branches/Kolibri-acpi/gui/mouse.inc index c39cc5e140..b8452648ac 100644 --- a/kernel/branches/Kolibri-acpi/gui/mouse.inc +++ b/kernel/branches/Kolibri-acpi/gui/mouse.inc @@ -9,9 +9,9 @@ $Revision$ include 'mousepointer.inc' -;============================================================================== -;///// public functions /////////////////////////////////////////////////////// -;============================================================================== +;================================ +;/////// public functions /////// +;================================ mouse.LEFT_BUTTON_FLAG = 0001b mouse.RIGHT_BUTTON_FLAG = 0010b @@ -36,14 +36,10 @@ mouse.WINDOW_RESIZE_SE_FLAG = \ mouse.WINDOW_RESIZE_E_FLAG align 4 -;------------------------------------------------------------------------------ -mouse_check_events: ;////////////////////////////////////////////////////////// -;------------------------------------------------------------------------------ -;? Check if mouse buttons state or cursor position has changed and call -;? appropriate handlers -;------------------------------------------------------------------------------ +;----------------------------------------------------------------- +mouse_check_events: +; Check if mouse buttons state or cursor position has changed push eax ebx - mov al, [BTN_DOWN] mov bl, [mouse.state.buttons] and al, mouse.BUTTONS_MASK @@ -63,8 +59,8 @@ mouse_check_events: ;////////////////////////////////////////////////////////// ; yes it is, activate window user is pointing at, if needed call mouse._.activate_sys_window_under_cursor - ; NOTE: this code wouldn't be necessary if we knew window did - ; already redraw itself after call above +; NOTE: this code wouldn't be necessary if we knew +; that window did already redraw itself after call above or eax, eax jnz .exit @@ -162,19 +158,19 @@ mouse_check_events: ;////////////////////////////////////////////////////////// jnz mouse._.middle_button_press_handler jmp mouse._.middle_button_release_handler -;============================================================================== -;///// private functions ////////////////////////////////////////////////////// -;============================================================================== +;=============================== +;////// private functions ////// +;=============================== uglobal mouse.state: .pos POINT .buttons db ? - ; NOTE: since there's no unique and lifetime-constant button identifiers, - ; we're using two dwords to identify each of them: - ; * pbid - process slot (high 8 bits) and button id (low 24 bits) pack - ; * coord - left (high 16 bits) and top (low 16 bits) coordinates pack +; NOTE: since there's no unique and lifetime-constant button identifiers, +; we are using two dwords to identify each of them: +; * pbid - process slot (high 8 bits) and button id (low 24 bits) pack +; * coord - left (high 16 bits) and top (low 16 bits) coordinates pack align 4 mouse.active_sys_button: .pbid dd ? @@ -191,12 +187,25 @@ uglobal .action db ? endg +iglobal + fl_moving db 0 + rb 3 +endg + align 4 -;------------------------------------------------------------------------------ -mouse._.left_button_press_handler: ;/////////////////////////////////////////// -;------------------------------------------------------------------------------ -;? Called when left mouse button has been pressed down -;------------------------------------------------------------------------------ +;----------------------------------------------------------------- +mouse._.left_button_press_handler: +; Called when left mouse button has been pressed down + bts word [BTN_DOWN], 8 + mov eax, [timer_ticks] + mov ebx, eax + xchg ebx, [mouse.active_sys_window.last_ticks] + sub eax, ebx + movzx ebx, [mouse_doubleclick_delay] + cmp eax, ebx + jg @f + bts dword [BTN_DOWN], 24 +@@: test [mouse.state.buttons], not mouse.LEFT_BUTTON_FLAG jnz .exit @@ -210,12 +219,8 @@ mouse._.left_button_press_handler: ;/////////////////////////////////////////// test dl, mouse.WINDOW_MOVE_FLAG jz @f - mov eax, [timer_ticks] - mov ebx, eax - xchg ebx, [mouse.active_sys_window.last_ticks] - sub eax, ebx - cmp eax, 50 - jg @f + bt dword [BTN_DOWN], 24 + jnc @f mov [mouse.active_sys_window.last_ticks], 0 call sys_window_maximize_handler @@ -254,9 +259,6 @@ mouse._.left_button_press_handler: ;/////////////////////////////////////////// call .calculate_e_delta .call_window_handler: -; mov eax, mouse.active_sys_window.old_box -; call sys_window_start_moving_handler - .exit: ret @@ -287,11 +289,10 @@ mouse._.left_button_press_handler: ;/////////////////////////////////////////// ret align 4 -;------------------------------------------------------------------------------ -mouse._.left_button_release_handler: ;///////////////////////////////////////// -;------------------------------------------------------------------------------ -;? Called when left mouse button has been released -;------------------------------------------------------------------------------ +;----------------------------------------------------------------- +mouse._.left_button_release_handler: +; Called when left mouse button has been released + bts dword [BTN_DOWN], 16 xor esi, esi xchg esi, [mouse.active_sys_window.pslot] or esi, esi @@ -310,60 +311,38 @@ mouse._.left_button_release_handler: ;///////////////////////////////////////// .exit: and [mouse.active_sys_window.action], 0 + mov [fl_moving], 0 ret -align 4 -;------------------------------------------------------------------------------ -mouse._.right_button_press_handler: ;////////////////////////////////////////// -;------------------------------------------------------------------------------ -;? Called when right mouse button has been pressed down -;------------------------------------------------------------------------------ +mouse._.right_button_press_handler: + bts word [BTN_DOWN], 9 test [mouse.state.buttons], not mouse.RIGHT_BUTTON_FLAG - jnz .exit - + jnz @f call mouse._.find_sys_window_under_cursor call mouse._.check_sys_window_actions test al, mouse.WINDOW_MOVE_FLAG - jz .exit + jz @f + jmp sys_window_rollup_handler - call sys_window_rollup_handler +mouse._.right_button_release_handler: + bts dword [BTN_DOWN], 17 +@@: + ret - .exit: +mouse._.middle_button_press_handler: + bts word [BTN_DOWN], 10 + ret + +mouse._.middle_button_release_handler: + bts dword [BTN_DOWN], 18 ret align 4 -;------------------------------------------------------------------------------ -mouse._.right_button_release_handler: ;//////////////////////////////////////// -;------------------------------------------------------------------------------ -;? Called when right mouse button has been released -;------------------------------------------------------------------------------ - ret - -align 4 -;------------------------------------------------------------------------------ -mouse._.middle_button_press_handler: ;///////////////////////////////////////// -;------------------------------------------------------------------------------ -;? Called when middle mouse button has been pressed down -;------------------------------------------------------------------------------ - ret - -align 4 -;------------------------------------------------------------------------------ -mouse._.middle_button_release_handler: ;/////////////////////////////////////// -;------------------------------------------------------------------------------ -;? Called when middle mouse button has been released -;------------------------------------------------------------------------------ - ret - -align 4 -;------------------------------------------------------------------------------ -mouse._.move_handler: ;//////////////////////////////////////////////////////// -;------------------------------------------------------------------------------ -;? Called when cursor has been moved -;------------------------------------------------------------------------------ +;----------------------------------------------------------------- +mouse._.move_handler: +; Called when cursor has been moved ;> eax = old x coord ;> ebx = old y coord -;------------------------------------------------------------------------------ cmp [mouse.active_sys_button.pbid], 0 jnz .exit @@ -507,6 +486,19 @@ mouse._.move_handler: ;//////////////////////////////////////////////////////// pop esi je .exit + test [fl_moving], 1 + jnz @f + + mov [fl_moving], 1 + push edi + mov edi, esi + shl edi, 5 + add edi, WDATA.box + window_data + call window._.draw_negative_box + pop edi + @@: + + mov [mouse.active_sys_window.last_ticks], 0 call sys_window_moving_handler @@ -514,15 +506,12 @@ mouse._.move_handler: ;//////////////////////////////////////////////////////// ret align 4 -;------------------------------------------------------------------------------ -mouse._.find_sys_window_under_cursor: ;//////////////////////////////////////// -;------------------------------------------------------------------------------ -;? Find system window object which is currently visible on screen and has -;? mouse cursor within its bounds -;------------------------------------------------------------------------------ +;----------------------------------------------------------------- +mouse._.find_sys_window_under_cursor: +; Find system window object which is currently visible on screen +; and has mouse cursor within its bounds ;< esi = process slot ;< edi = pointer to WDATA struct -;------------------------------------------------------------------------------ mov esi, [mouse.state.pos.y] mov esi, [d_width_calc_area + esi*4] @@ -535,27 +524,21 @@ mouse._.find_sys_window_under_cursor: ;//////////////////////////////////////// ret align 4 -;------------------------------------------------------------------------------ -mouse._.activate_sys_window_under_cursor: ;//////////////////////////////////// -;------------------------------------------------------------------------------ -;? -;------------------------------------------------------------------------------ - ; activate and redraw window under cursor (if necessary) +;----------------------------------------------------------------- +mouse._.activate_sys_window_under_cursor: +; activate and redraw window under cursor (if necessary) call mouse._.find_sys_window_under_cursor movzx esi, word[WIN_STACK + esi * 2] lea esi, [WIN_POS + esi * 2] jmp waredraw align 4 -;------------------------------------------------------------------------------ -mouse._.find_sys_button_under_cursor: ;//////////////////////////////////////// -;------------------------------------------------------------------------------ -;? Find system button object which is currently visible on screen and has -;? mouse cursor within its bounds -;------------------------------------------------------------------------------ +;----------------------------------------------------------------- +mouse._.find_sys_button_under_cursor: +; Find system button object which is currently visible on screen +; and has mouse cursor within its bounds ;< eax = pack[8(process slot), 24(button id)] or 0 ;< ebx = pack[16(button x coord), 16(button y coord)] -;------------------------------------------------------------------------------ push ecx edx esi edi call mouse._.find_sys_window_under_cursor @@ -612,13 +595,9 @@ mouse._.find_sys_button_under_cursor: ;//////////////////////////////////////// ret align 4 -;------------------------------------------------------------------------------ -mouse._.check_sys_window_actions: ;//////////////////////////////////////////// -;------------------------------------------------------------------------------ -;? -;------------------------------------------------------------------------------ +;----------------------------------------------------------------- +mouse._.check_sys_window_actions: ;< eax = action flags or 0 -;------------------------------------------------------------------------------ ; is window movable? test byte[edi + WDATA.cl_titlebar + 3], 0x01 jnz .no_action @@ -638,8 +617,8 @@ mouse._.check_sys_window_actions: ;//////////////////////////////////////////// ; no there isn't, can it be resized then? mov dl, [edi + WDATA.fl_wstyle] and dl, 0x0f - ; NOTE: dangerous optimization, revise if window types changed; - ; this currently implies only types 2 and 3 could be resized +; NOTE: dangerous optimization, revise if window types changed +; this currently implies only types 2 and 3 could be resized test dl, 2 jz .no_action diff --git a/kernel/branches/Kolibri-acpi/gui/window.inc b/kernel/branches/Kolibri-acpi/gui/window.inc index e2ef758ed5..5e66c57798 100644 --- a/kernel/branches/Kolibri-acpi/gui/window.inc +++ b/kernel/branches/Kolibri-acpi/gui/window.inc @@ -30,11 +30,8 @@ uglobal draw_limits RECT endg -align 4 ;------------------------------------------------------------------------------ syscall_draw_window: ;///// system function 0 ///////////////////////////////// -;------------------------------------------------------------------------------ -;? . ;------------------------------------------------------------------------------ mov eax, edx shr eax, 24 @@ -49,34 +46,28 @@ syscall_draw_window: ;///// system function 0 ///////////////////////////////// or al, al jnz @f - ; type I - original style +; type I - original style call drawwindow_I jmp window._.draw_window_caption.2 ;-------------------------------------- -align 4 @@: dec al jnz @f - ; type II - only reserve area, no draw -; call sys_window_mouse -; call [draw_pointer] +; type II - only reserve area, no draw call __sys_draw_pointer jmp .exit ;-------------------------------------- -align 4 @@: dec al jnz @f - ; type III - new style +; type III - new style call drawwindow_III jmp window._.draw_window_caption.2 - - ; type IV & V - skinned window (resizable & not) ;-------------------------------------- -align 4 @@: +; type IV & V - skinned window (resizable & not) mov eax, [TASK_COUNT] movzx eax, word[WIN_POS + eax * 2] cmp eax, [CURRENT_TASK] @@ -86,12 +77,9 @@ align 4 call drawwindow_IV jmp window._.draw_window_caption.2 ;-------------------------------------- -align 4 .exit: ret ;------------------------------------------------------------------------------ -align 4 -;------------------------------------------------------------------------------ syscall_display_settings: ;///// system function 48 /////////////////////////// ;------------------------------------------------------------------------------ ;; Redraw screen: @@ -134,74 +122,73 @@ syscall_display_settings: ;///// system function 48 /////////////////////////// ;< ebx = 8 ;< ecx = pointer to FileInfoBlock struct ;> eax = FS error code +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +;; Get font smoothing: +;< ebx = 9 +;> eax = 0 — off, 1 — on, 2 — subpixel +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +;; Set font smoothing: +;< ebx = 10 +;< ecx = 0 — off, 1 — on, 2 — subpixel +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +;; Get font size: +;< ebx = 11 +;> eax = height in pixels +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +;; Set font size: +;< ebx = 12 +;< ecx = height in pixels ;------------------------------------------------------------------------------ cmp ebx, .sizeof.ftable / 4 ja @f jmp [.ftable + ebx * 4] -;-------------------------------------- -align 4 -@@: - ret ;------------------------------------------------------------------------------ -align 4 syscall_display_settings.00: xor eax, eax inc ebx cmp [windowtypechanged], ebx - jne .exit + jne @f mov [windowtypechanged], eax - jmp syscall_display_settings._.redraw_whole_screen -;-------------------------------------- -align 4 -.exit: - ret ;------------------------------------------------------------------------------ -align 4 syscall_display_settings.01: and ecx, 1 cmp ecx, [buttontype] - je .exit + je @f mov [buttontype], ecx mov [windowtypechanged], ebx -;-------------------------------------- -align 4 - .exit: +@@: ret ;------------------------------------------------------------------------------ -align 4 syscall_display_settings.02: dec ebx mov esi, ecx cmp edx, 192 jnae @f mov edx, 192 ; max size - @@: +@@: mov edi, common_colours mov ecx, edx rep movsb mov [windowtypechanged], ebx ret ;------------------------------------------------------------------------------ -align 4 syscall_display_settings.03: mov edi, ecx cmp edx, 192 jnae @f mov edx, 192 ; max size - @@: +@@: mov esi, common_colours mov ecx, edx rep movsb ret ;------------------------------------------------------------------------------ -align 4 syscall_display_settings.04: mov eax, [_skinh] mov [esp + 32], eax ret ;------------------------------------------------------------------------------ -align 4 syscall_display_settings.05: mov eax, [screen_workarea.left - 2] mov ax, word[screen_workarea.right] @@ -211,10 +198,8 @@ syscall_display_settings.05: mov [esp + 20], eax ret ;------------------------------------------------------------------------------ -align 4 syscall_display_settings.06: xor esi, esi - mov edi, [_display.width] dec edi mov eax, ecx @@ -226,19 +211,13 @@ syscall_display_settings.06: or eax, eax jge @f xor eax, eax -;-------------------------------------- -align 4 @@: mov [screen_workarea.left], eax cmp ebx, edi jle @f mov ebx, edi -;-------------------------------------- -align 4 @@: mov [screen_workarea.right], ebx -;-------------------------------------- -align 4 .check_horizontal: mov edi, [_display.height] dec edi @@ -251,54 +230,58 @@ align 4 or eax, eax jge @f xor eax, eax -;-------------------------------------- -align 4 @@: mov [screen_workarea.top], eax cmp ebx, edi jle @f mov ebx, edi -;-------------------------------------- -align 4 @@: mov [screen_workarea.bottom], ebx -;-------------------------------------- -align 4 .check_if_redraw_needed: or esi, esi - jz .exit + jz @f call repos_windows jmp syscall_display_settings._.calculate_whole_screen -;-------------------------------------- -align 4 -.exit: - ret ;------------------------------------------------------------------------------ -align 4 syscall_display_settings.07: mov eax, [_skinmargins + 0] mov [esp + 32], eax mov eax, [_skinmargins + 4] mov [esp + 20], eax +@@: ret ;------------------------------------------------------------------------------ -align 4 syscall_display_settings.08: mov ebx, ecx call read_skin_file mov [esp + 32], eax test eax, eax - jnz .exit + jnz @b call syscall_display_settings._.calculate_whole_screen jmp syscall_display_settings._.redraw_whole_screen -;-------------------------------------- -align 4 -.exit: +;------------------------------------------------------------------------------ +syscall_display_settings.09: + xor eax, eax + mov al, [fontSmoothing] + mov [esp + 32], eax + ret +;------------------------------------------------------------------------------ +syscall_display_settings.10: + mov [fontSmoothing], cl + ret +;------------------------------------------------------------------------------ +syscall_display_settings.11: + xor eax, eax + mov al, [fontSize] + mov [esp + 32], eax + ret +;------------------------------------------------------------------------------ +syscall_display_settings.12: + mov [fontSize], cl ret ;------------------------------------------------------------------------------ -align 4 syscall_display_settings._.calculate_whole_screen: xor eax, eax xor ebx, ebx @@ -308,7 +291,6 @@ syscall_display_settings._.calculate_whole_screen: dec edx jmp calculatescreen ;------------------------------------------------------------------------------ -align 4 syscall_display_settings._.redraw_whole_screen: xor eax, eax mov [draw_limits.left], eax @@ -322,8 +304,6 @@ syscall_display_settings._.redraw_whole_screen: mov eax, window_data jmp redrawscreen ;------------------------------------------------------------------------------ -align 4 -;------------------------------------------------------------------------------ syscall_set_window_shape: ;///// system function 50 /////////////////////////// ;------------------------------------------------------------------------------ ;; Set window shape address: @@ -406,58 +386,19 @@ align 4 call window._.set_window_box add esp, sizeof.BOX - ; NOTE: do we really need this? to be reworked -; mov byte[DONT_DRAW_MOUSE], 0 ; mouse pointer -; mov byte[MOUSE_BACKGROUND], 0 ; no mouse under -; mov byte[MOUSE_DOWN], 0 ; react to mouse up/down - - ; NOTE: do we really need this? to be reworked -; call [draw_pointer] -;-------------------------------------- -align 4 .exit: ret ;------------------------------------------------------------------------------ -align 4 +syscall_window_settings: ;///// system function 71 //////////////////////////// ;------------------------------------------------------------------------------ -syscall_window_settings: ;///// system function 71 ///////////////////////////// -;------------------------------------------------------------------------------ -;? -;------------------------------------------------------------------------------ - dec ebx ; subfunction #1 - set window caption - jnz .exit_fail - - ; NOTE: only window owner thread can set its caption, - ; so there's no parameter for PID/TID - mov edi, [CURRENT_TASK] shl edi, 5 - mov [edi * 8 + SLOT_BASE + APPDATA.wnd_caption], ecx or [edi + window_data + WDATA.fl_wstyle], WSTYLE_HASCAPTION - - call window._.draw_window_caption - - xor eax, eax ; eax = 0 (success) - ret - -; .get_window_caption: -; dec eax ; subfunction #2 - get window caption -; jnz .exit_fail - - ; not implemented yet -;-------------------------------------- -align 4 -.exit_fail: - xor eax, eax - inc eax ; eax = 1 (fail) - ret + jmp window._.draw_window_caption ;------------------------------------------------------------------------------ align 4 -;------------------------------------------------------------------------------ set_window_defaults: ;///////////////////////////////////////////////////////// -;------------------------------------------------------------------------------ -;? ;------------------------------------------------------------------------------ mov byte [window_data + 0x20 + WDATA.cl_titlebar + 3], 1 ; desktop is not movable push eax ecx @@ -477,6 +418,7 @@ align 4 pop ecx eax ret ;------------------------------------------------------------------------------ + align 4 ;------------------------------------------------------------------------------ calculatescreen: ;///////////////////////////////////////////////////////////// @@ -502,12 +444,21 @@ calculatescreen: ;///////////////////////////////////////////////////////////// cmp ebp, 1 jbe .exit + push eax ;for num layout + push edx ecx ebx eax + + mov dword[esp+10h], ZPOS_DESKTOP +;-------------------------------------- +align 4 +.layout: + mov esi, 1 ; = num in window stack + mov ebp, [TASK_COUNT] ;-------------------------------------- align 4 .next_window: movzx edi, word[WIN_POS + esi * 2] - shl edi, 5 + shl edi, 5 ;size of TASKDATA and WDATA = 32 bytes cmp [CURRENT_TASK + edi + TASKDATA.state], TSTATE_FREE je .skip_window @@ -516,6 +467,10 @@ align 4 test [edi + WDATA.fl_wstate], WSTATE_MINIMIZED jnz .skip_window + mov eax, [esp+10h] + cmp [edi + WDATA.z_modif], al + jne .skip_window + mov eax, [edi + WDATA.box.left] cmp eax, [esp + RECT.right] jg .skip_window @@ -565,8 +520,18 @@ align 4 inc esi dec ebp jnz .next_window +;--------------------------------------------- + inc dword[esp+10h] + cmp dword[esp+10h], ZPOS_ALWAYS_TOP + jle .layout +;--------------------------------------------- + mov esi, [TASK_COUNT] + movzx edi, word[WIN_POS + esi * 2] + shl edi, 5 + add edi, window_data pop eax ebx ecx edx + pop ebp ;del num layout ;-------------------------------------- align 4 .exit: @@ -1019,6 +984,9 @@ waredraw: ;//////////////////////////////////////////////////////////////////// mov edi, [TASK_COUNT] movzx esi, word[WIN_POS + edi * 2] call window._.set_screen + + call window._.set_top_wnd + inc [_display.mask_seqno] popad @@ -1188,6 +1156,11 @@ align 4 add ecx, eax add edx, ebx call ebp + + cmp ebp, window._.set_screen + jne @f + call window._.set_top_wnd + @@: inc [_display.mask_seqno] ;-------------------------------------- align 4 @@ -1374,6 +1347,15 @@ sys_window_end_moving_handler: ;/////////////////////////////////////////////// shl edi, 5 add edi, window_data + test [fl_moving], 1 + jz @f + + push edi + mov edi, ebx + call window._.draw_negative_box + pop edi + @@: + mov eax, ebx mov bl, [edi + WDATA.fl_wstate] call window._.set_window_box @@ -1400,7 +1382,7 @@ sys_window_moving_handler: ;/////////////////////////////////////////////////// iglobal FuncTable syscall_display_settings, ftable, \ - 00, 01, 02, 03, 04, 05, 06, 07, 08 + 00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12 align 4 window_topleft dd \ @@ -1511,7 +1493,6 @@ end if call memmove mov eax, ebx mov ebx, esi - call window._.check_window_position call window._.set_window_clientbox call window._.invalidate_screen @@ -1618,30 +1599,21 @@ window._.sys_set_window: ;///////////////////////////////////////////////////// mov eax, [CURRENT_TASK] shl eax, 5 add eax, window_data - - ; save window colors +; save window colors mov [eax + WDATA.cl_workarea], edx mov [eax + WDATA.cl_titlebar], esi mov [eax + WDATA.cl_frames], edi - mov edi, eax - - ; was it already defined before? +; Was it already defined before? test [edi + WDATA.fl_wdrawn], 1 jnz .set_client_box - or [edi + WDATA.fl_wdrawn], 1 -; After first draw_window we need redraw mouse necessarily! +; No, it wasn't. After first draw_window we need redraw mouse necessarily! ; Otherwise the user can see cursor specified by f.37.5 from another window. -; He will be really unhappy! He is terrible in rage - usually he throws stones! +; He will be really unhappy! Usually, he will be enraged! + or [edi + WDATA.fl_wdrawn], 1 mov [redrawmouse_unconditional], 1 call wakeup_osloop - ; NOTE: commented out since doesn't provide necessary functionality - ; anyway, to be reworked -; mov eax, [timer_ticks] ; [0xfdf0] -; add eax, 100 -; mov [new_window_starting], eax - - ; no it wasn't, performing initial window definition +; performing initial window definition movzx eax, bx mov [edi + WDATA.box.width], eax movzx eax, cx @@ -2296,6 +2268,8 @@ align 4 or edx, edx jz .exit + mov ebp, [edi + window_data + WDATA.box.left - 2] + mov bp, word[edi + window_data + WDATA.box.top] movzx eax, [edi + window_data + WDATA.fl_wstyle] and al, 0x0F cmp al, 3 @@ -2307,66 +2281,46 @@ align 4 ;-------------------------------------- align 4 .skinned: - mov ebp, [edi + window_data + WDATA.box.left - 2] - mov bp, word[edi + window_data + WDATA.box.top] movzx eax, word[edi + window_data + WDATA.box.width] sub ax, [_skinmargins.left] sub ax, [_skinmargins.right] - push edx - cwde - cdq - mov ebx, 6 - idiv ebx - pop edx - or eax, eax js .exit - - mov esi, eax mov ebx, dword[_skinmargins.left - 2] mov bx, word[_skinh] sub bx, [_skinmargins.bottom] sub bx, [_skinmargins.top] sar bx, 1 - adc bx, 0 add bx, [_skinmargins.top] - add bx, -3 - add ebx, ebp + sub bx, 8 jmp .dodraw ;-------------------------------------- align 4 .not_skinned: cmp al, 1 je .exit - - mov ebp, [edi + window_data + WDATA.box.left - 2] - mov bp, word[edi + window_data + WDATA.box.top] movzx eax, word[edi + window_data + WDATA.box.width] sub eax, 16 - push edx - cwde - cdq - mov ebx, 6 - idiv ebx - pop edx - or eax, eax js .exit - - mov esi, eax - mov ebx, 0x00080007 - add ebx, ebp -;-------------------------------------- -align 4 + mov ebx, 80002h .dodraw: + shr eax, 3 + mov esi, eax + add ebx, ebp mov ecx, [common_colours + 16] - or ecx, 0x80000000 + mov al, 1 + cmp byte [edx], 4 + jnc @f + mov al, [edx] + test al, al + jz .exit + inc edx +@@: + shl eax, 28 + or ecx, eax xor edi, edi - call dtext_asciiz_esi -;-------------------------------------- -align 4 + call dtext .exit: -; call [draw_pointer] - call __sys_draw_pointer - ret + jmp __sys_draw_pointer ;------------------------------------------------------------------------------ align 4 ;------------------------------------------------------------------------------ @@ -2426,3 +2380,153 @@ window._.get_rect: ;///////////////////////////////////////////////////// mov [ecx+RECT.bottom], edx ret ;------------------------------------------------------------------------------ +align 4 +;------------------------------------------------------------------------------ +window._.redraw_top_wnd: ;//////////////////////////////////////////////////////// +;------------------------------------------------------------------------------ +;? redraw all windows one above the window +;------------------------------------------------------------------------------ +;> eax = left +;> ebx = top +;> ecx = right +;> edx = bottom +;> esi = process number +;! corrupted edi +;------------------------------------------------------------------------------ + push 0 + jmp window._.set_top_wnd.go + +align 4 +;------------------------------------------------------------------------------ +window._.set_top_wnd: ;//////////////////////////////////////////////////////// +;------------------------------------------------------------------------------ +;? call set_screen for all windows one above the window +;------------------------------------------------------------------------------ +;> eax = left +;> ebx = top +;> ecx = right +;> edx = bottom +;> esi = process number +;! corrupted edi +;------------------------------------------------------------------------------ + + push 1 +.go: + push esi + pushfd + cli + + push ebp + mov ebp, [TASK_COUNT] + cmp ebp, 1 + jbe .exit + + shl esi, 5 + cmp [esi + window_data + WDATA.z_modif], ZPOS_ALWAYS_TOP + je .exit + + push eax ;for num layout + push edx ecx ebx eax + + movsx eax, byte [esi + window_data + WDATA.z_modif] + inc eax + mov dword[esp+10h], eax +;-------------------------------------- +align 4 +.layout: + mov esi, 1 ; = num in window stack + mov ebp, [TASK_COUNT] +;-------------------------------------- +align 4 +.next_window: + movzx edi, word[WIN_POS + esi * 2] + shl edi, 5 ;size of TASKDATA and WDATA = 32 bytes + + cmp [CURRENT_TASK + edi + TASKDATA.state], TSTATE_FREE + je .skip_window + + add edi, window_data + test [edi + WDATA.fl_wstate], WSTATE_MINIMIZED + jnz .skip_window + + mov eax, [esp+10h] + cmp [edi + WDATA.z_modif], al + jne .skip_window + + mov eax, [edi + WDATA.box.left] + cmp eax, [esp + RECT.right] + jg .skip_window + mov ebx, [edi + WDATA.box.top] + cmp ebx, [esp + RECT.bottom] + jg .skip_window + mov ecx, [edi + WDATA.box.width] + add ecx, eax + cmp ecx, [esp + RECT.left] + jl .skip_window + mov edx, [edi + WDATA.box.height] + add edx, ebx + cmp edx, [esp + RECT.top] + jl .skip_window + + cmp eax, [esp + RECT.left] + jae @f + mov eax, [esp + RECT.left] +;-------------------------------------- +align 4 +@@: + cmp ebx, [esp + RECT.top] + jae @f + mov ebx, [esp + RECT.top] +;-------------------------------------- +align 4 +@@: + cmp ecx, [esp + RECT.right] + jbe @f + mov ecx, [esp + RECT.right] +;-------------------------------------- +align 4 +@@: + cmp edx, [esp + RECT.bottom] + jbe @f + mov edx, [esp + RECT.bottom] +;-------------------------------------- +align 4 +@@: + cmp dword[esp+32], 0 + je .set_fl_redraw + + push esi + movzx esi, word[WIN_POS + esi * 2] + call window._.set_screen + pop esi + jmp @f +.set_fl_redraw: + mov [edi + WDATA.fl_redraw], 1 ;set redraw flag + @@: +;-------------------------------------- +align 4 +.skip_window: + inc esi + dec ebp + jnz .next_window +;-------------------------------------- + inc dword[esp+10h] + cmp byte[esp+10h], ZPOS_ALWAYS_TOP + jle .layout +;------------------------------------- + + pop eax ebx ecx edx + pop ebp ;del num layout +;------------------------------------- +align 4 +.exit: + + pop ebp + popfd + pop esi + + add esp, 4 ;dword for 0/1 - set_screen/fl_redraw + ret + + + diff --git a/kernel/branches/Kolibri-acpi/hid/keyboard.inc b/kernel/branches/Kolibri-acpi/hid/keyboard.inc index a2751f9c22..f5528a9598 100644 --- a/kernel/branches/Kolibri-acpi/hid/keyboard.inc +++ b/kernel/branches/Kolibri-acpi/hid/keyboard.inc @@ -25,6 +25,8 @@ VKEY_CONTROL = 0000000000001100b VKEY_ALT = 0000000000110000b uglobal + align 4 + kb_state dd 0 ext_code db 0 keyboard_mode db 0 @@ -33,6 +35,7 @@ uglobal altmouseb db 0 ctrl_alt_del db 0 + kb_lights db 0 old_kb_lights db 0 align 4 @@ -42,13 +45,6 @@ align 4 endg iglobal - kb_lights db 2 - align 4 - kb_state dd VKEY_NUMLOCK -endg - -iglobal -align 4 hotkey_tests dd hotkey_test0 dd hotkey_test1 dd hotkey_test2 diff --git a/kernel/branches/Kolibri-acpi/hid/mousedrv.inc b/kernel/branches/Kolibri-acpi/hid/mousedrv.inc index 2b30b2bbd1..5dda193d88 100644 --- a/kernel/branches/Kolibri-acpi/hid/mousedrv.inc +++ b/kernel/branches/Kolibri-acpi/hid/mousedrv.inc @@ -35,10 +35,9 @@ endg iglobal ;-------------------------------------- align 4 -mouse_delay dd 10 -mouse_speed_factor: - dd 3 -mouse_timer_ticks dd 0 +mouse_speed_factor dw 1 +mouse_delay db 1 +mouse_doubleclick_delay db 64 endg ;----------------------------------------------------------------------------- @@ -490,11 +489,12 @@ proc set_mouse_data stdcall uses edx, BtnState:dword, XMoving:dword, YMoving:dwo mov eax, [XMoving] test [BtnState], 0x80000000 jnz .absolute_x + test eax, eax + jz @f call mouse_acceleration add ax, [MOUSE_X] - cmp ax, 0 - jge .check_x - mov eax, 0 + jns .check_x + xor eax, eax jmp .set_x .absolute_x: mov edx, [_display.width] @@ -508,15 +508,17 @@ proc set_mouse_data stdcall uses edx, BtnState:dword, XMoving:dword, YMoving:dwo .set_x: mov [MOUSE_X], ax ;-------------------------------------- +@@: mov eax, [YMoving] test [BtnState], 0x40000000 jnz .absolute_y + test eax, eax + jz @f neg eax call mouse_acceleration add ax, [MOUSE_Y] - cmp ax, 0 - jge .check_y - mov ax, 0 + jns .check_y + xor eax, eax jmp .set_y .absolute_y: mov edx, [_display.height] @@ -530,31 +532,54 @@ proc set_mouse_data stdcall uses edx, BtnState:dword, XMoving:dword, YMoving:dwo .set_y: mov [MOUSE_Y], ax ;-------------------------------------- +@@: mov eax, [VScroll] + test eax, eax + jz @f add [MOUSE_SCROLL_V], ax - + bts word [BTN_DOWN], 15 +@@: mov eax, [HScroll] + test eax, eax + jz @f add [MOUSE_SCROLL_H], ax - + bts dword [BTN_DOWN], 23 +@@: mov [mouse_active], 1 - mov eax, [timer_ticks] - mov [mouse_timer_ticks], eax call wakeup_osloop ret endp ;----------------------------------------------------------------------------- - +; 3 = x^2 /2 +; 2 = (x+1)^2 /4 +; 1 = (x+2)^2 /8 align 4 mouse_acceleration: + cmp [mouse_delay], 0 + jz .end push eax - mov eax, [timer_ticks] - sub eax, [mouse_timer_ticks] - cmp eax, [mouse_delay] - pop eax - ja @f - ;push edx - imul eax, [mouse_speed_factor] - ;pop edx - @@: +@@: + neg eax + jl @b + cmp [mouse_delay], 3 + adc eax, 0 + cmp [mouse_delay], 2 + adc eax, 0 + mul al + shr eax, 1 + adc eax, 0 + cmp [mouse_delay], 2 + jz .2 + jnc .3 + shr eax, 1 +.2: + shr eax, 1 +.3: + pop edx + test edx, edx + jns .end + neg eax +.end: + imul [mouse_speed_factor] ret diff --git a/kernel/branches/Kolibri-acpi/init.inc b/kernel/branches/Kolibri-acpi/init.inc index 9e4a2ff1ba..dac14ff9b3 100644 --- a/kernel/branches/Kolibri-acpi/init.inc +++ b/kernel/branches/Kolibri-acpi/init.inc @@ -439,7 +439,7 @@ acpi_hpet_base rd 1 hpet_base rd 1 hpet_period rd 1 hpet_timers rd 1 - +hpet_tsc_start rd 2 cpu_count rd 1 smpt rd 16 endg @@ -599,39 +599,62 @@ check_acpi: mov [acpi_ioapic_base-OS_BASE], eax jmp .next -HPET_PERIOD equ 0x004 -HPET_CFG_ENABLE equ 1 -HPET_CFG equ 0x010 +HPET_PERIOD equ 0x0004 +HPET_CFG_ENABLE equ 0x0001 +HPET_CFG equ 0x0010 +HPET_COUNTER equ 0x00f0 +HPET_T0_CFG equ 0x0100 + +HPET_TN_LEVEL equ 0x0002 +HPET_TN_ENABLE equ 0x0004 +HPET_TN_FSB equ 0x4000 align 4 init_hpet: mov ebx, [hpet_base-OS_BASE] test ebx, ebx - jz @F + jz .done mov eax, [ebx] and ah, 0x1F inc ah movzx eax, ah mov [hpet_timers-OS_BASE], eax + mov ecx, eax mov eax, [ebx+HPET_PERIOD] - mov edx, 0x431BDE83 - mul edx - shr edx, 18 - mov [hpet_period-OS_BASE], edx + xor edx, edx + shld edx, eax, 10 + shl eax, 10 + mov esi, 1000000 + div esi + mov [hpet_period-OS_BASE], eax - mov eax, [ebx+HPET_CFG] - and eax, not HPET_CFG_ENABLE - mov [ebx+HPET_CFG], eax ;stop main counter + mov esi, [ebx+HPET_CFG] + and esi, not HPET_CFG_ENABLE + mov [ebx+HPET_CFG], esi ;stop main counter - xor ecx, ecx - mov [ebx+0xF0], ecx ;reset counter - mov [ebx+0xF4], ecx - - or eax, HPET_CFG_ENABLE - mov [ebx+HPET_CFG], eax ;and start again + lea edx, [ebx+HPET_T0_CFG] @@: + jcxz @F + mov eax, [edx] + and eax, not (HPET_TN_ENABLE+HPET_TN_LEVEL+HPET_TN_FSB) + mov [edx], eax + add edx, 0x20 + dec ecx + jmp @B +@@: + mov [ebx+HPET_COUNTER], ecx ;reset main counter + mov [ebx+HPET_COUNTER+4], ecx + + or esi, HPET_CFG_ENABLE + mov [ebx+HPET_CFG], esi ;and start again + +.done: + rdtsc + mov [hpet_tsc_start-OS_BASE], eax + mov [hpet_tsc_start+4-OS_BASE], edx + ret diff --git a/kernel/branches/Kolibri-acpi/kernel.asm b/kernel/branches/Kolibri-acpi/kernel.asm index c9177b3857..f7cdfc94a0 100644 --- a/kernel/branches/Kolibri-acpi/kernel.asm +++ b/kernel/branches/Kolibri-acpi/kernel.asm @@ -701,19 +701,11 @@ setvideomode: mov eax, [hpet_base] test eax, eax jz @F - DEBUGF 1, "K : HPET base %x\n", eax - mov eax, [hpet_period] - DEBUGF 1, "K : HPET period %d\n", eax - mov eax, [hpet_timers] - DEBUGF 1, "K : HPET timers %d\n", eax - mov eax, [hpet_base] stdcall map_io_mem, [hpet_base], 1024, PG_GLOBAL+PAT_UC+PG_SWR mov [hpet_base], eax - mov eax, [eax] DEBUGF 1, "K : HPET caps %x\n", eax - @@: ; SET UP OS TASK @@ -1041,7 +1033,31 @@ include "detect/vortex86.inc" ; Vortex86 SoC detection code mov esi, boot_cpufreq call boot_log - cli ;FIXME check IF + cli + mov ebx, [hpet_base] + test ebx, ebx + jz @F + mov ebx, [ebx+0xF0] + + rdtsc + mov ecx, 1000 + sub eax, [hpet_tsc_start] + sbb edx, [hpet_tsc_start+4] + shld edx, eax, 10 + shl eax, 10 + mov esi, eax + mov eax, edx + mul ecx + xchg eax, esi + mul ecx + adc edx, esi + div ebx + mul ecx + div [hpet_period] + mul ecx + DEBUGF 1, "K : cpu frequency %u Hz\n", eax + jmp .next +@@: rdtsc mov ecx, eax mov esi, 250 ; wait 1/4 a second @@ -1053,6 +1069,7 @@ include "detect/vortex86.inc" ; Vortex86 SoC detection code xor edx, edx shld edx, eax, 2 shl eax, 2 +.next: mov dword [cpu_freq], eax mov dword [cpu_freq+4], edx mov ebx, 1000000 @@ -1103,7 +1120,7 @@ include "detect/vortex86.inc" ; Vortex86 SoC detection code call load_default_skin -;protect io permission map +; Protect I/O permission map mov esi, [default_io_map] stdcall map_page, esi, [SLOT_BASE+256+APPDATA.io_map], PG_READ @@ -1905,8 +1922,18 @@ sys_getsetup: ret ;-------------------------------------- @@: +; F.26.10 - get the time from kernel launch in nanoseconds + sub ebx, 1 + jnz @f + + call get_clock_ns + mov [esp+24], edx + mov [esp+32], eax + ret +;-------------------------------------- +@@: ; F.26.11 - Find out whether low-level HD access is enabled - sub ebx, 2 + sub ebx, 1 jnz @f mov eax, [lba_read_enabled] @@ -1932,7 +1959,10 @@ get_timer_ticks: ;----------------------------------------------------------------------------- iglobal align 4 -mousefn dd msscreen, mswin, msbutton, msset +mousefn dd msscreen + dd mswin + dd msbutton + dd msbuttonExt dd app_load_cursor dd app_set_cursor dd app_delete_cursor @@ -1944,21 +1974,24 @@ readmousepos: ; eax=0 screen relative ; eax=1 window relative ; eax=2 buttons pressed -; eax=3 set mouse pos ; reserved +; eax=3 buttons pressed ext ; eax=4 load cursor ; eax=5 set cursor -; eax=6 delete cursor ; reserved +; eax=6 delete cursor ; eax=7 get mouse_z cmp ebx, 7 - ja msset + ja @f jmp [mousefn+ebx*4] + msscreen: mov eax, [MOUSE_X] shl eax, 16 mov ax, [MOUSE_Y] mov [esp+36-4], eax +@@: ret + mswin: mov eax, [MOUSE_X] shl eax, 16 @@ -1968,7 +2001,6 @@ mswin: shl ebx, 16 mov bx, word [esi-twdw+WDATA.box.top] sub eax, ebx - mov edi, [CURRENT_TASK] shl edi, 8 sub ax, word[edi+SLOT_BASE+APPDATA.wnd_clientbox.top] @@ -1977,10 +2009,35 @@ mswin: rol eax, 16 mov [esp+36-4], eax ret + msbutton: movzx eax, byte [BTN_DOWN] mov [esp+36-4], eax ret + +msbuttonExt: + mov eax, [BTN_DOWN] + mov [esp+36-4], eax + ret + +app_load_cursor: + cmp ecx, OS_BASE + jae @f + stdcall load_cursor, ecx, edx + mov [esp+36-4], eax +@@: + ret + +app_set_cursor: + stdcall set_cursor, ecx + mov [esp+36-4], eax + ret + +app_delete_cursor: + stdcall delete_cursor, ecx + mov [esp+36-4], eax + ret + msz: mov edi, [TASK_COUNT] movzx edi, word [WIN_POS + edi*2] @@ -1993,27 +2050,8 @@ msz: and [MOUSE_SCROLL_H], word 0 and [MOUSE_SCROLL_V], word 0 ret - @@: +@@: and [esp+36-4], dword 0 -; ret -msset: - ret - -app_load_cursor: - cmp ecx, OS_BASE - jae msset - stdcall load_cursor, ecx, edx - mov [esp+36-4], eax - ret - -app_set_cursor: - stdcall set_cursor, ecx - mov [esp+36-4], eax - ret - -app_delete_cursor: - stdcall delete_cursor, ecx - mov [esp+36-4], eax ret is_input: @@ -2204,6 +2242,8 @@ sys_system_table: dd sysfn_min_rest_window ; 22 = minimize and restore any window dd sysfn_min_windows ; 23 = minimize all windows dd sysfn_set_screen_sizes ; 24 = set screen sizes for Vesa + + dd sysfn_zmodif ; 25 = get/set window z modifier ;Fantomer sysfn_num = ($ - sys_system_table)/4 endg ;------------------------------------------------------------------------------ @@ -2363,6 +2403,72 @@ sysfn_activate: ; 18.3 = ACTIVATE WINDOW .nowindowactivate: ret ;------------------------------------------------------------------------------ +align 4 +sysfn_zmodif: +;18,25,1 - get z_modif +;18,25,2 - set z_modif +;edx = -1(for current task) or TID +;esi(for 2) = new value z_modif +;return: +;1: eax = z_modif +;2: eax=0(fail),1(success) for set z_modif + + cmp edx, -1 + jne @f + mov edx, [CURRENT_TASK] + @@: + cmp edx, [TASK_COUNT] + ja .fail + cmp edx, 1 + je .fail + + mov eax, edx + shl edx, 5 + + cmp [edx + CURRENT_TASK + TASKDATA.state], 9 + je .fail + + cmp ecx, 1 + jnz .set_zmod + + mov al, [edx + window_data + WDATA.z_modif] + jmp .exit + +.set_zmod: + cmp ecx, 2 + jnz .fail + + mov ebx, esi + mov esi, eax + + cmp bl, ZPOS_ALWAYS_TOP + jg .fail + + mov [edx + window_data + WDATA.z_modif], bl + + mov eax, [edx + window_data + WDATA.box.left] + mov ebx, [edx + window_data + WDATA.box.top] + mov ecx, [edx + window_data + WDATA.box.width] + mov edx, [edx + window_data + WDATA.box.height] + add ecx, eax + add edx, ebx + call window._.set_screen + call window._.set_top_wnd + call window._.redraw_top_wnd + + shl esi, 5 + mov [esi + window_data + WDATA.fl_redraw], 1 + + + mov eax, 1 + jmp .exit +.fail: + xor eax, eax +.exit: + mov [esp+32], eax + ret + +;------------------------------------------------------------------------------ sysfn_getidletime: ; 18.4 = GET IDLETIME mov eax, [CURRENT_TASK+32+TASKDATA.cpu_usage] mov [esp+32], eax @@ -2446,11 +2552,6 @@ sysfn_waitretrace: ; 18.14 = sys wait retrace ;------------------------------------------------------------------------------ align 4 sysfn_centermouse: ; 18.15 = mouse centered -; removed here by -; call mouse_centered -;* mouse centered - start code- Mario79 -;mouse_centered: -; push eax mov eax, [_display.width] shr eax, 1 mov [MOUSE_X], ax @@ -2458,62 +2559,62 @@ sysfn_centermouse: ; 18.15 = mouse centered shr eax, 1 mov [MOUSE_Y], ax call wakeup_osloop -; ret -;* mouse centered - end code- Mario79 xor eax, eax and [esp+32], eax -; pop eax ret ;------------------------------------------------------------------------------ -align 4 -sysfn_mouse_acceleration: ; 18.19 = set/get mouse features - test ecx, ecx; get mouse speed factor - jnz .set_mouse_acceleration +sysfn_mouse_acceleration: ; 18.19 = set/get mouse features + cmp ecx, 8 + jnc @f + jmp dword [.table+ecx*4] +.get_mouse_acceleration: xor eax, eax mov ax, [mouse_speed_factor] mov [esp+32], eax ret - .set_mouse_acceleration: -; cmp ecx,1 ; set mouse speed factor - dec ecx - jnz .get_mouse_delay +.set_mouse_acceleration: mov [mouse_speed_factor], dx ret - .get_mouse_delay: -; cmp ecx,2 ; get mouse delay - dec ecx - jnz .set_mouse_delay - mov eax, [mouse_delay] +.get_mouse_delay: + xor eax, eax + mov al, [mouse_delay] mov [esp+32], eax ret - .set_mouse_delay: -; cmp ecx,3 ; set mouse delay - dec ecx - jnz .set_pointer_position - mov [mouse_delay], edx +.set_mouse_delay: + mov [mouse_delay], dl +@@: ret - .set_pointer_position: -; cmp ecx,4 ; set mouse pointer position - dec ecx - jnz .set_mouse_button +.set_pointer_position: cmp dx, word[_display.height] - jae .end + jae @b rol edx, 16 cmp dx, word[_display.width] - jae .end + jae @b mov [MOUSE_X], edx mov [mouse_active], 1 - call wakeup_osloop - ret - .set_mouse_button: -; cmp ecx,5 ; set mouse button features - dec ecx - jnz .end - mov [BTN_DOWN], dl + jmp wakeup_osloop +.set_mouse_button: + mov [BTN_DOWN], edx mov [mouse_active], 1 - call wakeup_osloop - .end: + jmp wakeup_osloop +.get_doubleclick_delay: + xor eax, eax + mov al, [mouse_doubleclick_delay] + mov [esp+32], eax ret +.set_doubleclick_delay: + mov [mouse_doubleclick_delay], dl + ret +align 4 +.table: +dd .get_mouse_acceleration +dd .set_mouse_acceleration +dd .get_mouse_delay +dd .set_mouse_delay +dd .set_pointer_position +dd .set_mouse_button +dd .get_doubleclick_delay +dd .set_doubleclick_delay ;------------------------------------------------------------------------------ sysfn_getfreemem: mov eax, [pg_data.pages_free] @@ -3740,6 +3841,14 @@ newdw2: cmp ecx, 1 ; limit for background jz bgli + mov eax, [esp+4] ;if upper in z-position - no redraw + test eax, eax + jz @f + mov al, [eax + WDATA.z_modif] + cmp [edi + WDATA.z_modif], al + jg ricino + @@: + mov eax, [edi + WDATA.box.left] mov ebx, [edi + WDATA.box.top] diff --git a/kernel/branches/Kolibri-acpi/kernel32.inc b/kernel/branches/Kolibri-acpi/kernel32.inc index 8dbcb02e2e..4d0263b1c7 100644 --- a/kernel/branches/Kolibri-acpi/kernel32.inc +++ b/kernel/branches/Kolibri-acpi/kernel32.inc @@ -5,7 +5,7 @@ ;; ;; ;; KERNEL32.INC ;; ;; ;; -;; Included 32 bit kernel files for KolibriOS ;; +;; Included 32 bit kernel files for MenuetOS ;; ;; ;; ;; This file is kept separate as it will be easier to ;; ;; maintain and compile with an automated SETUP program ;; diff --git a/kernel/branches/Kolibri-acpi/network/IPv4.inc b/kernel/branches/Kolibri-acpi/network/IPv4.inc index be6a7d4a57..ff5970638e 100644 --- a/kernel/branches/Kolibri-acpi/network/IPv4.inc +++ b/kernel/branches/Kolibri-acpi/network/IPv4.inc @@ -16,7 +16,7 @@ ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -$Revision: 5584 $ +$Revision: 5842 $ IPv4_MAX_FRAGMENTS = 64 IPv4_MAX_ROUTES = 64 @@ -215,7 +215,6 @@ macro IPv4_checksum ptr { ; It will also re-construct fragmented packets ; ; IN: Pointer to buffer in [esp] -; size of buffer in [esp+4] ; pointer to device struct in ebx ; pointer to IPv4 header in edx ; size of IPv4 packet in ecx @@ -223,7 +222,7 @@ macro IPv4_checksum ptr { ; ;----------------------------------------------------------------- align 4 -IPv4_input: ; TODO: add IPv4 raw sockets support +IPv4_input: DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: packet from %u.%u.%u.%u ",\ [edx + IPv4_header.SourceAddress + 0]:1,[edx + IPv4_header.SourceAddress + 1]:1,\ @@ -232,6 +231,10 @@ IPv4_input: ; TODO: add IPv4 [edx + IPv4_header.DestinationAddress + 0]:1,[edx + IPv4_header.DestinationAddress + 1]:1,\ [edx + IPv4_header.DestinationAddress + 2]:1,[edx + IPv4_header.DestinationAddress + 3]:1 + call NET_ptr_to_num4 + cmp edi, -1 + je .invalid_device + ;------------------------------- ; re-calculate the checksum @@ -240,40 +243,32 @@ IPv4_input: ; TODO: add IPv4 DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: Checksum ok\n" -;----------------------------------- -; Check if destination IP is correct - - call NET_ptr_to_num4 - - ; check if it matches local ip (Using RFC1122 strong end system model) +;-------------------------------- +; Check if destination IP matches +; local ip (Using RFC1122 strong end system model) mov eax, [edx + IPv4_header.DestinationAddress] cmp eax, [IP_LIST + edi] je .ip_ok - ; check for broadcast (IP or (not SUBNET)) - +; network layer broadcast cmp eax, [BROADCAST_LIST + edi] je .ip_ok - ; or a special broadcast (255.255.255.255) - +; physical layer broadcast (255.255.255.255) cmp eax, 0xffffffff je .ip_ok - ; maybe it's a multicast (224.0.0.0/4) - +; multicast (224.0.0.0/4 = 224.0.0.0 to 239.255.255.255) and eax, 0x0fffffff cmp eax, 224 je .ip_ok - ; maybe we just dont have an IP yet and should accept everything on the IP level - +; maybe we just dont have an IP yet and should accept everything on the IP level cmp [IP_LIST + edi], 0 je .ip_ok - ; or it's just not meant for us.. :( - +; or it's just not meant for us.. :( DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: Destination address does not match!\n" jmp .dump @@ -305,7 +300,6 @@ IPv4_input: ; TODO: add IPv4 xchg cl, ch ; sub ecx, esi ; - lea edi, [edx + IPv4_header.SourceAddress] ; make edi ptr to source and dest IPv4 address mov al, [edx + IPv4_header.Protocol] add esi, edx ; make esi ptr to data @@ -318,11 +312,60 @@ IPv4_input: ; TODO: add IPv4 cmp al, IP_PROTO_ICMP je ICMP_input +;------------------------------- +; Look for a matching RAW socket + pusha + mov ecx, socket_mutex + call mutex_lock + popa + + add ecx, esi + sub ecx, edx + mov esi, edx + movzx edx, al + mov eax, net_sockets + .next_socket: + mov eax, [eax + SOCKET.NextPtr] + or eax, eax + jz .dump_unlock + + cmp [eax + SOCKET.Domain], AF_INET4 + jne .next_socket + + cmp [eax + SOCKET.Protocol], edx + jne .next_socket + + pusha + mov ecx, socket_mutex + call mutex_unlock + popa + + DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: found matching RAW socket: 0x%x\n", eax + + pusha + lea ecx, [eax + SOCKET.mutex] + call mutex_lock + popa + + jmp SOCKET_input + + .dump_unlock: + + pusha + mov ecx, socket_mutex + call mutex_unlock + popa + DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: unknown protocol %u\n", al .dump: DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: dumping\n" - inc [IPv4_packets_dumped] ; FIXME: use correct interface + inc [IPv4_packets_dumped + edi] + call NET_BUFF_free + ret + + .invalid_device: + DEBUGF DEBUG_NETWORK_ERROR, "IPv4_input: packet originated from invalid device\n" call NET_BUFF_free ret @@ -568,11 +611,12 @@ IPv4_find_fragment_slot: ; ; IPv4_output ; -; IN: eax = Destination IP +; IN: al = protocol +; ah = TTL ; ebx = device ptr (or 0 to let IP layer decide) ; ecx = data length ; edx = Source IP -; di = TTL shl 8 + protocol +; edi = Destination IP ; ; OUT: eax = pointer to buffer start / 0 on error ; ebx = device ptr (send packet through this device) @@ -589,7 +633,8 @@ IPv4_output: cmp ecx, 65500 ; Max IPv4 packet size ja .too_large - push ecx di eax + push ecx ax edi + mov eax, edi call IPv4_route ; outputs device number in edi, dest ip in eax, source IP in edx push edx test edi, edi @@ -601,7 +646,7 @@ IPv4_output: push ebx ; push the mac onto the stack push ax - inc [IPv4_packets_tx + edi] ; update stats + inc [IPv4_packets_tx + edi] ; update stats mov ax, ETHER_PROTO_IPv4 mov ebx, [NET_DRV_LIST + edi] @@ -642,7 +687,10 @@ IPv4_output: .arp_error: DEBUGF DEBUG_NETWORK_ERROR, "IPv4_output: ARP error=%x\n", eax - add esp, 3*4+2 + add esp, 4 + pop eax + DEBUGF DEBUG_NETWORK_ERROR, "IPv4_output: ip=0x%x\n", eax + add esp, 4+2 xor eax, eax ret @@ -678,9 +726,6 @@ IPv4_output_raw: DEBUGF 1,"IPv4_output_raw: size=%u ptr=%x socket=%x\n", ecx, esi, eax - cmp ecx, 1480 ;;;;; FIXME - ja .too_large - sub esp, 8 push esi eax @@ -707,7 +752,7 @@ IPv4_output_raw: mov dword[esp+4+4+4], eax pop eax esi -;; todo: check socket options if we should add header, or just compute checksum +;; TODO: check socket options if we should add header, or just compute checksum push edi ecx rep movsb @@ -734,11 +779,14 @@ IPv4_output_raw: ret .error: - add esp, 6 + add esp, 6+8+4+4 + mov ebx, ENOBUFS ; FIXME: NOBUFS or MSGSIZE error + or eax, -1 + ret + .arp_error: add esp, 8+4+4 - .too_large: - DEBUGF DEBUG_NETWORK_ERROR, "IPv4_output_raw: Failed\n" + mov ebx, ENOTCONN or eax, -1 ret @@ -746,117 +794,120 @@ IPv4_output_raw: ;-------------------------------------------------------- ; ; -; IN: dword [esp] = pointer to buffer containing ipv4 packet to be fragmented -; esi = pointer to ip header in that buffer -; ecx = max size of fragments +; IN: [esp] = pointer to buffer containing ipv4 packet to be fragmented +; edi = pointer to ip header in that buffer +; ebx = device ptr ; ; OUT: / ; ;-------------------------------------------------------- +proc IPv4_fragment stdcall buffer -align 4 -IPv4_fragment: +locals + offset dd ? + headerlength dd ? + headerptr dd ? + dataptr dd ? + remaining dd ? + segmentsize dd ? +endl DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_fragment\n" - and ecx, not 111b ; align 4 - - cmp ecx, sizeof.IPv4_header + 8 ; must be able to put at least 8 bytes - jb .err2 - - push esi ecx - mov eax, [esi + IPv4_header.DestinationAddress] - call ARP_IP_to_MAC - pop ecx esi - cmp eax, -1 - jz .err2 - - push ebx - push ax - - mov ebx, [NET_DRV_LIST] - lea eax, [ebx + ETH_DEVICE.mac] - push eax - - - push esi ; ptr to ip header - sub ecx, sizeof.IPv4_header ; substract header size - push ecx ; max data size - push dword 0 ; offset - - .new_fragment: - DEBUGF DEBUG_NETWORK_VERBOSE, "Ipv4_fragment: new fragment" - - mov ax, ETHER_PROTO_IPv4 - lea ebx, [esp + 4*4] - call ETH_output - jz .err - -; copy header - mov esi, [esp + 2*4] - mov ecx, 5 ; 5 dwords: TODO: use IHL field of the header! - rep movsd - -; copy data - mov esi, [esp + 2*4] - add esi, sizeof.IPv4_header - add esi, [esp] ; offset - - mov ecx, [esp + 1*4] - DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_fragment: copying %u bytes\n", ecx - rep movsb - -; now, correct header - mov ecx, [esp + 1*4] - add ecx, sizeof.IPv4_header - xchg cl, ch - mov [edi + IPv4_header.TotalLength], cx - - mov ecx, [esp] ; offset - xchg cl, ch - -; cmp dword[esp + 4*4], 0 ; last fragment?;<<<<<< -; je .last_fragment - or cx, 1 shl 2 ; more fragments -; .last_fragment: - mov [edi + IPv4_header.FlagsAndFragmentOffset], cx +; We must be able to put at least 8 bytes per segment + movzx eax, byte[edi] ; IHL + and eax, 0xf + shl eax, 2 + mov [headerlength], eax + add eax, 8 + mov ecx, [ebx + NET_DEVICE.mtu] + and ecx, not 11b + cmp ecx, eax + jb .fail mov [edi + IPv4_header.HeaderChecksum], 0 - ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<< send the packet - mov ecx, [esp + 1*4] + mov [segmentsize], ecx + mov [headerptr], edi + movzx ecx, [edi + IPv4_header.TotalLength] + xchg cl, ch + sub ecx, [headerlength] + mov [remaining], ecx + mov [offset], 0 - push edx eax + add edi, [headerlength] + mov [dataptr], edi + + .loop: + DEBUGF DEBUG_NETWORK_VERBOSE, "Ipv4_fragment: new fragment" + + mov ecx, [segmentsize] + cmp ecx, [remaining] + jbe @f + mov ecx, [remaining] + @@: + + mov ax, ETHER_PROTO_IPv4 + mov edx, [esp] + add edx, [edx + NET_BUFF.offset] +; add edx, ETH_header.DstMAC ; = 0 + call ETH_output + jz .fail + + push edi + mov edx, ecx + +; copy header + mov esi, [headerptr] + mov ecx, [headerlength] + shr ecx, 2 + rep movsd + +; copy data + mov esi, [dataptr] + add esi, [offset] + mov ecx, edx + sub ecx, [headerlength] + shr ecx, 2 + rep movsd + pop edi + +; now, correct header +; packet length + mov ax, dx + xchg al, ah + mov [edi + IPv4_header.TotalLength], ax + +; offset + mov eax, [offset] + xchg al, ah + + sub edx, [headerlength] + sub [remaining], edx + je @f + jb .fail + or ah, 1 shl 2 ; more fragments + add [offset], edx + @@: + mov [edi + IPv4_header.FlagsAndFragmentOffset], ax + +; Send the fragment IPv4_checksum edi - call [ebx + NET_DEVICE.transmit] - ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - mov ecx, [esp+4] - add [esp], ecx + cmp [remaining], 0 + jne .loop - mov ecx, [esp+3*4+6+4] ; ptr to begin of buff - add ecx, [esp+3*4+6+4+4] ; buff size - sub ecx, [esp+2*4] ; ptr to ip header - add ecx, [esp] ; offset - - DEBUGF DEBUG_NETWORK_VERBOSE, "Ipv4_fragment: %u bytes remaining\n", ecx - - cmp ecx, [esp+1*4] - jae .new_fragment - - mov [esp+4], ecx ; set fragment size to remaining packet size - jmp .new_fragment - - .err: - DEBUGF DEBUG_NETWORK_ERROR, "Ipv4_fragment: failed\n" - .done: - add esp, 12 + 4 + 6 - .err2: - DEBUGF DEBUG_NETWORK_VERBOSE, "Ipv4_fragment: dumping\n" call NET_BUFF_free ret + .fail: + DEBUGF DEBUG_NETWORK_ERROR, "Ipv4_fragment: failed\n" + call NET_BUFF_free + ret + +endp + ;--------------------------------------------------------------------------- @@ -973,11 +1024,6 @@ IPv4_connect: pushd [edx + 4] pop [eax + IP_SOCKET.RemoteIP] -; Set up data receiving queue - push eax - init_queue (eax + SOCKET_QUEUE_LOCATION) - pop eax - lea ecx, [eax + SOCKET.mutex] call mutex_unlock diff --git a/kernel/branches/Kolibri-acpi/network/icmp.inc b/kernel/branches/Kolibri-acpi/network/icmp.inc index 27b1c92df8..c3cabca200 100644 --- a/kernel/branches/Kolibri-acpi/network/icmp.inc +++ b/kernel/branches/Kolibri-acpi/network/icmp.inc @@ -133,8 +133,9 @@ macro ICMP_init { ; IN: Pointer to buffer in [esp] ; ebx = pointer to device struct ; ecx = ICMP Packet size +; edx = ptr to IPv4 header ; esi = ptr to ICMP Packet data -; edi = ptr to ipv4 source and dest address +; edi = interface number*4 ; ; OUT: / ; @@ -144,8 +145,13 @@ ICMP_input: DEBUGF DEBUG_NETWORK_VERBOSE, "ICMP_input\n" +; Dump all multicasts and broadcasts + mov eax, [IP_LIST + edi] + cmp eax, [edx + IPv4_header.DestinationAddress] + jne .dump + ; Check the checksum - push esi ecx + push esi ecx edx push [esi + ICMP_header.Checksum] mov [esi + ICMP_header.Checksum], 0 xor edx, edx @@ -153,17 +159,11 @@ ICMP_input: call checksum_2 pop si cmp dx, si - pop ecx esi + pop edx ecx esi jne .checksum_mismatch DEBUGF DEBUG_NETWORK_VERBOSE, "ICMP_input: Checksum OK\n" -; Ualidate device ptr - mov eax, edi - call NET_ptr_to_num4 - cmp edi, -1 - je .dump - ; Update stats inc [ICMP_PACKETS_RX + edi] @@ -177,10 +177,10 @@ ICMP_input: call mutex_lock popa - mov edx, [eax] ; ipv4 source address + add ecx, esi + sub ecx, edx + mov esi, edx mov eax, net_sockets - .try_more: -; mov , [esi + ICMP_header.Identifier] .next_socket: mov eax, [eax + SOCKET.NextPtr] or eax, eax @@ -192,12 +192,6 @@ ICMP_input: cmp [eax + SOCKET.Protocol], IP_PROTO_ICMP jne .next_socket - cmp [eax + IP_SOCKET.RemoteIP], edx - jne .next_socket - -; cmp [eax + ICMP_SOCKET.Identifier], -; jne .next_socket - pusha mov ecx, socket_mutex call mutex_unlock @@ -376,7 +370,7 @@ end if ; ; IN: eax = socket ptr ; ecx = data length -; esi = data offset +; edx = data pointer ; ;----------------------------------------------------------------- align 4 @@ -385,13 +379,13 @@ ICMP_output_raw: DEBUGF DEBUG_NETWORK_VERBOSE, "Creating ICMP Packet for socket %x, data ptr=%x\n", eax, edx push edx - - mov di, IP_PROTO_ICMP SHL 8 + 128 ; TTL - mov edx, [eax + IP_SOCKET.LocalIP] mov ebx, [eax + IP_SOCKET.device] - mov eax, [eax + IP_SOCKET.RemoteIP] + mov edx, [eax + IP_SOCKET.LocalIP] + mov edi, [eax + IP_SOCKET.RemoteIP] + mov al, [eax + IP_SOCKET.ttl] + mov ah, IP_PROTO_ICMP call IPv4_output - jz .exit + jz .fail pop esi push eax @@ -415,10 +409,14 @@ ICMP_output_raw: jnz @f call NET_ptr_to_num4 inc [ICMP_PACKETS_TX + edi] - @@: + @@: ret - .exit: + + .fail: + pop edx DEBUGF DEBUG_NETWORK_ERROR, "Creating ICMP Packet failed\n" + or eax, -1 + mov ebx, EMSGSIZE ;;; FIXME ret diff --git a/kernel/branches/Kolibri-acpi/network/loopback.inc b/kernel/branches/Kolibri-acpi/network/loopback.inc index eca4c5d90d..d15c418558 100644 --- a/kernel/branches/Kolibri-acpi/network/loopback.inc +++ b/kernel/branches/Kolibri-acpi/network/loopback.inc @@ -14,7 +14,7 @@ ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -$Revision: 5523 $ +$Revision: 5976 $ iglobal align 4 @@ -61,15 +61,15 @@ local .fail .fail: } -;----------------------------------------------------------------- -; -; LOOP_input -; -; IN: [esp+4] = Pointer to buffer -; -; OUT: / -; -;----------------------------------------------------------------- +;-----------------------------------------------------------------; +; ; +; LOOP_input ; +; ; +; IN: [esp+4] = Pointer to buffer ; +; ; +; OUT: / ; +; ; +;-----------------------------------------------------------------; align 4 LOOP_input: @@ -105,19 +105,19 @@ LOOP_input: ret -;----------------------------------------------------------------- -; -; LOOP_output -; -; IN: ecx = packet size -; edi = address family -; -; OUT: eax = start of net frame / 0 on error -; ebx = to device structure -; ecx = unchanged (packet size of embedded data) -; edi = start of payload -; -;----------------------------------------------------------------- +;-----------------------------------------------------------------; +; ; +; LOOP_output ; +; ; +; IN: ecx = packet size ; +; edi = address family ; +; ; +; OUT: eax = start of net frame / 0 on error ; +; ebx = to device structure ; +; ecx = unchanged (packet size of embedded data) ; +; edi = start of payload ; +; ; +;-----------------------------------------------------------------; align 4 LOOP_output: diff --git a/kernel/branches/Kolibri-acpi/network/socket.inc b/kernel/branches/Kolibri-acpi/network/socket.inc index 8bc5c7ed94..bf67c3faee 100644 --- a/kernel/branches/Kolibri-acpi/network/socket.inc +++ b/kernel/branches/Kolibri-acpi/network/socket.inc @@ -19,23 +19,23 @@ $Revision$ struct SOCKET - NextPtr dd ? ; pointer to next socket in list - PrevPtr dd ? ; pointer to previous socket in list - Number dd ? ; socket number + NextPtr dd ? ; pointer to next socket in list + PrevPtr dd ? ; pointer to previous socket in list + Number dd ? ; socket number mutex MUTEX - PID dd ? ; process ID - TID dd ? ; thread ID - Domain dd ? ; INET/LOCAL/.. - Type dd ? ; RAW/STREAM/DGRAM - Protocol dd ? ; ICMP/IPv4/ARP/TCP/UDP + PID dd ? ; process ID + TID dd ? ; thread ID + Domain dd ? ; INET4/INET6/LOCAL/.. + Type dd ? ; RAW/STREAM/DGRAM + Protocol dd ? ; UDP/TCP/ARP/ICMP errorcode dd ? - device dd ? ; driver pointer, socket pointer if it's an LOCAL socket + device dd ? ; device pointer, paired socket pointer if it's a local socket options dd ? state dd ? - backlog dw ? ; how many incoming connections that can be queued + backlog dw ? ; number of incoming connections that can be queued snd_proc dd ? rcv_proc dd ? @@ -45,19 +45,21 @@ ends struct IP_SOCKET SOCKET - LocalIP rd 4 ; network byte order - RemoteIP rd 4 ; network byte order + LocalIP rd 4 ; network byte order + RemoteIP rd 4 ; network byte order + ttl db ? + rb 3 ; align ends struct TCP_SOCKET IP_SOCKET - LocalPort dw ? ; network byte order - RemotePort dw ? ; network byte order + LocalPort dw ? ; network byte order + RemotePort dw ? ; network byte order - t_state dd ? ; TCB state + t_state dd ? ; TCB state t_rxtshift db ? - rb 3 ; align + rb 3 ; align t_rxtcur dd ? t_dupacks dd ? t_maxseg dd ? @@ -68,19 +70,19 @@ struct TCP_SOCKET IP_SOCKET ; RFC783 page 21 ; send sequence - SND_UNA dd ? ; sequence number of unack'ed sent Packets - SND_NXT dd ? ; next send sequence number to use - SND_UP dd ? ; urgent pointer - SND_WL1 dd ? ; window minus one - SND_WL2 dd ? ; - ISS dd ? ; initial send sequence number - SND_WND dd ? ; send window + SND_UNA dd ? ; sequence number of unack'ed sent Packets + SND_NXT dd ? ; next send sequence number to use + SND_UP dd ? ; urgent pointer + SND_WL1 dd ? ; window minus one + SND_WL2 dd ? ; + ISS dd ? ; initial send sequence number + SND_WND dd ? ; send window ; receive sequence - RCV_WND dd ? ; receive window - RCV_NXT dd ? ; next receive sequence number to use - RCV_UP dd ? ; urgent pointer - IRS dd ? ; initial receive sequence number + RCV_WND dd ? ; receive window + RCV_NXT dd ? ; next receive sequence number to use + RCV_UP dd ? ; urgent pointer + IRS dd ? ; initial receive sequence number ;--------------------- ; Additional variables @@ -128,44 +130,36 @@ struct TCP_SOCKET IP_SOCKET ;------- ; Timers timer_flags dd ? - timer_retransmission dd ? ; rexmt + timer_retransmission dd ? ; rexmt timer_persist dd ? - timer_keepalive dd ? ; keepalive/syn timeout - timer_timed_wait dd ? ; also used as 2msl timer + timer_keepalive dd ? ; keepalive/syn timeout + timer_timed_wait dd ? ; also used as 2msl timer timer_connect dd ? ; extra - ts_ecr dd ? ; timestamp echo reply + ts_ecr dd ? ; timestamp echo reply ts_val dd ? - seg_next dd ? ; re-assembly queue + seg_next dd ? ; re-assembly queue ends struct UDP_SOCKET IP_SOCKET - LocalPort dw ? ; network byte order - RemotePort dw ? ; network byte order + LocalPort dw ? ; in network byte order + RemotePort dw ? ; in network byte order ends - -struct ICMP_SOCKET IP_SOCKET - - Identifier dw ? - -ends - - struct RING_BUFFER mutex MUTEX - start_ptr dd ? ; Pointer to start of buffer - end_ptr dd ? ; pointer to end of buffer - read_ptr dd ? ; Read pointer - write_ptr dd ? ; Write pointer - size dd ? ; Number of bytes buffered + start_ptr dd ? ; Pointer to start of buffer + end_ptr dd ? ; pointer to end of buffer + read_ptr dd ? ; Read pointer + write_ptr dd ? ; Write pointer + size dd ? ; Number of bytes buffered ends @@ -184,10 +178,18 @@ struct socket_queue_entry ends +struct socket_options -SOCKETBUFFSIZE = 4096 ; in bytes + level dd ? + optname dd ? + optlen dd ? + optval dd ? -SOCKET_QUEUE_SIZE = 10 ; maximum number of incoming packets queued for 1 socket +ends + +SOCKETBUFFSIZE = 4096 ; in bytes + +SOCKET_QUEUE_SIZE = 10 ; maximum number of incoming packets queued for 1 socket ; the incoming packet queue for sockets is placed in the socket struct itself, at this location from start SOCKET_QUEUE_LOCATION = (SOCKETBUFFSIZE - SOCKET_QUEUE_SIZE*sizeof.socket_queue_entry - sizeof.queue) @@ -196,18 +198,18 @@ align 4 net_sockets rd 4 last_socket_num dd ? - last_UDP_port dw ? ; These values give the number of the last used ephemeral port - last_TCP_port dw ? ; + last_UDP_port dw ? ; last used ephemeral port + last_TCP_port dw ? ; socket_mutex MUTEX endg -;----------------------------------------------------------------- -; -; SOCKET_init -; -;----------------------------------------------------------------- +;-----------------------------------------------------------------; +; ; +; SOCKET_init ; +; ; +;-----------------------------------------------------------------; macro SOCKET_init { xor eax, eax @@ -238,11 +240,11 @@ macro SOCKET_init { } -;----------------------------------------------------------------- -; -; Socket API (function 74) -; -;----------------------------------------------------------------- +;-----------------------------------------------------------------; +; ; +; Sockets API (system function 75) ; +; ; +;-----------------------------------------------------------------; align 4 sys_socket: @@ -256,17 +258,17 @@ sys_socket: jmp dword [.table + 4*ebx] .table: - dd SOCKET_open ; 0 - dd SOCKET_close ; 1 - dd SOCKET_bind ; 2 - dd SOCKET_listen ; 3 - dd SOCKET_connect ; 4 - dd SOCKET_accept ; 5 - dd SOCKET_send ; 6 - dd SOCKET_receive ; 7 - dd SOCKET_set_opt ; 8 - dd SOCKET_get_opt ; 9 - dd SOCKET_pair ; 10 + dd SOCKET_open ; 0 + dd SOCKET_close ; 1 + dd SOCKET_bind ; 2 + dd SOCKET_listen ; 3 + dd SOCKET_connect ; 4 + dd SOCKET_accept ; 5 + dd SOCKET_send ; 6 + dd SOCKET_receive ; 7 + dd SOCKET_set_opt ; 8 + dd SOCKET_get_opt ; 9 + dd SOCKET_pair ; 10 .number = ($ - .table) / 4 - 1 .error: @@ -275,16 +277,19 @@ sys_socket: ret -;----------------------------------------------------------------- -; -; SOCKET_open -; -; IN: domain in ecx -; type in edx -; protocol in esi -; OUT: eax is socket num, -1 on error -; -;----------------------------------------------------------------- +;-----------------------------------------------------------------; +; ; +; SOCKET_open: Create a new socket. ; +; ; +; IN: ecx = domain ; +; edx = type ; +; esi = protocol ; +; ; +; OUT: eax = socket number ; +; eax = -1 on error ; +; ebx = errorcode on error ; +; ; +;-----------------------------------------------------------------; align 4 SOCKET_open: @@ -296,7 +301,7 @@ SOCKET_open: test eax, eax jz .nobuffs - mov [esp+32], edi ; return socketnumber + mov [esp+32], edi ; return socketnumber DEBUGF DEBUG_NETWORK_VERBOSE, "socknum=%u\n", edi test edx, SO_NONBLOCK @@ -313,6 +318,8 @@ SOCKET_open: cmp ecx, AF_INET4 jne .no_inet4 + mov [eax + IP_SOCKET.ttl], 128 + cmp edx, SOCK_DGRAM je .udp @@ -344,7 +351,7 @@ SOCKET_open: ret .raw: - test esi, esi ; IP_PROTO_IP + test esi, esi ; IP_PROTO_IP jz .raw_ip cmp esi, IP_PROTO_ICMP @@ -354,6 +361,10 @@ SOCKET_open: align 4 .udp: + push eax + init_queue (eax + SOCKET_QUEUE_LOCATION) ; Set up data receiving queue + pop eax + mov [eax + SOCKET.Protocol], IP_PROTO_UDP mov [eax + SOCKET.snd_proc], SOCKET_send_udp mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram @@ -373,6 +384,10 @@ align 4 align 4 .raw_ip: + push eax + init_queue (eax + SOCKET_QUEUE_LOCATION) ; Set up data receiving queue + pop eax + mov [eax + SOCKET.snd_proc], SOCKET_send_ip mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram mov [eax + SOCKET.connect_proc], IPv4_connect @@ -381,6 +396,10 @@ align 4 align 4 .raw_icmp: + push eax + init_queue (eax + SOCKET_QUEUE_LOCATION) ; Set up data receiving queue + pop eax + mov [eax + SOCKET.snd_proc], SOCKET_send_icmp mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram mov [eax + SOCKET.connect_proc], IPv4_connect @@ -397,28 +416,32 @@ align 4 ret -;----------------------------------------------------------------- -; -; SOCKET_bind -; -; IN: socket number in ecx -; pointer to sockaddr struct in edx -; length of that struct in esi -; OUT: 0 on success -; -;----------------------------------------------------------------- +;-----------------------------------------------------------------; +; ; +; SOCKET_bind: Bind to a local port. ; +; ; +; IN: ecx = socket number ; +; edx = pointer to sockaddr struct ; +; esi = length of sockaddr struct ; +; ; +; OUT: eax = 0 on success ; +; eax = -1 on error ; +; ebx = errorcode on error ; +; ; +;-----------------------------------------------------------------; align 4 SOCKET_bind: DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_bind: socknum=%u sockaddr=%x length=%u\n", ecx, edx, esi call SOCKET_num_to_ptr + test eax, eax jz .invalid cmp esi, 2 jb .invalid - cmp [eax + UDP_SOCKET.LocalPort], 0 ; Socket can only be bound once + cmp [eax + UDP_SOCKET.LocalPort], 0 ; Socket can only be bound once jnz .invalid cmp word [edx], AF_INET4 @@ -486,22 +509,26 @@ SOCKET_bind: -;----------------------------------------------------------------- -; -; SOCKET_connect -; -; IN: socket number in ecx -; pointer to sockaddr struct in edx -; length of that struct in esi -; OUT: 0 on success -; -;----------------------------------------------------------------- +;-----------------------------------------------------------------; +; ; +; SOCKET_connect: Connect to the remote host. ; +; ; +; IN: ecx = socket number ; +; edx = pointer to sockaddr struct ; +; esi = length of sockaddr struct ; +; ; +; OUT: eax = 0 on success ; +; eax = -1 on error ; +; ebx = errorcode on error ; +; ; +;-----------------------------------------------------------------; align 4 SOCKET_connect: DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_connect: socknum=%u sockaddr=%x length=%u\n", ecx, edx, esi call SOCKET_num_to_ptr + test eax, eax jz .invalid cmp esi, 8 @@ -543,21 +570,25 @@ connect_notsupp: ret -;----------------------------------------------------------------- -; -; SOCKET_listen -; -; IN: socket number in ecx -; backlog in edx -; OUT: eax is socket num, -1 on error -; -;----------------------------------------------------------------- +;-----------------------------------------------------------------; +; ; +; SOCKET_listen: Listen for incoming connections. ; +; ; +; IN: ecx = socket number ; +; edx = backlog in edx ; +; ; +; OUT: eax = 0 on success ; +; eax = -1 on error ; +; ebx = errorcode on error ; +; ; +;-----------------------------------------------------------------; align 4 SOCKET_listen: DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_listen: socknum=%u backlog=%u\n", ecx, edx call SOCKET_num_to_ptr + test eax, eax jz .invalid cmp [eax + SOCKET.Domain], AF_INET4 @@ -608,22 +639,26 @@ SOCKET_listen: ret -;----------------------------------------------------------------- -; -; SOCKET_accept -; -; IN: socket number in ecx -; addr in edx -; addrlen in esi -; OUT: eax is socket num, -1 on error -; -;----------------------------------------------------------------- +;-----------------------------------------------------------------; +; ; +; SOCKET_accept: Accept an incoming connection. ; +; ; +; IN: ecx = socket number (of listening socket) ; +; edx = ptr to sockaddr struct ; +; esi = length of sockaddr struct ; +; ; +; OUT: eax = newly created socket num ; +; eax = -1 on error ; +; ebx = errorcode on error ; +; ; +;-----------------------------------------------------------------; align 4 SOCKET_accept: DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_accept: socknum=%u sockaddr=%x length=%u\n", ecx, edx, esi call SOCKET_num_to_ptr + test eax, eax jz .invalid test [eax + SOCKET.options], SO_ACCEPTCON @@ -641,16 +676,17 @@ SOCKET_accept: ; Ok, we got a socket ptr mov eax, [esi] -; Change thread ID to that of the current thread +; Verify that it is (still) a valid socket + call SOCKET_check + jz .invalid + +; Change sockets thread owner ID to that of the current thread mov ebx, [TASK_BASE] mov ebx, [ebx + TASKDATA.pid] mov [eax + SOCKET.TID], ebx -; Convert it to a socket number - call SOCKET_ptr_to_num - jz .invalid ; FIXME ? - -; and return it to caller +; Return socket number to caller + mov eax, [eax + SOCKET.Number] mov [esp+32], eax ret @@ -676,20 +712,24 @@ SOCKET_accept: mov dword[esp+32], -1 ret -;----------------------------------------------------------------- -; -; SOCKET_close -; -; IN: socket number in ecx -; OUT: eax is socket num, -1 on error -; -;----------------------------------------------------------------- +;-----------------------------------------------------------------; +; ; +; SOCKET_close: Close the socket (and connection). ; +; ; +; IN: ecx = socket number ; +; ; +; OUT: eax = 0 on success ; +; eax = -1 on error ; +; ebx = errorcode on error ; +; ; +;-----------------------------------------------------------------; align 4 SOCKET_close: DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_close: socknum=%u\n", ecx call SOCKET_num_to_ptr + test eax, eax jz .invalid mov dword[esp+32], 0 ; The socket exists, so we will succeed in closing it. @@ -712,14 +752,12 @@ SOCKET_close: ret .tcp: - call TCP_usrclosed test eax, eax jz @f call TCP_output ; If connection is not closed yet, send the FIN @@: - ret @@ -729,23 +767,28 @@ SOCKET_close: ret -;----------------------------------------------------------------- -; -; SOCKET_receive -; -; IN: socket number in ecx -; addr to buffer in edx -; length of buffer in esi -; flags in edi -; OUT: eax is number of bytes copied, -1 on error -; -;----------------------------------------------------------------- +;-----------------------------------------------------------------; +; ; +; SOCKET_receive: Receive some data from the remote end. ; +; ; +; IN: ecx = socket number ; +; edx = addr to application buffer ; +; edx = length of application buffer ; +; edi = flags ; +; ; +; OUT: eax = number of bytes copied ; +; eax = -1 on error ; +; eax = 0 when socket has been closed by the remote end ; +; ebx = errorcode on error ; +; ; +;-----------------------------------------------------------------; align 4 SOCKET_receive: DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_receive: socknum=%u bufaddr=%x buflength=%u flags=%x\n", ecx, edx, esi, edi call SOCKET_num_to_ptr + test eax, eax jz .invalid .loop: @@ -762,8 +805,8 @@ SOCKET_receive: test edi, MSG_DONTWAIT jnz .return_err -; test [eax + SOCKET.options], SO_NONBLOCK -; jnz .return_err + test [eax + SOCKET.options], SO_NONBLOCK + jnz .return_err call SOCKET_block jmp .loop @@ -782,7 +825,7 @@ SOCKET_receive: .last_data: test ecx, ecx jz .return - call SOCKET_notify + call SOCKET_notify ; Call me again! jmp .return @@ -793,7 +836,10 @@ SOCKET_receive_dgram: DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_receive: DGRAM\n" - mov ebx, esi ; bufferlength + test edi, MSG_PEEK + jnz .peek + + mov ebx, esi ; buffer length get_from_queue (eax + SOCKET_QUEUE_LOCATION), SOCKET_QUEUE_SIZE, sizeof.socket_queue_entry, .wouldblock ; sets esi only on success. mov ecx, [esi + socket_queue_entry.data_size] @@ -824,7 +870,11 @@ SOCKET_receive_dgram: call NET_BUFF_free pop ecx eax ; return number of bytes copied to application - xor ebx, ebx + cmp [eax + SOCKET_QUEUE_LOCATION + queue.size], 0 + je @f + call SOCKET_notify ; Queue another network event + @@: + xor ebx, ebx ; errorcode = 0 (no error) ret .too_small: @@ -838,6 +888,15 @@ SOCKET_receive_dgram: pop ebx ret + .peek: + xor ebx, ebx + xor ecx, ecx + cmp [eax + SOCKET_QUEUE_LOCATION + queue.size], 0 + je @f + mov esi, [eax + SOCKET_QUEUE_LOCATION + queue.r_ptr] + mov ecx, [esi + socket_queue_entry.data_size] + @@: + ret align 4 @@ -901,24 +960,27 @@ SOCKET_receive_stream: ret -;----------------------------------------------------------------- -; -; SOCKET_send -; -; -; IN: socket number in ecx -; pointer to data in edx -; datalength in esi -; flags in edi -; OUT: -1 on error -; -;----------------------------------------------------------------- +;-----------------------------------------------------------------; +; ; +; SOCKET_send: Send some data to the remote end. ; +; ; +; IN: ecx = socket number ; +; edx = pointer to data ; +; esi = data length ; +; edi = flags ; +; ; +; OUT: eax = number of bytes sent ; +; eax = -1 on error ; +; ebx = errorcode on error ; +; ; +;-----------------------------------------------------------------; align 4 SOCKET_send: DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_send: socknum=%u data ptr=%x length=%u flags=%x\n", ecx, edx, esi, edi call SOCKET_num_to_ptr + test eax, eax jz .invalid mov ecx, esi @@ -975,14 +1037,14 @@ SOCKET_send_ip: DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_send: IPv4\n" mov [esp+32], ecx - call IPv4_output_raw ; FIXME: IPv4_output_raw should return error codes! + call IPv4_output_raw cmp eax, -1 je .error ret .error: - mov dword[esp+32], -1 - mov dword[esp+20], EMSGSIZE + mov dword[esp+32], eax + mov dword[esp+20], ebx ret @@ -992,14 +1054,14 @@ SOCKET_send_icmp: DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_send: ICMP\n" mov [esp+32], ecx - call ICMP_output_raw ; FIXME: errorcodes + call ICMP_output_raw cmp eax, -1 je .error ret .error: - mov dword[esp+32], -1 - mov dword[esp+20], EMSGSIZE + mov dword[esp+32], eax + mov dword[esp+20], ebx ret @@ -1068,26 +1130,30 @@ SOCKET_send_local_: ret -;----------------------------------------------------------------- -; -; SOCKET_get_options -; -; IN: ecx = socket number -; edx = pointer to the options: -; dd level, optname, optval, optlen -; OUT: -1 on error -; +;-----------------------------------------------------------------; +; ; +; SOCKET_get_options: Read a socket option ; +; ; +; IN: ecx = socket number ; +; edx = pointer to socket options struct ; +; ; +; OUT: eax = 0 on success ; +; eax = -1 on error ; +; ebx = errorcode on error ; +; ; +;-----------------------------------------------------------------; +align 4 +SOCKET_get_opt: + +; FIXME: ; At moment, uses only pseudo-optname -2 for get last_ack_number for TCP. ; TODO: find best way to notify that send()'ed data were acknowledged ; Also pseudo-optname -3 is valid and returns socket state, one of TCPS_*. -; -;----------------------------------------------------------------- -align 4 -SOCKET_get_opt: DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_get_opt\n" call SOCKET_num_to_ptr + test eax, eax jz .invalid cmp dword [edx], IP_PROTO_TCP @@ -1126,41 +1192,41 @@ SOCKET_get_opt: ret - -;----------------------------------------------------------------- -; -; SOCKET_set_options -; -; IN: ecx = socket number -; edx = pointer to the options: -; dd level, optname, optlen, optval -; OUT: -1 on error -; -;----------------------------------------------------------------- +;-----------------------------------------------------------------; +; ; +; SOCKET_set_options: Set a socket option. ; +; ; +; IN: ecx = socket number ; +; edx = pointer to socket options struct ; +; ; +; OUT: eax = 0 on success ; +; eax = -1 on error ; +; ebx = errorcode on error ; +; ; +;-----------------------------------------------------------------; align 4 SOCKET_set_opt: DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_set_opt\n" call SOCKET_num_to_ptr + test eax, eax jz .invalid - cmp dword [edx], SOL_SOCKET + cmp [edx + socket_options.level], IP_PROTO_IP + je .ip + cmp [edx + socket_options.level], SOL_SOCKET jne .invalid - cmp dword [edx+4], SO_BINDTODEVICE - je .bind - - .invalid: - mov dword[esp+32], -1 - mov dword[esp+20], EINVAL - ret + .socket: + cmp [edx + socket_options.optname], SO_BINDTODEVICE + jne .invalid .bind: - cmp dword[edx+8], 0 + cmp [edx + socket_options.optlen], 0 je .unbind - movzx edx, byte[edx + 12] + movzx edx, byte[edx + socket_options.optval] cmp edx, NET_DEVICES_MAX ja .invalid @@ -1180,25 +1246,42 @@ SOCKET_set_opt: mov dword[esp+32], 0 ; success! ret + .ip: + cmp [edx + socket_options.optname], IP_TTL + jne .invalid + + .ttl: + mov bl, byte[edx + socket_options.optval] + mov [eax + IP_SOCKET.ttl], bl + + mov dword[esp+32], 0 ; success! + ret + .already: mov dword[esp+20], EALREADY mov dword[esp+32], -1 ret + .invalid: + mov dword[esp+20], EINVAL + mov dword[esp+32], -1 + ret + -;----------------------------------------------------------------- -; -; SOCKET_pair -; -; Allocates a pair of linked LOCAL domain sockets -; -; IN: / -; OUT: eax is socket1 num, -1 on error -; ebx is socket2 num -; -;----------------------------------------------------------------- +;-----------------------------------------------------------------; +; ; +; SOCKET_pair: Allocate a pair of linked local sockets. ; +; ; +; IN: / ; +; ; +; OUT: eax = socket1 num on success ; +; eax = -1 on error ; +; ebx = socket2 num on success ; +; ebx = errorcode on error ; +; ; +;-----------------------------------------------------------------; align 4 SOCKET_pair: @@ -1236,7 +1319,7 @@ SOCKET_pair: lea eax, [eax + STREAM_SOCKET.rcv] call SOCKET_ring_create test eax, eax - jz .nomem1 + jz .nomem2 lea eax, [ebx + STREAM_SOCKET.rcv] call SOCKET_ring_create @@ -1246,26 +1329,31 @@ SOCKET_pair: ret .nomem2: - mov eax, ebx + mov eax, [esp+20] call SOCKET_free + .nomem1: + mov eax, [esp+32] + call SOCKET_free + mov dword[esp+32], -1 - mov dword[esp+28], ENOMEM + mov dword[esp+20], ENOMEM ret -;----------------------------------------------------------------- -; -; SOCKET_debug -; -; Copies socket variables to application buffer -; -; IN: ecx = socket number -; edx = pointer to buffer -; -; OUT: -1 on error -;----------------------------------------------------------------- +;-----------------------------------------------------------------; +; ; +; SOCKET_debug: Copy socket variables to application buffer. ; +; ; +; IN: ecx = socket number ; +; edx = pointer to application buffer ; +; ; +; OUT: eax = 0 on success ; +; eax = -1 on error ; +; ebx = errorcode on error ; +; ; +;-----------------------------------------------------------------; align 4 SOCKET_debug: @@ -1277,6 +1365,7 @@ SOCKET_debug: jz .returnall call SOCKET_num_to_ptr + test eax, eax jz .invalid mov esi, eax @@ -1303,22 +1392,31 @@ SOCKET_debug: .invalid: mov dword[esp+32], -1 - mov dword[esp+28], EINVAL + mov dword[esp+20], EINVAL ret -;----------------------------------------------------------------- -; -; SOCKET_find_port -; -; Fills in the local port number for TCP and UDP sockets -; This procedure always works because the number of sockets is -; limited to a smaller number then the number of possible ports -; -; IN: eax = socket pointer -; OUT: / -; -;----------------------------------------------------------------- +;-----------------------------------------------------------------; +; ____ ____ ; +; \ / End of sockets API \ / ; +; \/ \/ ; +; () Internally used functions follow () ; +; ; +;-----------------------------------------------------------------; + + +;-----------------------------------------------------------------; +; ; +; SOCKET_find_port: ; +; Fill in the local port number for TCP and UDP sockets ; +; This procedure always works because the number of sockets is ; +; limited to a smaller number then the number of possible ports ; +; ; +; IN: eax = socket pointer ; +; ; +; OUT: / ; +; ; +;-----------------------------------------------------------------; align 4 SOCKET_find_port: @@ -1367,19 +1465,20 @@ SOCKET_find_port: -;----------------------------------------------------------------- -; -; SOCKET_check_port (to be used with AF_INET only!) -; -; Checks if a local port number is unused -; If the proposed port number is unused, it is filled in in the socket structure -; -; IN: eax = socket ptr (to find out if its a TCP/UDP socket) -; bx = proposed socket number (network byte order) -; -; OUT: ZF = set on error -; -;----------------------------------------------------------------- +;-----------------------------------------------------------------; +; ; +; SOCKET_check_port (to be used with AF_INET only!) ; +; ; +; Checks if a local port number is unused ; +; If the proposed port number is unused, it is filled in in the ; +; socket structure ; +; ; +; IN: eax = socket ptr ; +; bx = proposed socket number (network byte order) ; +; ; +; OUT: ZF = set on error ; +; ; +;-----------------------------------------------------------------; align 4 SOCKET_check_port: @@ -1429,22 +1528,20 @@ SOCKET_check_port: -;----------------------------------------------------------------- -; -; SOCKET_input -; -; Updates a (stateless) socket with received data -; -; Note: the mutex should already be set ! -; -; IN: eax = socket ptr -; ecx = data size -; esi = ptr to data -; [esp] = ptr to buf -; -; OUT: / -; -;----------------------------------------------------------------- +;-----------------------------------------------------------------; +; ; +; SOCKET_input: Update a (stateless) socket with received data. ; +; ; +; Note: The socket's mutex should already be set ! ; +; ; +; IN: eax = socket ptr ; +; ecx = data size ; +; esi = ptr to data ; +; [esp] = ptr to buf ; +; ; +; OUT: / ; +; ; +;-----------------------------------------------------------------; align 4 SOCKET_input: @@ -1474,14 +1571,21 @@ SOCKET_input: call mutex_unlock popa + add esp, 8 call NET_BUFF_free ret -;-------------------------- -; -; eax = ptr to ring struct (just a buffer of the right size) -; +;-----------------------------------------------------------------; +; ; +; SOCKET_ring_create: Create a ringbuffer for sockets. ; +; ; +; IN: eax = ptr to ring struct ; +; ; +; OUT: eax = 0 on error ; +; eax = start ptr ; +; ; +;-----------------------------------------------------------------; align 4 SOCKET_ring_create: @@ -1494,7 +1598,7 @@ SOCKET_ring_create: test eax, eax jz .fail - DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_ring_created: %x\n", eax + DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_ring_create: %x\n", eax pusha lea ecx, [esi + RING_BUFFER.mutex] @@ -1509,23 +1613,25 @@ SOCKET_ring_create: mov [esi + RING_BUFFER.end_ptr], eax mov eax, esi - .fail: pop esi ret -;----------------------------------------------------------------- -; -; SOCKET_ring_write -; -; Adds data to a stream socket, and updates write pointer and size -; -; IN: eax = ptr to ring struct -; ecx = data size -; esi = ptr to data -; -; OUT: ecx = number of bytes stored -; -;----------------------------------------------------------------- + .fail: + DEBUGF DEBUG_NETWORK_ERROR, "SOCKET_ring_create: Out of memory!\n" + pop esi + ret + +;-----------------------------------------------------------------; +; ; +; SOCKET_ring_write: Write data to ring buffer. ; +; ; +; IN: eax = ptr to ring struct ; +; ecx = data size ; +; esi = ptr to data ; +; ; +; OUT: ecx = number of bytes stored ; +; ; +;-----------------------------------------------------------------; align 4 SOCKET_ring_write: @@ -1585,22 +1691,22 @@ SOCKET_ring_write: ret -;----------------------------------------------------------------- -; -; SOCKET_ring_read -; -; IN: eax = ring struct ptr -; ecx = bytes to read -; edx = offset -; edi = ptr to buffer start -; -; OUT: eax = unchanged -; ecx = number of bytes read (0 on error) -; edx = destroyed -; esi = destroyed -; edi = ptr to buffer end -; -;----------------------------------------------------------------- +;-----------------------------------------------------------------; +; ; +; SOCKET_ring_read: Read from ring buffer ; +; ; +; IN: eax = ring struct ptr ; +; ecx = bytes to read ; +; edx = offset ; +; edi = ptr to buffer start ; +; ; +; OUT: eax = unchanged ; +; ecx = number of bytes read (0 on error) ; +; edx = destroyed ; +; esi = destroyed ; +; edi = ptr to buffer end ; +; ; +;-----------------------------------------------------------------; align 4 SOCKET_ring_read: @@ -1659,18 +1765,16 @@ SOCKET_ring_read: jmp .copy -;----------------------------------------------------------------- -; -; SOCKET_ring_free -; -; Free's some bytes from the ringbuffer -; -; IN: eax = ptr to ring struct -; ecx = data size -; -; OUT: ecx = number of bytes free-ed -; -;----------------------------------------------------------------- +;-----------------------------------------------------------------; +; ; +; SOCKET_ring_free: Free data from a ringbuffer ; +; ; +; IN: eax = ptr to ring struct ; +; ecx = data size ; +; ; +; OUT: ecx = number of freed bytes ; +; ; +;-----------------------------------------------------------------; align 4 SOCKET_ring_free: @@ -1711,16 +1815,15 @@ SOCKET_ring_free: ret -;----------------------------------------------------------------- -; -; SOCKET_block -; -; Suspends the thread attached to a socket -; -; IN: eax = socket ptr -; OUT: eax = unchanged -; -;----------------------------------------------------------------- +;-----------------------------------------------------------------; +; ; +; SOCKET_block: Suspend the thread attached to a socket. ; +; ; +; IN: eax = socket ptr ; +; ; +; OUT: eax = unchanged ; +; ; +;-----------------------------------------------------------------; align 4 SOCKET_block: @@ -1754,16 +1857,15 @@ SOCKET_block: ret -;----------------------------------------------------------------- -; -; SOCKET_notify -; -; notify's the owner of a socket that something happened -; -; IN: eax = socket ptr -; OUT: eax = unchanged -; -;----------------------------------------------------------------- +;-----------------------------------------------------------------; +; ; +; SOCKET_notify: Wake up socket owner thread. ; +; ; +; IN: eax = socket ptr ; +; ; +; OUT: eax = unchanged ; +; ; +;-----------------------------------------------------------------; align 4 SOCKET_notify: @@ -1802,7 +1904,7 @@ SOCKET_notify: test [eax + SOCKET.state], SS_BLOCKED jnz .un_block -; socket and thread exists and socket is of non blocking type. +; Socket and thread exists and socket is of non blocking type. ; We'll try to flag an event to the thread. shl ecx, 8 or [ecx + SLOT_BASE + APPDATA.event_mask], EVENT_NETWORK @@ -1813,7 +1915,7 @@ SOCKET_notify: .un_block: -; socket and thread exists and socket is of blocking type +; Socket and thread exists and socket is of blocking type ; We'll try to unblock it. and [eax + SOCKET.state], not SS_BLOCKED ; Clear the 'socket is blocked' flag mov [esi + TASKDATA.state], 0 ; Run the thread @@ -1823,28 +1925,29 @@ SOCKET_notify: ret -;-------------------------------------------------------------------- -; -; SOCKET_alloc -; -; Allocate memory for socket data and put new socket into the list -; Newly created socket is initialized with calling PID and number and -; put into beginning of list (which is a fastest way). -; -; IN: / -; OUT: eax = 0 on error, socket ptr otherwise -; edi = socket number -; -;-------------------------------------------------------------------- +;-----------------------------------------------------------------; +; ; +; SOCKET_alloc: ; +; Allocate memory for socket and put new socket into the list. ; +; Newly created socket is initialized with calling PID and socket ; +; number. ; +; ; +; IN: / ; +; ; +; OUT: eax = socket ptr on success ; +; eax = 0 on error ; +; edi = socket number on success ; +; ; +;-----------------------------------------------------------------; align 4 SOCKET_alloc: push ebx stdcall kernel_alloc, SOCKETBUFFSIZE - DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_alloc: ptr=%x\n", eax or eax, eax - jz .exit + jz .nomem + DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_alloc: ptr=%x\n", eax ; zero-initialize allocated memory push eax @@ -1925,29 +2028,32 @@ SOCKET_alloc: mov ecx, socket_mutex call mutex_unlock popa - - .exit: pop ebx ret + .nomem: + DEBUGF DEBUG_NETWORK_ERROR, "SOCKET_alloc: Out of memory!\n" + pop ebx + ret + .not_yet: mov dword[esp+20], ENOTCONN mov dword[esp+32], -1 ret -;---------------------------------------------------- -; -; SOCKET_free -; -; Free socket data memory and remove socket from the list -; Caller should lock and unlock socket_mutex -; -; IN: eax = socket ptr -; OUT: / -; -;---------------------------------------------------- +;-----------------------------------------------------------------; +; ; +; SOCKET_free: ; +; Free socket data memory and remove socket from the list. ; +; Caller should lock and unlock socket_mutex. ; +; ; +; IN: eax = socket ptr ; +; ; +; OUT: / ; +; ; +;-----------------------------------------------------------------; align 4 SOCKET_free: @@ -1963,17 +2069,20 @@ SOCKET_free: call mutex_lock popa - cmp [eax + SOCKET.Domain], AF_INET4 - jnz .no_tcp - - cmp [eax + SOCKET.Protocol], IP_PROTO_TCP - jnz .no_tcp + cmp [eax + SOCKET.Type], SOCK_STREAM + jne .no_stream mov ebx, eax - stdcall kernel_free, [ebx + STREAM_SOCKET.rcv.start_ptr] - stdcall kernel_free, [ebx + STREAM_SOCKET.snd.start_ptr] + cmp [eax + STREAM_SOCKET.rcv.start_ptr], 0 + je @f + stdcall free_kernel_space, [eax + STREAM_SOCKET.rcv.start_ptr] + @@: + cmp [ebx + STREAM_SOCKET.snd.start_ptr], 0 + je @f + stdcall free_kernel_space, [ebx + STREAM_SOCKET.snd.start_ptr] + @@: mov eax, ebx - .no_tcp: + .no_stream: DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_free: freeing socket %x\n", eax push eax ; this will be passed to kernel_free @@ -2000,16 +2109,22 @@ SOCKET_free: .error: ret -;------------------------------------ -; -; SOCKET_fork -; -; Create a child socket -; -; IN: socket nr in ebx -; OUT: child socket nr in eax -; -;----------------------------------- + .error1: + pop ebx + DEBUGF DEBUG_NETWORK_ERROR, "SOCKET_free: error!\n" + DEBUGF DEBUG_NETWORK_ERROR, "socket ptr=0x%x caller=0x%x\n", eax, [esp] + ret + +;-----------------------------------------------------------------; +; ; +; SOCKET_fork: Create a child socket. ; +; ; +; IN: ebx = socket number ; +; ; +; OUT: eax = child socket number on success ; +; eax = 0 on error ; +; ; +;-----------------------------------------------------------------; align 4 SOCKET_fork: @@ -2058,17 +2173,16 @@ SOCKET_fork: ret -;--------------------------------------------------- -; -; SOCKET_num_to_ptr -; -; Get socket structure address by its number -; -; IN: ecx = socket number -; OUT: eax = 0 on error, socket ptr otherwise -; ZF = set on error -; -;--------------------------------------------------- +;-----------------------------------------------------------------; +; ; +; SOCKET_num_to_ptr: Get socket structure address by its number. ; +; ; +; IN: ecx = socket number ; +; ; +; OUT: eax = socket ptr ; +; eax = 0 on error ; +; ; +;-----------------------------------------------------------------; align 4 SOCKET_num_to_ptr: @@ -2080,16 +2194,13 @@ SOCKET_num_to_ptr: popa mov eax, net_sockets - .next_socket: mov eax, [eax + SOCKET.NextPtr] - or eax, eax + test eax, eax jz .error cmp [eax + SOCKET.Number], ecx jne .next_socket - test eax, eax - pusha mov ecx, socket_mutex call mutex_unlock @@ -2109,17 +2220,17 @@ SOCKET_num_to_ptr: ret -;--------------------------------------------------- -; -; SOCKET_ptr_to_num -; -; Get socket number by its address -; -; IN: eax = socket ptr -; OUT: eax = 0 on error, socket num otherwise -; ZF = set on error -; -;--------------------------------------------------- +;-----------------------------------------------------------------; +; ; +; SOCKET_ptr_to_num: Get socket number by its address. ; +; ; +; IN: eax = socket ptr ; +; ; +; OUT: eax = socket number ; +; eax = 0 on error ; +; ZF = set on error ; +; ; +;-----------------------------------------------------------------; align 4 SOCKET_ptr_to_num: @@ -2138,22 +2249,23 @@ SOCKET_ptr_to_num: ret -;--------------------------------------------------- -; -; SOCKET_check -; -; checks if the given value is really a socket ptr -; -; IN: eax = socket ptr -; OUT: eax = 0 on error, unchanged otherwise -; ZF = set on error -; -;--------------------------------------------------- +;-----------------------------------------------------------------; +; ; +; SOCKET_check: Checks if the given ptr is really a socket ptr. ; +; ; +; IN: eax = socket ptr ; +; ; +; OUT: eax = 0 on error ; +; ZF = set on error ; +; ; +;-----------------------------------------------------------------; align 4 SOCKET_check: DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_check: %x\n", eax + test eax, eax + jz .error push ebx mov ebx, net_sockets @@ -2168,21 +2280,24 @@ SOCKET_check: mov eax, ebx test eax, eax pop ebx + ret + .error: + DEBUGF DEBUG_NETWORK_ERROR, "SOCKET_check: called with argument 0\n" + DEBUGF DEBUG_NETWORK_ERROR, "stack: 0x%x, 0x%x, 0x%x\n", [esp], [esp+4], [esp+8] ret -;--------------------------------------------------- -; -; SOCKET_check_owner -; -; checks if the caller application owns the socket -; -; IN: eax = socket ptr -; OUT: ZF = true/false -; -;--------------------------------------------------- +;-----------------------------------------------------------------; +; ; +; SOCKET_check_owner: Check if the caller app owns the socket. ; +; ; +; IN: eax = socket ptr ; +; ; +; OUT: ZF = true/false ; +; ; +;-----------------------------------------------------------------; align 4 SOCKET_check_owner: @@ -2199,18 +2314,18 @@ SOCKET_check_owner: -;------------------------------------------------------ -; -; SOCKET_process_end -; -; Kernel calls this function when a certain process ends -; This function will check if the process had any open sockets -; And update them accordingly (clean up) -; -; IN: edx = pid -; OUT: / -; -;------------------------------------------------------ +;-----------------------------------------------------------------; +; ; +; SOCKET_process_end: ; +; Kernel calls this function when a certain process ends. ; +; This function will check if the process had any open sockets, ; +; and update them accordingly (clean up). ; +; ; +; IN: edx = pid ; +; ; +; OUT: / ; +; ; +;-----------------------------------------------------------------; align 4 SOCKET_process_end: @@ -2277,15 +2392,15 @@ SOCKET_process_end: -;----------------------------------------------------------------- -; -; SOCKET_is_connecting -; -; IN: eax = socket ptr -; OUT: / -; -;----------------------------------------------------------------- - +;-----------------------------------------------------------------; +; ; +; SOCKET_is_connecting: Update socket state. ; +; ; +; IN: eax = socket ptr ; +; ; +; OUT: / ; +; ; +;-----------------------------------------------------------------; align 4 SOCKET_is_connecting: @@ -2293,20 +2408,19 @@ SOCKET_is_connecting: and [eax + SOCKET.state], not (SS_ISCONNECTED + SS_ISDISCONNECTING + SS_ISCONFIRMING) or [eax + SOCKET.state], SS_ISCONNECTING - ret -;----------------------------------------------------------------- -; -; SOCKET_is_connected -; -; IN: eax = socket ptr -; OUT: / -; -;----------------------------------------------------------------- - +;-----------------------------------------------------------------; +; ; +; SOCKET_is_connected: Update socket state. ; +; ; +; IN: eax = socket ptr ; +; ; +; OUT: / ; +; ; +;-----------------------------------------------------------------; align 4 SOCKET_is_connected: @@ -2314,21 +2428,20 @@ SOCKET_is_connected: and [eax + SOCKET.state], not (SS_ISCONNECTING + SS_ISDISCONNECTING + SS_ISCONFIRMING) or [eax + SOCKET.state], SS_ISCONNECTED - jmp SOCKET_notify -;----------------------------------------------------------------- -; -; SOCKET_is_disconnecting -; -; IN: eax = socket ptr -; OUT: / -; -;----------------------------------------------------------------- - +;-----------------------------------------------------------------; +; ; +; SOCKET_is_disconnecting: Update socket state. ; +; ; +; IN: eax = socket ptr ; +; ; +; OUT: / ; +; ; +;-----------------------------------------------------------------; align 4 SOCKET_is_disconnecting: @@ -2336,20 +2449,19 @@ SOCKET_is_disconnecting: and [eax + SOCKET.state], not (SS_ISCONNECTING) or [eax + SOCKET.state], SS_ISDISCONNECTING + SS_CANTRCVMORE + SS_CANTSENDMORE - jmp SOCKET_notify -;----------------------------------------------------------------- -; -; SOCKET_is_disconnected -; -; IN: eax = socket ptr -; OUT: / -; -;----------------------------------------------------------------- - +;-----------------------------------------------------------------; +; ; +; SOCKET_is_disconnected: Update socket state. ; +; ; +; IN: eax = socket ptr ; +; ; +; OUT: / ; +; ; +;-----------------------------------------------------------------; align 4 SOCKET_is_disconnected: @@ -2357,43 +2469,38 @@ SOCKET_is_disconnected: and [eax + SOCKET.state], not (SS_ISCONNECTING + SS_ISCONNECTED + SS_ISDISCONNECTING) or [eax + SOCKET.state], SS_CANTRCVMORE + SS_CANTSENDMORE - - jmp SOCKET_notify -;----------------------------------------------------------------- -; -; SOCKET_cant_recv_more -; -; IN: eax = socket ptr -; OUT: / -; -;----------------------------------------------------------------- - +;-----------------------------------------------------------------; +; ; +; SOCKET_cant_recv_more: Update socket state. ; +; ; +; IN: eax = socket ptr ; +; ; +; OUT: / ; +; ; +;-----------------------------------------------------------------; align 4 SOCKET_cant_recv_more: DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_cant_recv_more: %x\n", eax or [eax + SOCKET.state], SS_CANTRCVMORE - - call SOCKET_notify - - ret + jmp SOCKET_notify -;----------------------------------------------------------------- -; -; SOCKET_cant_send_more -; -; IN: eax = socket ptr -; OUT: / -; -;----------------------------------------------------------------- - +;-----------------------------------------------------------------; +; ; +; SOCKET_cant_send_more: Update socket state. ; +; ; +; IN: eax = socket ptr ; +; ; +; OUT: / ; +; ; +;-----------------------------------------------------------------; align 4 SOCKET_cant_send_more: @@ -2401,10 +2508,7 @@ SOCKET_cant_send_more: or [eax + SOCKET.state], SS_CANTSENDMORE mov [eax + SOCKET.snd_proc], .notconn - - call SOCKET_notify - - ret + jmp SOCKET_notify .notconn: mov dword[esp+20], ENOTCONN diff --git a/kernel/branches/Kolibri-acpi/network/stack.inc b/kernel/branches/Kolibri-acpi/network/stack.inc index fb3249edfb..5f0d7b90d8 100644 --- a/kernel/branches/Kolibri-acpi/network/stack.inc +++ b/kernel/branches/Kolibri-acpi/network/stack.inc @@ -53,6 +53,12 @@ IP_PROTO_IP = 0 IP_PROTO_ICMP = 1 IP_PROTO_TCP = 6 IP_PROTO_UDP = 17 +IP_PROTO_RAW = 255 + +; IP options +IP_TOS = 1 +IP_TTL = 2 +IP_HDRINCL = 3 ; PPP protocol numbers PPP_PROTO_IPv4 = 0x2100 @@ -71,6 +77,9 @@ SOCK_STREAM = 1 SOCK_DGRAM = 2 SOCK_RAW = 3 +; Socket level +SOL_SOCKET = 0xffff + ; Socket options SO_ACCEPTCON = 1 shl 0 SO_BROADCAST = 1 shl 1 @@ -89,10 +98,6 @@ SO_NONBLOCK = 1 shl 31 MSG_PEEK = 0x02 MSG_DONTWAIT = 0x40 -; Socket level -SOL_SOCKET = 0 - - ; Socket States SS_NOFDREF = 0x0001 ; no file table ref any more SS_ISCONNECTED = 0x0002 ; socket connected to a peer diff --git a/kernel/branches/Kolibri-acpi/network/tcp.inc b/kernel/branches/Kolibri-acpi/network/tcp.inc index b4c8fce060..4de1c981cc 100644 --- a/kernel/branches/Kolibri-acpi/network/tcp.inc +++ b/kernel/branches/Kolibri-acpi/network/tcp.inc @@ -201,13 +201,11 @@ align 4 endg -;----------------------------------------------------------------- -; -; TCP_init -; -; This function resets all TCP variables -; -;----------------------------------------------------------------- +;-----------------------------------------------------------------; +; ; +; TCP_init: Resets all TCP variables. ; +; ; +;-----------------------------------------------------------------; macro TCP_init { xor eax, eax @@ -246,19 +244,17 @@ include 'tcp_input.inc' include 'tcp_output.inc' -;--------------------------------------------------------------------------- -; -; TCP_API -; -; This function is called by system function 76 -; -; IN: subfunction number in bl -; device number in bh -; ecx, edx, .. depends on subfunction -; -; OUT: -; -;--------------------------------------------------------------------------- +;------------------------------------------------------------------; +; ; +; TCP_api: This function is called by system function 76 ; +; ; +; IN: bl = subfunction number ; +; bh = device number ; +; ecx, edx, .. depends on subfunction ; +; ; +; OUT: depends on subfunction ; +; ; +;------------------------------------------------------------------; align 4 TCP_api: diff --git a/kernel/branches/Kolibri-acpi/network/tcp_input.inc b/kernel/branches/Kolibri-acpi/network/tcp_input.inc index 2c554c5eba..0fc0e57155 100644 --- a/kernel/branches/Kolibri-acpi/network/tcp_input.inc +++ b/kernel/branches/Kolibri-acpi/network/tcp_input.inc @@ -14,36 +14,35 @@ ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -$Revision: 5522 $ - -;----------------------------------------------------------------- -; -; TCP_input: -; -; Add a segment to the incoming TCP queue -; -; IN: [esp] = ptr to buffer -; ebx = ptr to device struct -; ecx = segment size -; esi = ptr to TCP segment -; edi = ptr to ipv4 source address, followed by ipv4 dest address -; -; OUT: / -; -;----------------------------------------------------------------- +$Revision: 5976 $ +;-----------------------------------------------------------------; +; ; +; TCP_input: Add a segment to the incoming TCP queue. ; +; ; +; IN: [esp] = ptr to buffer ; +; ebx = ptr to device struct ; +; ecx = TCP segment size ; +; edx = ptr to IPv4 header ; +; esi = ptr to TCP segment ; +; edi = interface number*4 ; +; ; +; OUT: / ; +; ; +;-----------------------------------------------------------------; align 4 TCP_input: ; record the current time push [timer_ticks] ; in 1/100 seconds - push ebx ecx esi edi ; mind the order (see TCP_queue_entry struct) + push ebx ecx esi edx ; mind the order (see TCP_queue_entry struct) mov esi, esp + push edi add_to_queue TCP_queue, TCP_QUEUE_SIZE, sizeof.TCP_queue_entry, .fail + pop edi add esp, sizeof.TCP_queue_entry - call NET_ptr_to_num4 inc [TCP_segments_rx + edi] xor edx, edx @@ -55,12 +54,13 @@ TCP_input: ret .fail: + pop edi DEBUGF DEBUG_NETWORK_VERBOSE, "TCP incoming queue is full, discarding packet!\n" call NET_ptr_to_num4 inc [TCP_segments_missed + edi] - add esp, sizeof.TCP_queue_entry - 8 + add esp, sizeof.TCP_queue_entry - 4 call NET_BUFF_free ret @@ -94,7 +94,7 @@ endl mov ebx, [esi + TCP_queue_entry.device_ptr] mov ecx, [esi + TCP_queue_entry.segment_size] - mov edi, [esi + TCP_queue_entry.ip_ptr] ; ptr to ipv4 source address, followed by ipv4 destination address + mov edi, [esi + TCP_queue_entry.ip_ptr] ; ptr to ipv4 header mov esi, [esi + TCP_queue_entry.segment_ptr] ; change esi last DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: size=%u time=%d\n", ecx, [timer_ticks] @@ -111,8 +111,8 @@ endl push ecx esi pushw [esi + TCP_header.Checksum] mov [esi + TCP_header.Checksum], 0 - TCP_checksum (edi), (edi+4) - pop cx ; previous checksum + TCP_checksum (edi+IPv4_header.SourceAddress), (edi+IPv4_header.DestinationAddress) + pop cx ; previous checksum cmp cx, dx pop edx ecx jne .drop_no_socket @@ -170,7 +170,7 @@ endl jne .socket_loop mov eax, [ebx + IP_SOCKET.RemoteIP] - cmp eax, [edi] ; Ipv4 source address + cmp eax, [edi + IPv4_header.SourceAddress] je @f test eax, eax jnz .socket_loop @@ -233,7 +233,7 @@ endl call mutex_unlock popa - push ecx edx esi edi ;;; + push ecx edx esi edi call SOCKET_fork pop edi esi edx ecx @@ -244,7 +244,7 @@ endl mov [temp_bits], TCP_BIT_DROPSOCKET - push dword [edi + 4] ; Ipv4 destination addres + push [edi + IPv4_header.DestinationAddress] pop [ebx + IP_SOCKET.LocalIP] push [edx + TCP_header.DestinationPort] @@ -485,8 +485,8 @@ endl inc eax call TCP_xmit_timer jmp .rtt_done - .no_timestamp_rtt: + cmp [ebx + TCP_SOCKET.t_rtt], 0 je .rtt_done mov eax, [edx + TCP_header.AckNumber] @@ -494,7 +494,6 @@ endl jbe .rtt_done mov eax, [ebx + TCP_SOCKET.t_rtt] call TCP_xmit_timer - .rtt_done: ; update window pointers @@ -1211,7 +1210,7 @@ align 4 ;;; TODO: check if it's a broadcast or multicast, and drop if so - push dword [edi] ; Ipv4 source addres + push [edi + IPv4_header.SourceAddress] pop [ebx + IP_SOCKET.RemoteIP] push [edx + TCP_header.SourcePort] @@ -1673,11 +1672,13 @@ align 4 .respond_seg_ack: mov cl, TH_RST + xor ebx, ebx ; FIXME: find a way to get the receiving device ptr call TCP_respond_segment jmp .drop_no_socket .respond_seg_syn: mov cl, TH_RST + TH_ACK + xor ebx, ebx ; FIXME: find a way to get the receiving device ptr call TCP_respond_segment jmp .drop_no_socket diff --git a/kernel/branches/Kolibri-acpi/network/tcp_output.inc b/kernel/branches/Kolibri-acpi/network/tcp_output.inc index 346b0420dd..1025504a0f 100644 --- a/kernel/branches/Kolibri-acpi/network/tcp_output.inc +++ b/kernel/branches/Kolibri-acpi/network/tcp_output.inc @@ -16,14 +16,15 @@ $Revision: 5584 $ -;----------------------------------------------------------------- -; -; TCP_output -; -; IN: eax = socket pointer -; OUT: eax = 0 on success/errorcode -; -;----------------------------------------------------------------- +;-----------------------------------------------------------------; +; ; +; TCP_output ; +; ; +; IN: eax = socket pointer ; +; ; +; OUT: eax = 0 on success/errorcode ; +; ; +;-----------------------------------------------------------------; align 4 proc TCP_output @@ -503,10 +504,11 @@ endl ; Create the IP packet mov ecx, esi - mov edx, [eax + IP_SOCKET.LocalIP] ; source ip mov ebx, [eax + IP_SOCKET.device] - mov eax, [eax + IP_SOCKET.RemoteIP] ; dest ip - mov di, IP_PROTO_TCP shl 8 + 128 + mov edx, [eax + IP_SOCKET.LocalIP] ; source ip + mov edi, [eax + IP_SOCKET.RemoteIP] ; dest ip + mov al, [eax + IP_SOCKET.ttl] + mov ah, IP_PROTO_TCP call IPv4_output jz .ip_error diff --git a/kernel/branches/Kolibri-acpi/network/tcp_subr.inc b/kernel/branches/Kolibri-acpi/network/tcp_subr.inc index f082c513de..cf843e125e 100644 --- a/kernel/branches/Kolibri-acpi/network/tcp_subr.inc +++ b/kernel/branches/Kolibri-acpi/network/tcp_subr.inc @@ -104,18 +104,17 @@ macro TCP_init_socket socket { } -;--------------------------- -; -; TCP_pull_out_of_band -; -; IN: eax = -; ebx = socket ptr -; edx = tcp packet ptr -; -; OUT: / -; -;--------------------------- - +;-----------------------------------------------------------------; +; ; +; TCP_pull_out_of_band ; +; ; +; IN: eax = ? ; +; ebx = socket ptr ; +; edx = tcp packet ptr ; +; ; +; OUT: / ; +; ; +;-----------------------------------------------------------------; align 4 TCP_pull_out_of_band: @@ -127,21 +126,16 @@ TCP_pull_out_of_band: - - - - - -;------------------------- -; -; TCP_drop -; -; IN: eax = socket ptr -; ebx = error number -; -; OUT: eax = socket ptr -; -;------------------------- +;-----------------------------------------------------------------; +; ; +; TCP_drop ; +; ; +; IN: eax = socket ptr ; +; ebx = error number ; +; ; +; OUT: eax = socket ptr ; +; ; +;-----------------------------------------------------------------; align 4 TCP_drop: ; FIXME CHECKME TODO @@ -171,14 +165,15 @@ TCP_drop: ; FIXME CHECKME TODO -;------------------------- -; -; TCP_disconnect -; -; IN: eax = socket ptr -; OUT: eax = socket ptr / 0 -; -;------------------------- +;-----------------------------------------------------------------; +; ; +; TCP_disconnect ; +; ; +; IN: eax = socket ptr ; +; ; +; OUT: eax = socket ptr / 0 ; +; ; +;-----------------------------------------------------------------; align 4 TCP_disconnect: @@ -198,18 +193,18 @@ TCP_disconnect: call TCP_output pop eax @@: - ret -;------------------------- -; -; TCP_close -; -; IN: eax = socket ptr -; OUT: / -; -;------------------------- +;-----------------------------------------------------------------; +; ; +; TCP_close ; +; ; +; IN: eax = socket ptr ; +; ; +; OUT: / ; +; ; +;-----------------------------------------------------------------; align 4 TCP_close: @@ -222,21 +217,19 @@ TCP_close: call SOCKET_free xor eax, eax - ret - -;------------------------- -; -; TCP_outflags -; -; IN: eax = socket ptr -; -; OUT: edx = flags -; -;------------------------- +;-----------------------------------------------------------------; +; ; +; TCP_outflags ; +; ; +; IN: eax = socket ptr ; +; ; +; OUT: edx = flags ; +; ; +;-----------------------------------------------------------------; align 4 TCP_outflags: @@ -266,16 +259,16 @@ TCP_outflags: -;--------------------------------------- -; -; The fast way to send an ACK/RST/keepalive segment -; -; TCP_respond -; -; IN: ebx = socket ptr -; cl = flags -; -;-------------------------------------- +;-----------------------------------------------------------------; +; ; +; TCP_respond: Fast way to send an ACK/RST/keepalive segment. ; +; ; +; IN: ebx = socket ptr ; +; cl = flags ; +; ; +; OUT: / ; +; ; +;-----------------------------------------------------------------; align 4 TCP_respond: @@ -285,11 +278,12 @@ TCP_respond: ; Create the IP packet push cx ebx - mov eax, [ebx + IP_SOCKET.RemoteIP] mov edx, [ebx + IP_SOCKET.LocalIP] - mov ebx, [ebx + IP_SOCKET.device] + mov edi, [ebx + IP_SOCKET.RemoteIP] + mov al, [ebx + IP_SOCKET.ttl] + mov ah, IP_PROTO_TCP mov ecx, sizeof.TCP_header - mov di, IP_PROTO_TCP shl 8 + 128 + mov ebx, [ebx + IP_SOCKET.device] call IPv4_output jz .error pop esi cx @@ -347,33 +341,31 @@ TCP_respond: ret - - - - - - -;------------------------- -; TCP_respond_segment: -; -; IN: edx = segment ptr (a previously received segment) -; edi = ptr to dest and src IPv4 addresses -; cl = flags - +;-----------------------------------------------------------------; +; ; +; TCP_respond_segment ; +; ; +; IN: ebx = device ptr ; +; edx = segment ptr (a previously received segment) ; +; edi = ptr to IPv4 header ; +; cl = flags ; +; ; +; OUT: / ; +; ; +;-----------------------------------------------------------------; align 4 TCP_respond_segment: - DEBUGF DEBUG_NETWORK_VERBOSE,"TCP_respond_segment: frame=%x flags=%x\n", edx, cl + DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_respond_segment: frame=%x flags=%x\n", edx, cl ;--------------------- ; Create the IP packet push cx edx - mov edx, [edi + 4] - mov eax, [edi] + mov edx, [edi + IPv4_header.DestinationAddress] + mov edi, [edi + IPv4_header.SourceAddress] mov ecx, sizeof.TCP_header - mov di, IP_PROTO_TCP shl 8 + 128 - xor ebx, ebx ;;; fixme + mov ax, IP_PROTO_TCP shl 8 + 128 call IPv4_output jz .error pop esi cx @@ -454,7 +446,11 @@ local .done .done: } - +;-----------------------------------------------------------------; +; ; +; TCP_set_persist ; +; ; +;-----------------------------------------------------------------; align 4 TCP_set_persist: @@ -491,13 +487,20 @@ TCP_set_persist: -; eax = rtt -; ebx = socket ptr - +;-----------------------------------------------------------------; +; ; +; TCP_xmit_timer: Calculate new smoothed RTT. ; +; ; +; IN: eax = rtt ; +; ebx = socket ptr ; +; ; +; OUT: / ; +; ; +;-----------------------------------------------------------------; align 4 TCP_xmit_timer: - DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_xmit_timer: socket=%x rtt=%d0ms\n", ebx, eax + DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_xmit_timer: socket=0x%x rtt=%d0ms\n", ebx, eax ;TODO: update stats @@ -546,7 +549,6 @@ TCP_xmit_timer: .no_rtt_yet: - push ecx mov ecx, eax shl ecx, TCP_RTT_SHIFT @@ -559,14 +561,20 @@ TCP_xmit_timer: ret - - -; eax = max segment size -; ebx = socket ptr +;-----------------------------------------------------------------; +; ; +; TCP_mss: Update maximum segment size ; +; ; +; IN: eax = max segment size ; +; ebx = socket ptr ; +; ; +; OUT: / ; +; ; +;-----------------------------------------------------------------; align 4 TCP_mss: - cmp eax, 1420 ; FIXME + cmp eax, 1420 ; FIXME jbe @f mov eax, 1420 @@: @@ -577,13 +585,20 @@ TCP_mss: - -; ebx = socket ptr -; edx = segment ptr +;-----------------------------------------------------------------; +; ; +; TCP_reassemble ; +; ; +; IN: ebx = socket ptr ; +; edx = segment ptr ; +; ; +; OUT: / ; +; ; +;-----------------------------------------------------------------; align 4 TCP_reassemble: - + ;;;;; TODO ret diff --git a/kernel/branches/Kolibri-acpi/network/tcp_timer.inc b/kernel/branches/Kolibri-acpi/network/tcp_timer.inc index 3fee78754e..f90f32279b 100644 --- a/kernel/branches/Kolibri-acpi/network/tcp_timer.inc +++ b/kernel/branches/Kolibri-acpi/network/tcp_timer.inc @@ -23,9 +23,6 @@ timer_flag_persist = 1 shl 3 timer_flag_wait = 1 shl 4 -;---------------------- -; 160 ms timer -;---------------------- macro TCP_timer_160ms { local .loop @@ -150,9 +147,9 @@ proc TCP_timer_640ms ; TODO: implement timed wait timer! .check_more5: dec [eax + TCP_SOCKET.timer_persist] - jnz .loop + jnz .check_more6 test [eax + TCP_SOCKET.timer_flags], timer_flag_persist - jz .loop + jz .check_more6 DEBUGF DEBUG_NETWORK_VERBOSE, "socket %x: persist timer expired\n", eax @@ -163,14 +160,33 @@ proc TCP_timer_640ms ; TODO: implement timed wait timer! pop eax mov [eax + TCP_SOCKET.t_force], 0 - jmp .loop + .check_more6: + dec [eax + TCP_SOCKET.timer_timed_wait] + jnz .loop + test [eax + TCP_SOCKET.timer_flags], timer_flag_wait + jz .loop + + DEBUGF DEBUG_NETWORK_VERBOSE, "socket %x: timed wait timer expired\n", eax + + push [eax + SOCKET.NextPtr] + call TCP_close + pop eax + + jmp .check_only endp - -; eax = socket - +;-----------------------------------------------------------------; +; ; +; TCP_cancel_timers ; +; ; +; IN: eax = socket ; +; ; +; OUT: / ; +; ; +;-----------------------------------------------------------------; +align 4 TCP_cancel_timers: mov [eax + TCP_SOCKET.timer_flags], 0 diff --git a/kernel/branches/Kolibri-acpi/network/tcp_usreq.inc b/kernel/branches/Kolibri-acpi/network/tcp_usreq.inc index 3bc533da2c..efc06ac3fb 100644 --- a/kernel/branches/Kolibri-acpi/network/tcp_usreq.inc +++ b/kernel/branches/Kolibri-acpi/network/tcp_usreq.inc @@ -17,15 +17,15 @@ $Revision: 5442 $ -;------------------------- -; -; TCP_usrclose -; -; Move connection to next state, based on process close. -; -; IN: eax = socket ptr -; -;------------------------- +;-----------------------------------------------------------------; +; ; +; TCP_usrclosed ; +; ; +; IN: eax = socket ptr ; +; ; +; OUT: / ; +; ; +;-----------------------------------------------------------------; align 4 TCP_usrclosed: @@ -37,7 +37,6 @@ TCP_usrclosed: jmp ebx .switch: - dd .close ; TCPS_CLOSED dd .close ; TCPS_LISTEN dd .close ; TCPS_SYN_SENT @@ -50,7 +49,6 @@ TCP_usrclosed: dd .disc ; TCPS_FIN_WAIT_2 dd .disc ; TCPS_TIMED_WAIT - .close: mov [eax + TCP_SOCKET.t_state], TCPS_CLOSED call TCP_close @@ -74,15 +72,17 @@ TCP_usrclosed: ret -;------------------------- -; -; TCP_connect -; -; IN: eax = socket ptr -; OUT: eax = 0 ok / -1 error -; ebx = error code -; -;------------------------- +;-----------------------------------------------------------------; +; ; +; TCP_connect ; +; ; +; IN: eax = socket ptr ; +; ; +; OUT: eax = 0 on success ; +; eax = -1 on error ; +; ebx = error code on error ; +; ; +;-----------------------------------------------------------------; align 4 TCP_connect: diff --git a/kernel/branches/Kolibri-acpi/network/udp.inc b/kernel/branches/Kolibri-acpi/network/udp.inc index 89df807f18..593dc4ee7c 100644 --- a/kernel/branches/Kolibri-acpi/network/udp.inc +++ b/kernel/branches/Kolibri-acpi/network/udp.inc @@ -36,13 +36,11 @@ align 4 endg -;----------------------------------------------------------------- -; -; UDP_init -; -; This function resets all UDP variables -; -;----------------------------------------------------------------- +;-----------------------------------------------------------------; +; ; +; UDP_init: This function resets all UDP variables ; +; ; +;-----------------------------------------------------------------; macro UDP_init { xor eax, eax @@ -57,15 +55,15 @@ macro UDP_checksum IP1, IP2 { ; esi = ptr to udp packet, ecx = packet size ; Pseudoheader mov edx, IP_PROTO_UDP - add dl, [IP1+1] - adc dh, [IP1+0] - adc dl, [IP1+3] - adc dh, [IP1+2] + add dl, byte[IP1+1] + adc dh, byte[IP1+0] + adc dl, byte[IP1+3] + adc dh, byte[IP1+2] - adc dl, [IP2+1] - adc dh, [IP2+0] - adc dl, [IP2+3] - adc dh, [IP2+2] + adc dl, byte[IP2+1] + adc dh, byte[IP2+0] + adc dl, byte[IP2+3] + adc dh, byte[IP2+2] adc dl, cl ; byte[esi+UDP_header.Length+1] adc dh, ch ; byte[esi+UDP_header.Length+0] @@ -98,23 +96,20 @@ macro UDP_checksum IP1, IP2 { ; esi = ptr to udp packet, ecx = packet size } -;----------------------------------------------------------------- -; -; UDP_input: -; -; Called by IPv4_input, -; this procedure will inject the udp data diagrams in the application sockets. -; -; IN: [esp] = Pointer to buffer -; [esp+4] = size of buffer -; ebx = ptr to device struct -; ecx = UDP Packet size -; esi = ptr to UDP header -; edi = ptr to ipv4 source and dest address -; -; OUT: / -; -;----------------------------------------------------------------- +;-----------------------------------------------------------------; +; ; +; UDP_input: Inject the UDP data in the application sockets. ; +; ; +; IN: [esp] = ptr to buffer ; +; ebx = ptr to device struct ; +; ecx = UDP packet size ; +; edx = ptr to IPv4 header ; +; esi = ptr to UDP packet data ; +; edi = interface number*4 ; +; ; +; OUT: / ; +; ; +;-----------------------------------------------------------------; align 4 UDP_input: @@ -127,7 +122,8 @@ UDP_input: ; otherwise, we will re-calculate the checksum and add it to this value, thus creating 0 when it is correct - UDP_checksum (edi), (edi+4) + mov eax, edx + UDP_checksum (eax+IPv4_header.SourceAddress), (eax+IPv4_header.DestinationAddress) jnz .checksum_mismatch .no_checksum: @@ -148,9 +144,7 @@ UDP_input: mov cx, [esi + UDP_header.SourcePort] mov dx, [esi + UDP_header.DestinationPort] - mov edi, [edi + 4] ; ipv4 source address mov eax, net_sockets - .next_socket: mov eax, [eax + SOCKET.NextPtr] or eax, eax @@ -172,15 +166,15 @@ UDP_input: call mutex_unlock popa - ;;; TODO: when packet is processed, check more sockets! + ;;; TODO: when packet is processed, check more sockets?! +; FIXME: check remote IP if possible +; ; cmp [eax + IP_SOCKET.RemoteIP], 0xffffffff ; je @f -; cmp [eax + IP_SOCKET.RemoteIP], edi +; cmp [eax + IP_SOCKET.RemoteIP], ; jne .next_socket ; @@: -; -; FIXME: UDP should check remote IP, but not under all circumstances! cmp [eax + UDP_SOCKET.RemotePort], 0 je .updateport @@ -194,7 +188,6 @@ UDP_input: popa .updatesock: - call NET_ptr_to_num4 inc [UDP_PACKETS_RX + edi] movzx ecx, [esi + UDP_header.Length] @@ -232,17 +225,17 @@ UDP_input: -;----------------------------------------------------------------- -; -; UDP_output -; -; IN: eax = socket pointer -; ecx = number of bytes to send -; esi = pointer to data -; -; OUT: eax = -1 on error -; -;----------------------------------------------------------------- +;-----------------------------------------------------------------; +; ; +; UDP_output: Create an UDP packet. ; +; ; +; IN: eax = socket pointer ; +; ecx = number of bytes to send ; +; esi = pointer to data ; +; ; +; OUT: eax = -1 on error ; +; ; +;-----------------------------------------------------------------; align 4 UDP_output: @@ -257,10 +250,11 @@ UDP_output: sub esp, 4 ; Data ptr will be placed here push edx esi - mov edx, [eax + IP_SOCKET.LocalIP] mov ebx, [eax + IP_SOCKET.device] - mov eax, [eax + IP_SOCKET.RemoteIP] - mov di, IP_PROTO_UDP shl 8 + 128 + mov edx, [eax + IP_SOCKET.LocalIP] + mov edi, [eax + IP_SOCKET.RemoteIP] + mov al, [eax + IP_SOCKET.ttl] + mov ah, IP_PROTO_UDP add ecx, sizeof.UDP_header call IPv4_output jz .fail @@ -306,15 +300,17 @@ UDP_output: -;----------------------------------------------------------------- -; -; UDP_connect -; -; IN: eax = socket pointer -; OUT: eax = 0 ok / -1 error -; ebx = error code -; -;------------------------- +;-----------------------------------------------------------------; +; ; +; UDP_connect ; +; ; +; IN: eax = socket pointer ; +; ; +; OUT: eax = 0 on success ; +; eax = -1 on error ; +; ebx = error code on error ; +; ; +;-----------------------------------------------------------------; align 4 UDP_connect: @@ -347,10 +343,6 @@ UDP_connect: call SOCKET_find_port @@: - push eax - init_queue (eax + SOCKET_QUEUE_LOCATION) ; Set up data receiving queue - pop eax - push eax lea ecx, [eax + SOCKET.mutex] call mutex_unlock @@ -362,14 +354,15 @@ UDP_connect: ret -;----------------------------------------------------------------- -; -; UDP_disconnect -; -; IN: eax = socket pointer -; OUT: eax = socket pointer -; -;------------------------- +;-----------------------------------------------------------------; +; ; +; UDP_disconnect ; +; ; +; IN: eax = socket pointer ; +; ; +; OUT: eax = socket pointer ; +; ; +;-----------------------------------------------------------------; align 4 UDP_disconnect: @@ -383,20 +376,17 @@ UDP_disconnect: -;--------------------------------------------------------------------------- -; -; UDP_API -; -; This function is called by system function 75 -; -; IN: subfunction number in bl -; device number in bh -; ecx, edx, .. depends on subfunction -; -; OUT: -; -;--------------------------------------------------------------------------- - +;-----------------------------------------------------------------; +; ; +; UDP_api: This function is called by system function 76 ; +; ; +; IN: bl = subfunction number in bl ; +; bh = device number in bh ; +; ecx, edx, .. depends on subfunction ; +; ; +; OUT: depends on subfunction ; +; ; +;-----------------------------------------------------------------; align 4 UDP_api: