/kernel/branches/Kolibri-acpi/blkdev/hd_drv.inc |
---|
10,15 → 10,16 |
; 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 ide_callbacks.end - ide_callbacks |
dd 0 ; no close function |
dd 0 ; no closemedia function |
dd ide_querymedia |
28,18 → 29,18 |
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 |
74,7 → 75,6 |
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 |
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 |
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 |
mov [channel_lock], ecx |
call mutex_lock |
; prepare worker procedures variables |
mov esi, [buffer] |
mov edi, esi |
mov ecx, [hd_data] |
mov eax, [ecx+HD_DATA.hdbase] |
movzx eax, [ecx+HD_DATA.hdbase] |
mov [hdbase], eax |
mov eax, [ecx+HD_DATA.hdid] |
mov ax, [ecx+HD_DATA.hdid] |
mov [hdid], eax |
mov eax, [ecx+HD_DATA.hdpos] |
mov [hdpos], 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 |
mov esi, [buffer] |
mov edi, esi |
mov bl, [operation] |
mov ecx, [hdpos] |
movzx ecx, [ecx+HD_DATA.hdpos] |
mov [hdpos], ecx |
dec ecx |
shr ecx, 2 |
imul ecx, sizeof.IDE_DATA |
134,7 → 133,7 |
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 |
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 |
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 |
cld |
mov ecx, 256 |
mov edx, [hdbase] |
cmp bl, 34h |
jz .write |
cmp bl, 30h |
jnc .write |
rep insw |
jmp @f |
.write: |
/kernel/branches/Kolibri-acpi/boot/bootcode.inc |
---|
176,9 → 176,9 |
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 |
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 |
/kernel/branches/Kolibri-acpi/build.bat |
---|
51,7 → 51,6 |
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 |
:Error_FasmFailed |
echo error: fasm execution failed |
erase lang.inc >nul 2>&1 |
echo. |
pause |
exit 1 |
/kernel/branches/Kolibri-acpi/const.inc |
---|
544,6 → 544,10 |
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 |
550,7 → 554,7 |
cl_workarea dd ? |
cl_titlebar dd ? |
cl_frames dd ? |
reserved db ? |
z_modif db ? |
fl_wstate db ? |
fl_wdrawn db ? |
fl_redraw db ? |
/kernel/branches/Kolibri-acpi/core/apic.inc |
---|
447,6 → 447,7 |
jz .old_tics |
push ebx |
push esi |
pushfd |
cli |
456,15 → 457,24 |
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 |
/kernel/branches/Kolibri-acpi/core/sched.inc |
---|
285,7 → 285,7 |
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] |
/kernel/branches/Kolibri-acpi/core/sys32.inc |
---|
581,7 → 581,7 |
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 |
/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 |
mov [DeviceNumber], 0 |
cmp ecx, IDE_controller_1 |
jz .find |
add bl, 5 |
add [DeviceNumber], sizeof.HD_DATA*4 |
cmp ecx, IDE_controller_2 |
jne @f |
jz .find |
add bl, 5 |
jmp .find |
@@: |
cmp ecx, IDE_controller_3 |
jne .find |
add bl, 10 |
;-------------------------------------- |
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] |
dec [DiskNumber] |
call FindHDD_2 |
mov [DiskNumber], 0 |
inc [DiskNumber] |
call FindHDD_2 |
mov [DiskNumber], 1 |
call FindHDD_1 |
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 |
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 |
ChannelNumber dw ? |
; Номер диска |
DiskNumber db ? |
DeviceNumber db ? |
; Базовый адрес группы портов контроллера ATA |
ATABasePortAddr dw ? |
; Параметры ATA-команды |
/kernel/branches/Kolibri-acpi/detect/sear_par.inc |
---|
13,27 → 13,27 |
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. |
/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 - пауза. ========================= |
====================================================================== |
244,38 → 246,6 |
функции 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 |
Возвращаемое значение: |
* функция не возвращает значения |
------------- Подподфункция 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,22 → 1016,26 |
* бит 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 ===================== |
============= Получить информацию об оперативной памяти. ============= |
1146,6 → 1122,37 |
видеорежима, иначе функция ничего не изменит. |
====================================================================== |
===================== Функция 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. ==================== |
====================================================================== |
1460,6 → 1467,22 |
* Системное время можно получить функцией 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,19 → 1642,42 |
и всё равно содержит относительную 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 - загрузить курсор ------------------- |
Параметры: |
* eax = 37 - номер функции |
2086,6 → 2132,40 |
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 |
Возвращаемое значение: |
* функция не возвращает значения |
Замечания: |
* Строка заголовка должна быть в формате ASCIIZ. В заголовке |
отображается не более 255 символов независимо от полной длины |
строки. |
* Строка заголовка должна заканчиваться нулём. |
* Можно указать кодировку заголовка, |
поместив в начале строки байт со значениями: |
1 = cp866 |
2 = UTF-16LE |
3 = UTF-8 |
иначе будет использоваться cp866. |
* Чтобы убрать заголовок, передайте NULL в ecx. |
====================================================================== |
3917,6 → 4001,76 |
* 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 (Открыть сокет). ======= |
====================================================================== |
Параметры: |
/kernel/branches/Kolibri-acpi/docs/sysfuncs.txt |
---|
192,40 → 192,38 |
* 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. ======================== |
243,38 → 241,6 |
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. =============== |
====================================================================== |
Paramters: |
1004,20 → 970,22 |
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,23 → 1012,26 |
* 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. ======= |
====================================================================== |
1149,6 → 1120,37 |
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. =================== |
====================================================================== |
1454,6 → 1456,20 |
* 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 ==================== |
========== Find out whether low-level HD access is enabled. ========== |
====================================================================== |
1611,19 → 1627,42 |
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: |
* eax = 37 - function number |
2074,6 → 2113,40 |
'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). =========== |
====================================================================== |
Parameters: |
3056,7 → 3129,7 |
FPU and/or SSE. |
====================================================================== |
====== Function 68, subfunction 25 - set FPU exception handler. ====== |
======== Function 68, subfunction 25 - set exception activity ======== |
====================================================================== |
Parameters: |
* eax = 68 - function number |
3772,12 → 3845,16 |
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 |
* 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 |
* bl = 0 - subfunction number |
* bh = device number |
Returned value: |
* eax = device type |
* eax = device type number |
====================================================================== |
======== Function 74, Subfunction 1, Get network device name. ======== |
3885,6 → 3962,78 |
* 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. ============== |
====================================================================== |
Parameters: |
4000,7 → 4149,8 |
* ebx = errorcode |
Remarks: |
Optstruct: dd level |
Optstruct: |
dd level |
dd optionname |
dd optlength |
db options... |
4018,7 → 4168,8 |
* ebx = errorcode |
Remarks: |
Optstruct: dd level |
Optstruct: |
dd level |
dd optionname |
dd optlength |
db options... |
4034,6 → 4185,53 |
* 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 =============== |
====================================================================== |
Parameters: |
/kernel/branches/Kolibri-acpi/fs/fat.inc |
---|
1843,6 → 1843,9 |
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 |
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 |
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 |
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 |
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 |
/kernel/branches/Kolibri-acpi/fs/ntfs.inc |
---|
7,33 → 7,113 |
$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 |
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 ? |
mftmirr_cluster dd ? |
frs_size dd ? ; FRS size in bytes |
iab_size dd ? ; IndexAllocationBuffer size in bytes |
frs_buffer dd ? |
iab_buffer 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 ? |
cur_index_buf 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_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 ? ; [output] |
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 ? |
rb 3 |
ntfsNotFound db ? |
ntfsFolder db ? |
ntfsFragmentCount db ? |
cur_subnode_size dd ? |
ntfs_attr_iRecord dd ? |
48,14 → 128,21 |
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 |
68,7 → 155,7 |
ntfs_test_bootsec: |
; in: ebx->buffer, edx=size of partition |
; out: CF set <=> invalid |
; out: CF=1 -> invalid |
; 1. Name=='NTFS ' |
cmp dword [ebx+3], 'NTFS' |
jnz .no |
121,7 → 208,7 |
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 |
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 |
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,7 → 253,7 |
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 |
176,9 → 260,8 |
.nope: |
xor eax, eax |
jmp .exit |
; By given bootsector, initialize some NTFS variables |
.ntfs_setup: |
; By given bootsector, initialize some NTFS variables |
movi eax, sizeof.NTFS |
call malloc |
test eax, eax |
194,12 → 277,11 |
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 |
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 |
.1: |
jmp .1 |
@@: |
neg eax |
mov ecx, eax |
mov eax, 1 |
shl eax, cl |
.2: |
.1: |
mov [ebp+NTFS.frs_size], eax |
movsx eax, byte [ebx+0x44] |
stdcall kernel_alloc, eax |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
937,8 → 1065,8 |
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 |
; 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] |
1080,9 → 1208,11 |
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 |
@@: |
; 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 |
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 |
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 |
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 |
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 |
popad |
xor ebx, ebx |
.eof: |
movi eax, ERROR_END_OF_FILE |
push eax |
push ERROR_END_OF_FILE |
call ntfs_unlock |
pop eax |
ret |
1392,12 → 1515,6 |
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 |
mov eax, 5 ; root cluster |
1458,12 → 1575,10 |
@@: |
; 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 |
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 |
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 |
1860,30 → 1973,698 |
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 |
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 - 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 |
;---------------------------------------------------------------- |
ntfs_Write: |
xor ebx, ebx |
mov eax, ERROR_UNSUPPORTED_FS |
ret |
;---------------------------------------------------------------- |
ntfs_SetFileEnd: |
ntfs_SetFileInfo: |
ntfs_Delete: |
1891,12 → 2672,6 |
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 |
jnz @f |
1907,14 → 2682,11 |
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 |
xor eax, eax |
ret |
ntfsError: |
call ntfs_unlock |
xor ebx, ebx |
pop eax |
ret |
/kernel/branches/Kolibri-acpi/gui/char2_et.mt |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Deleted: svn:mime-type |
-application/octet-stream |
\ No newline at end of property |
/kernel/branches/Kolibri-acpi/gui/char2.mt |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Deleted: svn:mime-type |
-application/octet-stream |
\ No newline at end of property |
/kernel/branches/Kolibri-acpi/gui/char2_sp.mt |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Deleted: svn:mime-type |
-application/octet-stream |
\ No newline at end of property |
/kernel/branches/Kolibri-acpi/gui/char.mt |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/kernel/branches/Kolibri-acpi/gui/charUni.mt |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/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: |
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 |
.ret: |
add esp, 28 |
ret |
.redirect: |
mov ebp, [edi] |
add edi, 8 |
@@: |
shl ebp, 2 |
imul eax, ebp |
shl ebx, 2 |
add eax, ebx |
js .ret |
add edi, eax |
mov eax, ecx |
mov ebx, ecx |
test ecx, ecx |
js .test_asciiz |
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 |
dec esi |
js .end |
; ebp = font color |
; esi -> string |
; edi -> buffer |
jmp @f |
;-------------------------------------- |
align 4 |
.test_asciiz: |
cmp byte [edx], 0 |
jz .end |
; 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 |
cmp byte [esp+28], 1 |
jne @f |
.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 |
dec esi |
js .end |
;-------------------------------------- |
align 4 |
.drawUTF8: |
dec dword [esp] |
js .done |
@@: |
inc edx |
pushad |
movzx edx, byte [edx-1] |
test ecx, 0x10000000 |
jnz .font2 |
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 |
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 |
.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 |
jnc .nopix |
.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 |
test ecx, 0x08000000 ; redirect the output to the user area |
jz @f |
.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 |
@@: ; 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 |
call draw_text_to_user_area |
jmp .pixloop1cont |
;-------------------------------------- |
align 4 |
; 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 |
@@: |
and ecx, 0xFBFFFFFF ;negate 0x04000000 save to mouseunder area |
; call [putpixel] |
call __sys_putpixel |
jmp .pixloop1cont |
;-------------------------------------- |
align 4 |
.nopix: |
test ecx, 0x40000000 |
jz .pixloop1cont |
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 |
push ecx |
mov ecx, [esp+4+20h+20h] |
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 |
test ecx, 0x08000000 ; redirect the output to the user area |
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 |
call draw_text_to_user_area |
pop ecx |
jmp .pixloop1cont |
;-------------------------------------- |
align 4 |
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 |
@@: |
and ecx, 0xFBFFFFFF ;negate 0x04000000 save to mouseunder area |
; call [putpixel] |
call __sys_putpixel |
pop ecx |
;-------------------------------------- |
align 4 |
.pixloop1cont: |
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 |
jmp .pixloop1 |
;-------------------------------------- |
align 4 |
.pixloop1end: |
sub eax, 6 |
inc ebx |
inc ebp |
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 |
jnz .symloop1 |
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 |
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 |
.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 |
test ecx, 0x08000000 ; redirect the output to the user area |
jz @f |
@@: |
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 |
call draw_text_to_user_area |
jmp .pixloop2cont |
;-------------------------------------- |
align 4 |
.upRightHigh: |
imul ecx, esi |
shl ecx, 2 |
add edi, ecx |
add edi, 4 |
mov ecx, esi |
dec ecx |
dec ecx |
.drawUpRightHigh: |
mov eax, ecx |
@@: |
and ecx, 0xFBFFFFFF ;negate 0x04000000 save to mouseunder area |
; call [putpixel] |
call __sys_putpixel |
jmp .pixloop2cont |
;-------------------------------------- |
align 4 |
.nopix2: |
test ecx, 0x40000000 |
jz .pixloop2cont |
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 |
push ecx |
mov ecx, [esp+12+20h+20h] |
@@: |
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 |
test ecx, 0x08000000 ; redirect the output to the user area |
jz @f |
.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 |
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: |
bt [ebx+1], eax |
jc .nextPixel |
inc eax |
dec esi |
jnz .pixloop2 |
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 |
pop esi |
sub eax, esi |
.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 |
inc ebp |
dec dword [esp] |
jnz .symloop2 |
mov eax, [esp+16+widthX] |
imul eax, esi |
add edi, eax |
dec dword [esp+4] |
jnz drawChar |
ret |
pop eax |
add dword [esp+28], esi |
popad |
jmp .loop |
;-------------------------------------- |
align 4 |
.end: |
popad |
pop eax |
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 |
;------------------------------------------------------------------------------ |
; 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] |
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 |
ret |
;------------------------------------------------------------------------------ |
align 4 |
FONT_I: |
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 |
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' |
/kernel/branches/Kolibri-acpi/gui/mouse.inc |
---|
9,9 → 9,9 |
include 'mousepointer.inc' |
;============================================================================== |
;///// public functions /////////////////////////////////////////////////////// |
;============================================================================== |
;================================ |
;/////// public functions /////// |
;================================ |
mouse.LEFT_BUTTON_FLAG = 0001b |
mouse.RIGHT_BUTTON_FLAG = 0010b |
36,14 → 36,10 |
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 |
; 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,9 → 158,9 |
jnz mouse._.middle_button_press_handler |
jmp mouse._.middle_button_release_handler |
;============================================================================== |
;///// private functions ////////////////////////////////////////////////////// |
;============================================================================== |
;=============================== |
;////// private functions ////// |
;=============================== |
uglobal |
mouse.state: |
172,7 → 168,7 |
.buttons db ? |
; NOTE: since there's no unique and lifetime-constant button identifiers, |
; we're using two dwords to identify each of them: |
; 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 |
191,12 → 187,25 |
.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 |
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 |
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 |
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 |
.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 |
.exit: |
mouse._.right_button_release_handler: |
bts dword [BTN_DOWN], 17 |
@@: |
ret |
align 4 |
;------------------------------------------------------------------------------ |
mouse._.right_button_release_handler: ;//////////////////////////////////////// |
;------------------------------------------------------------------------------ |
;? Called when right mouse button has been released |
;------------------------------------------------------------------------------ |
mouse._.middle_button_press_handler: |
bts word [BTN_DOWN], 10 |
ret |
align 4 |
;------------------------------------------------------------------------------ |
mouse._.middle_button_press_handler: ;///////////////////////////////////////// |
;------------------------------------------------------------------------------ |
;? Called when middle mouse button has been pressed down |
;------------------------------------------------------------------------------ |
mouse._.middle_button_release_handler: |
bts dword [BTN_DOWN], 18 |
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 |
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 |
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,11 → 524,8 |
ret |
align 4 |
;------------------------------------------------------------------------------ |
mouse._.activate_sys_window_under_cursor: ;//////////////////////////////////// |
;------------------------------------------------------------------------------ |
;? <description> |
;------------------------------------------------------------------------------ |
;----------------------------------------------------------------- |
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] |
547,15 → 533,12 |
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 |
ret |
align 4 |
;------------------------------------------------------------------------------ |
mouse._.check_sys_window_actions: ;//////////////////////////////////////////// |
;------------------------------------------------------------------------------ |
;? <description> |
;------------------------------------------------------------------------------ |
;----------------------------------------------------------------- |
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,7 → 617,7 |
; 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; |
; 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 |
/kernel/branches/Kolibri-acpi/gui/window.inc |
---|
30,12 → 30,9 |
draw_limits RECT |
endg |
align 4 |
;------------------------------------------------------------------------------ |
syscall_draw_window: ;///// system function 0 ///////////////////////////////// |
;------------------------------------------------------------------------------ |
;? <description>. |
;------------------------------------------------------------------------------ |
mov eax, edx |
shr eax, 24 |
and al, 0x0f |
53,18 → 50,14 |
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] |
call __sys_draw_pointer |
jmp .exit |
;-------------------------------------- |
align 4 |
@@: |
dec al |
jnz @f |
72,11 → 65,9 |
; 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 |
call drawwindow_IV |
jmp window._.draw_window_caption.2 |
;-------------------------------------- |
align 4 |
.exit: |
ret |
;------------------------------------------------------------------------------ |
align 4 |
;------------------------------------------------------------------------------ |
syscall_display_settings: ;///// system function 48 /////////////////////////// |
;------------------------------------------------------------------------------ |
;; Redraw screen: |
134,42 → 122,44 |
;< 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 |
183,7 → 173,6 |
mov [windowtypechanged], ebx |
ret |
;------------------------------------------------------------------------------ |
align 4 |
syscall_display_settings.03: |
mov edi, ecx |
cmp edx, 192 |
195,13 → 184,11 |
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 |
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 |
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 |
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 |
;------------------------------------------------------------------------------ |
align 4 |
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 |
;------------------------------------------------------------------------------ |
syscall_display_settings._.calculate_whole_screen: |
xor eax, eax |
xor ebx, ebx |
308,7 → 291,6 |
dec edx |
jmp calculatescreen |
;------------------------------------------------------------------------------ |
align 4 |
syscall_display_settings._.redraw_whole_screen: |
xor eax, eax |
mov [draw_limits.left], eax |
322,8 → 304,6 |
mov eax, window_data |
jmp redrawscreen |
;------------------------------------------------------------------------------ |
align 4 |
;------------------------------------------------------------------------------ |
syscall_set_window_shape: ;///// system function 50 /////////////////////////// |
;------------------------------------------------------------------------------ |
;; Set window shape address: |
406,59 → 386,20 |
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 ///////////////////////////// |
;------------------------------------------------------------------------------ |
;? <description> |
;------------------------------------------------------------------------------ |
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: ;///////////////////////////////////////////////////////// |
;------------------------------------------------------------------------------ |
;? <description> |
;------------------------------------------------------------------------------ |
mov byte [window_data + 0x20 + WDATA.cl_titlebar + 3], 1 ; desktop is not movable |
push eax ecx |
xor eax, eax |
477,6 → 418,7 |
pop ecx eax |
ret |
;------------------------------------------------------------------------------ |
align 4 |
;------------------------------------------------------------------------------ |
calculatescreen: ;///////////////////////////////////////////////////////////// |
502,12 → 444,21 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
mov eax, [CURRENT_TASK] |
shl eax, 5 |
add eax, window_data |
; 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 |
; 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! Usually, he will be enraged! |
or [edi + WDATA.fl_wdrawn], 1 |
; 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! |
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 |
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,30 → 2281,17 |
;-------------------------------------- |
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 |
2337,36 → 2298,29 |
.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 ebx, 80002h |
.dodraw: |
shr eax, 3 |
mov esi, eax |
mov ebx, 0x00080007 |
add ebx, ebp |
;-------------------------------------- |
align 4 |
.dodraw: |
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 |
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 |
/kernel/branches/Kolibri-acpi/hid/keyboard.inc |
---|
25,6 → 25,8 |
VKEY_ALT = 0000000000110000b |
uglobal |
align 4 |
kb_state dd 0 |
ext_code db 0 |
keyboard_mode db 0 |
33,6 → 35,7 |
altmouseb db 0 |
ctrl_alt_del db 0 |
kb_lights db 0 |
old_kb_lights db 0 |
align 4 |
42,13 → 45,6 |
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 |
/kernel/branches/Kolibri-acpi/hid/mousedrv.inc |
---|
35,10 → 35,9 |
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 |
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 |
.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 |
.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 |
/kernel/branches/Kolibri-acpi/init.inc |
---|
439,7 → 439,7 |
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,15 → 599,21 |
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 |
614,24 → 620,41 |
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 |
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 eax, HPET_CFG_ENABLE |
mov [ebx+HPET_CFG], eax ;and start again |
@@: |
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 |
/kernel/branches/Kolibri-acpi/kernel.asm |
---|
701,19 → 701,11 |
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,8 → 1033,32 |
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 |
call delay_ms |
1053,6 → 1069,7 |
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 |
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 |
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 |
;----------------------------------------------------------------------------- |
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 |
; 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 |
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,33 → 2009,23 |
rol eax, 16 |
mov [esp+36-4], eax |
ret |
msbutton: |
movzx eax, byte [BTN_DOWN] |
mov [esp+36-4], eax |
ret |
msz: |
mov edi, [TASK_COUNT] |
movzx edi, word [WIN_POS + edi*2] |
cmp edi, [CURRENT_TASK] |
jne @f |
mov ax, [MOUSE_SCROLL_H] |
shl eax, 16 |
mov ax, [MOUSE_SCROLL_V] |
msbuttonExt: |
mov eax, [BTN_DOWN] |
mov [esp+36-4], eax |
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 |
jae @f |
stdcall load_cursor, ecx, edx |
mov [esp+36-4], eax |
@@: |
ret |
app_set_cursor: |
2016,6 → 2038,22 |
mov [esp+36-4], eax |
ret |
msz: |
mov edi, [TASK_COUNT] |
movzx edi, word [WIN_POS + edi*2] |
cmp edi, [CURRENT_TASK] |
jne @f |
mov ax, [MOUSE_SCROLL_H] |
shl eax, 16 |
mov ax, [MOUSE_SCROLL_V] |
mov [esp+36-4], eax |
and [MOUSE_SCROLL_H], word 0 |
and [MOUSE_SCROLL_V], word 0 |
ret |
@@: |
and [esp+36-4], dword 0 |
ret |
is_input: |
push edx |
2204,6 → 2242,8 |
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 |
.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 |
;------------------------------------------------------------------------------ |
align 4 |
sysfn_centermouse: ; 18.15 = mouse centered |
; removed here by <Lrz> |
; 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 |
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 |
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 |
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] |
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 |
mov [mouse_delay], dl |
@@: |
ret |
.set_pointer_position: |
; cmp ecx,4 ; set mouse pointer position |
dec ecx |
jnz .set_mouse_button |
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 |
jmp wakeup_osloop |
.set_mouse_button: |
; cmp ecx,5 ; set mouse button features |
dec ecx |
jnz .end |
mov [BTN_DOWN], dl |
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 |
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] |
/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 ;; |
/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 |
; 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 |
; |
;----------------------------------------------------------------- |
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 |
[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 |
DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: Checksum ok\n" |
;----------------------------------- |
; Check if destination IP is correct |
;-------------------------------- |
; Check if destination IP matches |
call NET_ptr_to_num4 |
; check if it matches local ip (Using RFC1122 strong end system model) |
; 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 |
cmp [IP_LIST + edi], 0 |
je .ip_ok |
; 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 |
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,15 → 312,64 |
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 |
;--------------------------- |
; Fragmented packet handler |
568,11 → 611,12 |
; |
; 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 |
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 |
642,7 → 687,10 |
.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 |
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 |
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 |
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,119 → 794,122 |
;-------------------------------------------------------- |
; |
; |
; 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 |
; 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 |
cmp ecx, sizeof.IPv4_header + 8 ; must be able to put at least 8 bytes |
jb .err2 |
mov [edi + IPv4_header.HeaderChecksum], 0 |
push esi ecx |
mov eax, [esi + IPv4_header.DestinationAddress] |
call ARP_IP_to_MAC |
pop ecx esi |
cmp eax, -1 |
jz .err2 |
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 ebx |
push ax |
add edi, [headerlength] |
mov [dataptr], edi |
mov ebx, [NET_DRV_LIST] |
lea eax, [ebx + ETH_DEVICE.mac] |
push eax |
.loop: |
DEBUGF DEBUG_NETWORK_VERBOSE, "Ipv4_fragment: new fragment" |
mov ecx, [segmentsize] |
cmp ecx, [remaining] |
jbe @f |
mov ecx, [remaining] |
@@: |
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] |
mov edx, [esp] |
add edx, [edx + NET_BUFF.offset] |
; add edx, ETH_header.DstMAC ; = 0 |
call ETH_output |
jz .err |
jz .fail |
push edi |
mov edx, ecx |
; copy header |
mov esi, [esp + 2*4] |
mov ecx, 5 ; 5 dwords: TODO: use IHL field of the header! |
mov esi, [headerptr] |
mov ecx, [headerlength] |
shr ecx, 2 |
rep movsd |
; copy data |
mov esi, [esp + 2*4] |
add esi, sizeof.IPv4_header |
add esi, [esp] ; offset |
mov esi, [dataptr] |
add esi, [offset] |
mov ecx, edx |
sub ecx, [headerlength] |
shr ecx, 2 |
rep movsd |
pop edi |
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 |
; packet length |
mov ax, dx |
xchg al, ah |
mov [edi + IPv4_header.TotalLength], ax |
mov ecx, [esp] ; offset |
xchg cl, ch |
; offset |
mov eax, [offset] |
xchg al, ah |
; 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 |
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 |
mov [edi + IPv4_header.HeaderChecksum], 0 |
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<< send the packet |
mov ecx, [esp + 1*4] |
push edx eax |
; 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 |
call NET_BUFF_free |
ret |
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: |
.fail: |
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 |
endp |
;--------------------------------------------------------------------------- |
; |
; IPv4_route |
973,11 → 1024,6 |
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 |
/kernel/branches/Kolibri-acpi/network/icmp.inc |
---|
133,8 → 133,9 |
; 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 |
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 |
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 |
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 |
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 |
; |
; IN: eax = socket ptr |
; ecx = data length |
; esi = data offset |
; edx = data pointer |
; |
;----------------------------------------------------------------- |
align 4 |
385,13 → 379,13 |
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 ebx, [eax + IP_SOCKET.device] |
mov edx, [eax + IP_SOCKET.LocalIP] |
mov ebx, [eax + IP_SOCKET.device] |
mov eax, [eax + IP_SOCKET.RemoteIP] |
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 |
417,8 → 411,12 |
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 |
/kernel/branches/Kolibri-acpi/network/loopback.inc |
---|
14,7 → 14,7 |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision: 5523 $ |
$Revision: 5976 $ |
iglobal |
align 4 |
61,15 → 61,15 |
.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 |
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: |
/kernel/branches/Kolibri-acpi/network/socket.inc |
---|
27,15 → 27,15 |
PID dd ? ; process ID |
TID dd ? ; thread ID |
Domain dd ? ; INET/LOCAL/.. |
Domain dd ? ; INET4/INET6/LOCAL/.. |
Type dd ? ; RAW/STREAM/DGRAM |
Protocol dd ? ; ICMP/IPv4/ARP/TCP/UDP |
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 ? |
47,6 → 47,8 |
LocalIP rd 4 ; network byte order |
RemoteIP rd 4 ; network byte order |
ttl db ? |
rb 3 ; align |
ends |
145,19 → 147,11 |
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 |
184,7 → 178,15 |
ends |
struct socket_options |
level dd ? |
optname dd ? |
optlen dd ? |
optval dd ? |
ends |
SOCKETBUFFSIZE = 4096 ; in bytes |
SOCKET_QUEUE_SIZE = 10 ; maximum number of incoming packets queued for 1 socket |
196,7 → 198,7 |
net_sockets rd 4 |
last_socket_num dd ? |
last_UDP_port dw ? ; These values give the number of the last used ephemeral port |
last_UDP_port dw ? ; last used ephemeral port |
last_TCP_port dw ? ; |
socket_mutex MUTEX |
203,11 → 205,11 |
endg |
;----------------------------------------------------------------- |
; |
; SOCKET_init |
; |
;----------------------------------------------------------------- |
;-----------------------------------------------------------------; |
; ; |
; SOCKET_init ; |
; ; |
;-----------------------------------------------------------------; |
macro SOCKET_init { |
xor eax, eax |
238,11 → 240,11 |
} |
;----------------------------------------------------------------- |
; |
; Socket API (function 74) |
; |
;----------------------------------------------------------------- |
;-----------------------------------------------------------------; |
; ; |
; Sockets API (system function 75) ; |
; ; |
;-----------------------------------------------------------------; |
align 4 |
sys_socket: |
275,16 → 277,19 |
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: |
313,6 → 318,8 |
cmp ecx, AF_INET4 |
jne .no_inet4 |
mov [eax + IP_SOCKET.ttl], 128 |
cmp edx, SOCK_DGRAM |
je .udp |
354,6 → 361,10 |
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 |
.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 |
.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,16 → 416,19 |
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: |
413,6 → 435,7 |
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 |
486,16 → 509,19 |
;----------------------------------------------------------------- |
; |
; 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: |
502,6 → 528,7 |
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,15 → 570,18 |
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: |
558,6 → 588,7 |
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,16 → 639,19 |
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: |
624,6 → 658,7 |
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 |
; 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,14 → 712,17 |
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: |
690,6 → 729,7 |
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,7 → 752,6 |
ret |
.tcp: |
call TCP_usrclosed |
test eax, eax |
719,7 → 758,6 |
jz @f |
call TCP_output ; If connection is not closed yet, send the FIN |
@@: |
ret |
729,17 → 767,21 |
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: |
746,6 → 788,7 |
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 |
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 |
.last_data: |
test ecx, ecx |
jz .return |
call SOCKET_notify |
call SOCKET_notify ; Call me again! |
jmp .return |
793,6 → 836,9 |
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_receive: DGRAM\n" |
test edi, MSG_PEEK |
jnz .peek |
mov ebx, esi ; bufferlength |
get_from_queue (eax + SOCKET_QUEUE_LOCATION), SOCKET_QUEUE_SIZE, sizeof.socket_queue_entry, .wouldblock ; sets esi only on success. |
824,7 → 870,11 |
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 |
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,18 → 960,20 |
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: |
919,6 → 980,7 |
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 |
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 |
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 |
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,17 → 1192,18 |
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: |
1143,24 → 1210,23 |
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 |
.socket: |
cmp [edx + socket_options.optname], SO_BINDTODEVICE |
jne .invalid |
.invalid: |
mov dword[esp+32], -1 |
mov dword[esp+20], EINVAL |
ret |
.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 |
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 |
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 |
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 |
jz .returnall |
call SOCKET_num_to_ptr |
test eax, eax |
jz .invalid |
mov esi, eax |
1303,22 → 1392,31 |
.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_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_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 |
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 |
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 |
mov [esi + RING_BUFFER.end_ptr], eax |
mov eax, esi |
pop esi |
ret |
.fail: |
DEBUGF DEBUG_NETWORK_ERROR, "SOCKET_ring_create: Out of memory!\n" |
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 |
; |
;----------------------------------------------------------------- |
;-----------------------------------------------------------------; |
; ; |
; 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 |
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 |
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 |
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 |
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 |
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 |
.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,19 → 1925,20 |
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: |
1842,9 → 1945,9 |
push ebx |
stdcall kernel_alloc, SOCKETBUFFSIZE |
or eax, eax |
jz .nomem |
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_alloc: ptr=%x\n", eax |
or eax, eax |
jz .exit |
; zero-initialize allocated memory |
push eax |
1925,12 → 2028,15 |
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 |
1937,17 → 2043,17 |
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 |
call mutex_lock |
popa |
cmp [eax + SOCKET.Domain], AF_INET4 |
jnz .no_tcp |
cmp [eax + SOCKET.Type], SOCK_STREAM |
jne .no_stream |
cmp [eax + SOCKET.Protocol], IP_PROTO_TCP |
jnz .no_tcp |
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 |
.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 |
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 |
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 |
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 |
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 |
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_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_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 |
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 |
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 |
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,21 → 2469,19 |
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: |
2378,22 → 2488,19 |
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_cant_recv_more: %x\n", eax |
or [eax + SOCKET.state], SS_CANTRCVMORE |
jmp SOCKET_notify |
call SOCKET_notify |
ret |
;----------------------------------------------------------------- |
; |
; 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,11 → 2508,8 |
or [eax + SOCKET.state], SS_CANTSENDMORE |
mov [eax + SOCKET.snd_proc], .notconn |
jmp SOCKET_notify |
call SOCKET_notify |
ret |
.notconn: |
mov dword[esp+20], ENOTCONN |
mov dword[esp+32], -1 |
/kernel/branches/Kolibri-acpi/network/stack.inc |
---|
53,7 → 53,13 |
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 |
PPP_PROTO_IPV6 = 0x5780 |
71,6 → 77,9 |
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 |
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 |
/kernel/branches/Kolibri-acpi/network/tcp.inc |
---|
201,13 → 201,11 |
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_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: |
/kernel/branches/Kolibri-acpi/network/tcp_input.inc |
---|
14,36 → 14,35 |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision: 5522 $ |
$Revision: 5976 $ |
;----------------------------------------------------------------- |
; |
; 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: / |
; |
;----------------------------------------------------------------- |
;-----------------------------------------------------------------; |
; ; |
; 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 |
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 |
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,7 → 111,7 |
push ecx esi |
pushw [esi + TCP_header.Checksum] |
mov [esi + TCP_header.Checksum], 0 |
TCP_checksum (edi), (edi+4) |
TCP_checksum (edi+IPv4_header.SourceAddress), (edi+IPv4_header.DestinationAddress) |
pop cx ; previous checksum |
cmp cx, dx |
pop edx ecx |
170,7 → 170,7 |
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 |
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 |
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 |
inc eax |
call TCP_xmit_timer |
jmp .rtt_done |
.no_timestamp_rtt: |
.no_timestamp_rtt: |
cmp [ebx + TCP_SOCKET.t_rtt], 0 |
je .rtt_done |
mov eax, [edx + TCP_header.AckNumber] |
494,7 → 494,6 |
jbe .rtt_done |
mov eax, [ebx + TCP_SOCKET.t_rtt] |
call TCP_xmit_timer |
.rtt_done: |
; update window pointers |
1211,7 → 1210,7 |
;;; 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 |
.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 |
/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 |
; Create the IP packet |
mov ecx, esi |
mov ebx, [eax + IP_SOCKET.device] |
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 edi, [eax + IP_SOCKET.RemoteIP] ; dest ip |
mov al, [eax + IP_SOCKET.ttl] |
mov ah, IP_PROTO_TCP |
call IPv4_output |
jz .ip_error |
/kernel/branches/Kolibri-acpi/network/tcp_subr.inc |
---|
104,18 → 104,17 |
} |
;--------------------------- |
; |
; 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_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_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 |
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 |
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 |
;--------------------------------------- |
; |
; 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 |
; Create the IP packet |
push cx ebx |
mov eax, [ebx + IP_SOCKET.RemoteIP] |
mov edx, [ebx + IP_SOCKET.LocalIP] |
mov edi, [ebx + IP_SOCKET.RemoteIP] |
mov al, [ebx + IP_SOCKET.ttl] |
mov ah, IP_PROTO_TCP |
mov ecx, sizeof.TCP_header |
mov ebx, [ebx + IP_SOCKET.device] |
mov ecx, sizeof.TCP_header |
mov di, IP_PROTO_TCP shl 8 + 128 |
call IPv4_output |
jz .error |
pop esi cx |
347,19 → 341,18 |
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: |
369,11 → 362,10 |
; 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 |
.done: |
} |
;-----------------------------------------------------------------; |
; ; |
; TCP_set_persist ; |
; ; |
;-----------------------------------------------------------------; |
align 4 |
TCP_set_persist: |
491,13 → 487,20 |
; 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 |
.no_rtt_yet: |
push ecx |
mov ecx, eax |
shl ecx, TCP_RTT_SHIFT |
559,10 → 561,16 |
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: |
577,13 → 585,20 |
; ebx = socket ptr |
; edx = segment ptr |
;-----------------------------------------------------------------; |
; ; |
; TCP_reassemble ; |
; ; |
; IN: ebx = socket ptr ; |
; edx = segment ptr ; |
; ; |
; OUT: / ; |
; ; |
;-----------------------------------------------------------------; |
align 4 |
TCP_reassemble: |
;;;;; TODO |
ret |
/kernel/branches/Kolibri-acpi/network/tcp_timer.inc |
---|
23,9 → 23,6 |
timer_flag_wait = 1 shl 4 |
;---------------------- |
; 160 ms timer |
;---------------------- |
macro TCP_timer_160ms { |
local .loop |
150,9 → 147,9 |
.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 |
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 |
endp |
DEBUGF DEBUG_NETWORK_VERBOSE, "socket %x: timed wait timer expired\n", eax |
push [eax + SOCKET.NextPtr] |
call TCP_close |
pop eax |
jmp .check_only |
; eax = socket |
endp |
;-----------------------------------------------------------------; |
; ; |
; TCP_cancel_timers ; |
; ; |
; IN: eax = socket ; |
; ; |
; OUT: / ; |
; ; |
;-----------------------------------------------------------------; |
align 4 |
TCP_cancel_timers: |
mov [eax + TCP_SOCKET.timer_flags], 0 |
/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 |
jmp ebx |
.switch: |
dd .close ; TCPS_CLOSED |
dd .close ; TCPS_LISTEN |
dd .close ; TCPS_SYN_SENT |
50,7 → 49,6 |
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 |
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: |
/kernel/branches/Kolibri-acpi/network/udp.inc |
---|
36,13 → 36,11 |
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 |
; 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 |
} |
;----------------------------------------------------------------- |
; |
; 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 |
; 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 |
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 |
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 |
popa |
.updatesock: |
call NET_ptr_to_num4 |
inc [UDP_PACKETS_RX + edi] |
movzx ecx, [esi + UDP_header.Length] |
232,17 → 225,17 |
;----------------------------------------------------------------- |
; |
; 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 |
sub esp, 4 ; Data ptr will be placed here |
push edx esi |
mov ebx, [eax + IP_SOCKET.device] |
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 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_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: |
348,10 → 344,6 |
@@: |
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 |
pop eax |
362,14 → 354,15 |
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_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: |