Subversion Repositories Kolibri OS

Compare Revisions

No changes between revisions

Regard whitespace Rev 4265 → Rev 3910

/kernel/branches/Kolibri-acpi/data32et.inc
File deleted
\ No newline at end of file
/kernel/branches/Kolibri-acpi/bus/usb/protocol.inc
202,7 → 202,8
; For now, we need sizeof.usb_device_data and extra 8 bytes for GET_DESCRIPTOR
; input and output, see usb_after_set_address. Later we will reallocate it
; to actual size needed for descriptors.
movi eax, sizeof.usb_device_data + 8
push sizeof.usb_device_data + 8
pop eax
push ecx
call malloc
pop ecx
497,7 → 498,10
pop edi esi
call usb_reinit_pipe_list
; 1d. Free the old memory.
; Note that free destroys ebx.
push ebx
call free
pop ebx
pop eax
; 2. Issue control transfer GET_DESCRIPTOR(DEVICE) for full descriptor.
; restore length saved in step 1a
/kernel/branches/Kolibri-acpi/bus/usb/hub.inc
105,9 → 105,6
StatusPipe dd ?
NumPorts dd ?
; Number of downstream ports; from 1 to 255.
MaxPacketSize dd ?
; Maximum packet size for interrupt endpoint.
; Usually equals ceil((1+NumPorts)/8), but some hubs give additional bytes.
Actions dd ?
; Bitfield with HUB_* constants.
PoweredOnTime dd ?
253,11 → 250,10
; the pointer is in edx.
; 2. Allocate memory for the hub descriptor.
; Maximum length (assuming 255 downstream ports) is 40 bytes.
; Allocate 4 extra bytes to keep wMaxPacketSize.
; 2a. Save registers.
push edx
; 2b. Call the allocator.
movi eax, 44
movi eax, 40
call malloc
; 2c. Restore registers.
pop ecx
271,11 → 267,7
movzx eax, [ecx+usb_endpoint_descr.bEndpointAddress]
movzx edx, [ecx+usb_endpoint_descr.bInterval]
movzx ecx, [ecx+usb_endpoint_descr.wMaxPacketSize]
test ecx, (1 shl 11) - 1
jz .free
push ecx
stdcall usb_open_pipe, ebx, eax, ecx, INTERRUPT_PIPE, edx
pop ecx
; If failed, free the memory allocated in step 2,
; say something to the debug board and return error.
test eax, eax
283,8 → 275,6
; 4. Send control query for the hub descriptor,
; pass status pipe as a callback parameter,
; allow short packets.
and ecx, (1 shl 11) - 1
mov [esi+40], ecx
mov dword [esi], 0xA0 + \ ; class-specific request
(USB_GET_DESCRIPTOR shl 8) + \
(0 shl 16) + \ ; descriptor index 0
362,9 → 352,8
cmp [length], edx
jb .invalid
; 5. Allocate the memory for usb_hub structure.
; Total size of variable-length data is ALIGN_UP(floor(NumPorts/8)+1+MaxPacketSize,4)+8*NumPorts.
add edx, [eax+40]
add edx, sizeof.usb_hub - sizeof.usb_hub_descr + 3
; Total size of variable-length data is ALIGN_UP(2*(floor(NumPorts/8)+1),4)+8*NumPorts.
lea edx, [sizeof.usb_hub+(edx-sizeof.usb_hub_descr)*2+3]
and edx, not 3
lea eax, [edx+ecx*8]
push ecx edx
385,8 → 374,6
mov [ebx+usb_hub.StatusPipe], eax
push esi edi
mov esi, [buffer]
mov eax, [esi+40]
mov [ebx+usb_hub.MaxPacketSize], eax
; The following commands load bNbrPorts, wHubCharacteristics, bPwrOn2PwrGood.
mov edx, dword [esi+usb_hub_descr.bNbrPorts]
mov dl, 0
500,8 → 487,11
; Called when initial configuration is done and when a previous notification
; has been processed.
proc usb_hub_wait_change
mov ecx, [eax+usb_hub.NumPorts]
shr ecx, 3
inc ecx
stdcall usb_normal_transfer_async, [eax+usb_hub.StatusPipe], \
[eax+usb_hub.StatusChangePtr], [eax+usb_hub.MaxPacketSize], usb_hub_changed, eax, 1
[eax+usb_hub.StatusChangePtr], ecx, usb_hub_changed, eax, 1
ret
endp
 
523,7 → 513,6
shr ecx, 3
inc ecx
sub ecx, [length]
jbe .restart
push eax edi
mov edi, [buffer]
add edi, [length]
/kernel/branches/Kolibri-acpi/blkdev/disk.inc
1006,9 → 1006,6
call ext2_create_partition
test eax, eax
jnz .success
call xfs_create_partition
test eax, eax
jnz .success
; 3. No file system has recognized the volume, so just allocate the PARTITION
; structure without extra fields.
movi eax, sizeof.PARTITION
/kernel/branches/Kolibri-acpi/blkdev/disk_cache.inc
512,7 → 512,7
 
push edi
mov edi, [esi+DISK.SysCache.pointer]
lea ecx, [(ecx+1)*3]
lea ecx, [ecx*3]
xor eax, eax
rep stosd
pop edi
527,7 → 527,7
 
push edi
mov edi, [esi+DISK.AppCache.pointer]
lea ecx, [(ecx+1)*3]
lea ecx, [ecx*3]
xor eax, eax
rep stosd
pop edi
/kernel/branches/Kolibri-acpi/blkdev/flp_drv.inc
162,7 → 162,7
mov [FDC_Status], FDC_Normal
; Проверить готовность контроллера к передаче данных
mov DX, 3F4h ;(порт состояния FDC)
mov ecx, 0x10000 ;установить счетчик тайм-аута
xor CX, CX ;установить счетчик тайм-аута
@@TestRS_1:
in AL, DX ;прочитать регистр RS
and AL, 0C0h ;выдлить разряды 6 и 7
197,6 → 197,8
pusha
; Сбросить байт состояния операции
mov [FDC_Status], FDC_Normal
; Сбросить флаг прерывани
mov [FDD_IntFlag], 0
; Обнулить счетчик тиков
mov eax, [timer_ticks]
mov [TickCounter], eax
370,8 → 372,6
SeekTrack:
pusha
call save_timer_fdd_motor
; Сбросить флаг прерывания
mov [FDD_IntFlag], 0
; Подать команду "Поиск"
mov AL, 0Fh
call FDCDataOutput
431,8 → 431,6
ReadSector:
pushad
call save_timer_fdd_motor
; Сбросить флаг прерывания
mov [FDD_IntFlag], 0
; Установить скорость передачи 500 Кбайт/с
mov AX, 0
mov DX, 03F7h
533,8 → 531,6
WriteSector:
pushad
call save_timer_fdd_motor
; Сбросить флаг прерывания
mov [FDD_IntFlag], 0
; Установить скорость передачи 500 Кбайт/с
mov AX, 0
mov DX, 03F7h
/kernel/branches/Kolibri-acpi/boot/bootcode.inc
51,20 → 51,18
; get number in range [bl,bh] (bl,bh in ['0'..'9'])
; in: bx=range
; out: ax=digit (1..9, 10 for 0)
mov ah, 0 ; If 'int 16h' is called with 'ah' equal to zero, the BIOS will not return control to the caller
int 16h ; until a key is available in the system type ahead buffer. On return, 'al' contains the ASCII
cmp al, 27 ; code for the key read from the buffer and 'ah' contains the keyboard scan code. (27=>ESC)
jz @f ; If ESC is pressed, return (user doesn't want to change any value).
cmp al, bl ; Compare 'al' (ASCII code of key pressed) with 'bl' (lowest accepted char from the range).
jb getkey ; ASCII code is below lowest accepted value => continue waiting for another key.
cmp al, bh ; Compare 'al' (ASCII code of key pressed) with 'bh' (highest accepted char from the range).
ja getkey ; ASCII code is above highest accepted value => continue waiting for another key.
mov ah, 0 ; If 'int 16h' is called with 'ah' equal to zero, the BIOS will not return control
int 16h ; to the caller until a key is available in the system type ahead buffer. On return,
cmp al, bl ; 'al' contains the ASCII code for the key read from the buffer and 'ah' contains
jb getkey ; the keyboard scan code. Here we compare 'al' with the range of accepted characters.
cmp al, bh ; If the key pressed is not in the range, continue waiting for another key.
ja getkey
push ax ; If the pressed key is in the accepted range, save it on the stack and echo to screen.
call putchar
pop ax
and ax, 0Fh ; Convert ASCII code to number: '1'->1, '2'->2, etc. 0Fh=1111b.
jnz @f ; ASCII code for '0' is 48 (110000b). (110000b AND 1111b) = 0
mov al, 10 ; So if key '0' was entered, return 10 in 'ax'
and ax, 0Fh ; ASCII code for '0' is 48 (110000b). 0F4=1111b. (110000b AND 1111b) = 0
jnz @f ; So if key '0' was entered, return 10 in 'ax'
mov al, 10
@@:
ret
 
81,18 → 79,6
call setcursor
}
 
macro _ask_question question,range,variable_to_set
{
_setcursor 16,0
mov si, question ; Print the question
call print
mov bx, range ; range accepted for answer
call getkey
cmp al, 27 ; If ESC was pressed, do not change the value
jz .esc_pressed
mov [variable_to_set], al
}
 
boot_read_floppy:
push si
xor si, si
447,7 → 433,7
mov [es:BOOT_IDE_PI_16], cx
xor si, si ; device index = 0
int 0x1A
jnc .found ; Parallel IDE Controller
jnc .found_1 ; Parallel IDE Controller
; Controller not found!
xor ax, ax
mov [es:BOOT_IDE_PI_16], ax
789,26 → 775,25
cmp al, 'e' ; select boot origin
jnz .show_remarks
; e) preboot_device = from where to boot?
_setcursor 16,0
mov si, bdev
call print
if defined extended_primary_loader
_ask_question bdev,'12',preboot_device ; range accepted for answer: 1-2
mov bx, '12' ; range accepted for answer: 1-2
else
_ask_question bdev,'14',preboot_device ; range accepted for answer: 1-4
mov bx, '14' ; range accepted for answer: 1-4
end if
call getkey
mov [preboot_device], al
_setcursor 14,0
 
.d:
if ~ defined extended_primary_loader
mov [.bSettingsChanged], 1
end if
.esc_pressed:
call clear_vmodes_table ;clear vmodes_table
jmp .printcfg
 
.change_a:
call clear_vmodes_table ;clear vmodes_table
 
mov si, word [cursor_pos]
mov word [cursor_pos_old], si
.loops:
call draw_vmodes_table
_setcursor 25,0 ; out of screen
818,13 → 803,6
 
mov si, word [cursor_pos]
 
cmp al, 27 ; If ESC was pressed, do not change the value
jnz @f ; Just exit the resolution selection box
 
mov si, word [cursor_pos_old]
mov word [cursor_pos], si
jmp .esc_pressed
@@:
cmp ah, 0x48;x,0x48E0 ; up
jne .down
cmp si, modes_table
895,13 → 873,17
jmp .d
 
.change_b: ; b) preboot_biosdisk = use BIOS disks through V86 emulation?
; _setcursor 16,0
_setcursor 16,0
; mov si, ask_dma // (earlier was: preboot_dma = use DMA access?)
; call print
; mov bx, '13' ; range accepted for answer: 1-3
; call getkey
; mov [preboot_dma], al
_ask_question ask_bd,'12',preboot_biosdisk ; range accepted for answer: 1-2
mov si, ask_bd
call print
mov bx, '12' ; range accepted for answer: 1-2
call getkey
mov [preboot_biosdisk], al
_setcursor 11,0
jmp .d
;.change_c: ; // VRR is an obsolete functionality, used only with CRT monitors
914,11 → 896,21
; _setcursor 12,0
; jmp .d
.change_c: ; c) preboot_debug = duplicates kernel debug output to the screen
_ask_question ask_debug,'12',preboot_debug ; range accepted for answer: 1-2
_setcursor 16,0
mov si, ask_debug
call print
mov bx, '12' ; range accepted for answer: 1-2
call getkey
mov [preboot_debug], al
_setcursor 12,0
jmp .d
.change_d: ; d) preboot_launcher = start the first app (right now it's LAUNCHER) after kernel is loaded?
_ask_question ask_launcher,'12',preboot_launcher ; range accepted for answer: 1-2
_setcursor 16,0
mov si, ask_launcher
call print
mov bx, '12' ; range accepted for answer: 1-2
call getkey
mov [preboot_launcher], al
_setcursor 13,0
jmp .d
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
/kernel/branches/Kolibri-acpi/boot/booten.inc
15,10 → 15,10
 
 
d80x25_bottom:
db 186,' KolibriOS comes with ABSOLUTELY NO WARRANTY. See file COPYING for details ',186
db 186,' If you find any bugs, please report them at: http://board.kolibrios.org ',186
db 186,' KolibriOS comes with ABSOLUTELY NO WARRANTY. See file COP'
db 'YING for details ',186
line_full_bottom
d80x25_bottom_num = 3
d80x25_bottom_num = 2
 
msg_apm db " APM x.x ", 0
novesa db "Display: EGA/CGA",13,10,0
79,7 → 79,7
pdm1 db "real floppy",13,10,0
pdm2 db "C:\kolibri.img (FAT32)",13,10,0
else
preboot_device_msgs dw 0,pdm1,pdm2,pdm3,pdm4,0
preboot_device_msgs dw 0,pdm1,pdm2,pdm3
pdm1 db "real floppy",13,10,0
pdm2 db "C:\kolibri.img (FAT32)",13,10,0
pdm3 db "use already loaded image",13,10,0
93,14 → 93,13
loader_block_error db "Bootloader data invalid, I cannot continue. Stopped.",0
end if
 
_st latin1 '║ ┌───────────────────────────────┬─┐',13,10,0
_r1 latin1 '║ │ 320x200 EGA/CGA 256 colors │ │',13,10,0
_r2 latin1 '║ │ 640x480 VGA 16 colors │ │',13,10,0
_rs latin1 '║ │ ????x????@?? SVGA VESA │ │',13,10,0
_bt latin1 '║ └───────────────────────────────┴─┘',13,10,0
_st:latin1 '║ ┌───────────────────────────────┬─┐',13,10,0
_r1:latin1 '║ │ 320x200 EGA/CGA 256 colors │ │',13,10,0
_r2:latin1 '║ │ 640x480 VGA 16 colors │ │',13,10,0
_rs:latin1 '║ │ ????x????@?? SVGA VESA │ │',13,10,0
_bt:latin1 '║ └───────────────────────────────┴─┘',13,10,0
 
remark1 db "Default values were selected to match most of configurations, but not all.",0
remark2 db "If the system does not boot, try to disable option [b]. If the system gets",0
remark3 db "stuck after booting, enable option [c], disable option [d] and make photo.",0
remarks dw remark1, remark2, remark3
num_remarks = 3
remark2 db "If the system does not boot, try to disable the item [b].",0
remarks dw remark1, remark2
num_remarks = 2
/kernel/branches/Kolibri-acpi/boot/bootet.inc
15,24 → 15,24
 
d80x25_bottom:
latin1 '║ KolibriOS on IGASUGUSE GARANTIITA. Vaata faili COPYING info saamiseks. Kui ║'
latin1 '║ leiate vigu, anna neist palun teada aadressil: http://board.kolibrios.org ║'
latin1 '║ KolibriOS kaasas IGASUGUSE GARANTIITA. Naha faili COPY'
latin1 'ING detailid ║'
line_full_bottom
d80x25_bottom_num = 3
d80x25_bottom_num = 2
 
msg_apm latin1 " APM x.x ", 0
novesa latin1 "Ekraan: EGA/CGA",13,10,0
s_vesa latin1 "Vesa versioon: "
msg_apm: latin1 " APM x.x ", 0
novesa: latin1 "Ekraan: EGA/CGA",13,10,0
s_vesa: latin1 "Vesa versioon: "
.ver db "?.?",13,10,0
 
gr_mode latin1 "Vali video resolutsioon: ",13,10,0
gr_mode: latin1 "Vali videomode: ",13,10,0
 
ask_bd latin1 "Lisa V86 reziimis BIOSle nähtavad kettad? [1-jah, 2-ei]: ",0
ask_bd: latin1 "Lisa kettad nahtavaks BIOS reziim V86? [1-jah, 2-no]: ",0
 
if defined extended_primary_loader
bdev latin1 "Paigalda mäluketas [1-diskett; 2-kolibri.img]: ",0
bdev: latin1 "Paigalda mäluketas [1-diskett; 2-kolibri.img]: ",0
else
bdev latin1 "Paigalda mäluketas [1-diskett; 2-C:\kolibri.img (FAT32);"
bdev: latin1 "Paigalda mäluketas [1-diskett; 2-C:\kolibri.img (FAT32);"
latin1 13,10,"║ "
latin1 "3-kasuta eellaaditud mäluketast kerneli restardist;"
latin1 13,10,"║ "
39,68 → 39,67
latin1 "4-loo tühi pilt]: ",0
end if
 
prnotfnd latin1 "Fataalne - Video resolutsiooni ei leitud.",0
prnotfnd: latin1 "Fataalne - Videoreziimi ei leitud.",0
 
not386 latin1 "Fataalne - CPU 386+ on vajalik.",0
fatalsel latin1 "Fataalne - Riistvara ei toeta graafilist resolutsiooni.",0
pres_key latin1 "Vajutage suvalist klahvi, et valida uus videomode.",0
badsect latin1 13,10,"║ Fataalne - Vigane sektor. Asenda diskett.",0
memmovefailed latin1 13,10,"║ Fataalne - Int 0x15 liigutamine ebaõnnestus.",0
okt latin1 " ... OK"
linef latin1 13,10,0
diskload latin1 "Loen disketti: 00 %",8,8,8,8,0
pros latin1 "00"
backspace2 latin1 8,8,0
not386: latin1 "Fataalne - CPU 386+ on vajalik.",0
fatalsel: latin1 "Fataalne - Graafilist reziimi riistvara ei toeta.",0
pres_key: latin1 "Vajutage suvalist klahvi, et valida uus videomode.",0
badsect: latin1 13,10,"║ Fataalne - Vigane sektor. Asenda diskett.",0
memmovefailed:latin1 13,10,"║ Fataalne - Int 0x15 liigutamine ebaõnnestus.",0
okt: latin1 " ... OK"
linef: latin1 13,10,0
diskload: latin1 "Loen disketti: 00 %",8,8,8,8,0
pros: latin1 "00"
backspace2:latin1 8,8,0
boot_dev db 0 ; 0=floppy, 1=hd
start_msg latin1 "Vajuta [abcde] seadete muutmiseks, vajuta [Enter] laadimise jätkamiseks",13,10,0
time_msg latin1 " või oota "
time_str latin1 " 5 sekundit"
start_msg:latin1 "Vajuta [abcde] seadete muutmiseks, vajuta [Enter] laadimise jätkamiseks",13,10,0
time_msg: latin1 " või oota "
time_str: latin1 " 5 sekundit"
latin1 " automaatseks jätkamiseks",13,10,0
current_cfg_msg latin1 "Praegused seaded:",13,10,0
curvideo_msg latin1 " [a] Video resolutsioon: ",0
current_cfg_msg:latin1 "Praegused seaded:",13,10,0
curvideo_msg:latin1 " [a] Videoreziim: ",0
 
mode0 latin1 "320x200, EGA/CGA 256 värvi",0
mode9 latin1 "640x480, VGA 16 värvi",0
mode0: latin1 "320x200, EGA/CGA 256 värvi",0
mode9: latin1 "640x480, VGA 16 värvi",0
 
usebd_msg latin1 " [b] Lisa BIOSle nähtavad kettad:",0
on_msg latin1 " sees",13,10,0
off_msg latin1 " väljas",13,10,0
usebd_msg:latin1 " [b] Lisa kettad nahtavaks BIOS:",0
on_msg: latin1 " sees",13,10,0
off_msg: latin1 " väljas",13,10,0
 
debug_mode_msg latin1 " [c] Dubleeri silumisinfo ekraanile:",0
ask_debug latin1 "Dubleeri silumisinfo ekraanile? [1-jah, 2-ei]: ",0
debug_mode_msg: latin1 " [c] Duplicate siluda väljund ekraani:",0
ask_debug: latin1 "Duplicate siluda väljund ekraani? [1-jah, 2-no]: ",0
 
launcher_msg latin1 " [d] Käivita LAUNCHER pärast kerneli laadimist:",0
ask_launcher latin1 "Käivita esimese programm (LAUNCHER) peale kerneli laadimist? [1-jah, 2-ei]: ",0
launcher_msg: latin1 " [d] Alusta LAUNCHER pärast kernel on koormatud:",0
ask_launcher: latin1 "Alusta esimese taotluse (LAUNCHER) pärast kernel laetakse? [1-jah, 2-no]: ",0
 
preboot_device_msg latin1 " [e] Disketi kujutis: ",0
preboot_device_msg:latin1 " [e] Disketi kujutis: ",0
 
if defined extended_primary_loader
preboot_device_msgs dw 0,pdm1,pdm2,0
pdm1 latin1 "reaalne diskett",13,10,0
pdm2 latin1 "kolibri.img",13,10,0
pdm1: latin1 "reaalne diskett",13,10,0
pdm2: latin1 "kolibri.img",13,10,0
else
preboot_device_msgs dw 0,pdm1,pdm2,pdm3,pdm4,0
pdm1 latin1 "reaalne diskett",13,10,0
pdm2 latin1 "C:\kolibri.img (FAT32)",13,10,0
pdm3 latin1 "kasuta juba laaditud kujutist",13,10,0
pdm4 latin1 "loo tühi pilt",13,10,0
preboot_device_msgs dw 0,pdm1,pdm2,pdm3
pdm1: latin1 "reaalne diskett",13,10,0
pdm2: latin1 "C:\kolibri.img (FAT32)",13,10,0
pdm3: latin1 "kasuta juba laaditud kujutist",13,10,0
pdm4: latin1 "loo tühi pilt",13,10,0
end if
 
loading_msg latin1 "Laadin KolibriOS...",0
loading_msg:latin1 "Laadin KolibriOS...",0
 
if ~ defined extended_primary_loader
save_quest latin1 "Jäta meelde praegused seaded? [y/n]: ",0
loader_block_error latin1 "Alglaaduri andmed vigased, ei saa jätkata. Peatatud.",0
save_quest:latin1 "Jäta meelde praegused seaded? [y/n]: ",0
loader_block_error:latin1 "Alglaaduri andmed vigased, ei saa jätkata. Peatatud.",0
end if
 
_st latin1 '║ ┌───────────────────────────────┬─┐',13,10,0
_r1 latin1 '║ │ 320x200 EGA/CGA 256 colors │ │',13,10,0
_r2 latin1 '║ │ 640x480 VGA 16 colors │ │',13,10,0
_rs latin1 '║ │ ????x????@?? SVGA VESA │ │',13,10,0
_bt latin1 '║ └───────────────────────────────┴─┘',13,10,0
_st:latin1 '║ ┌───────────────────────────────┬─┐',13,10,0
_r1:latin1 '║ │ 320x200 EGA/CGA 256 colors │ │',13,10,0
_r2:latin1 '║ │ 640x480 VGA 16 colors │ │',13,10,0
_rs:latin1 '║ │ ????x????@?? SVGA VESA │ │',13,10,0
_bt:latin1 '║ └───────────────────────────────┴─┘',13,10,0
 
remark1 latin1 "Vaikimisi väärtused on kasutatavad enamikes arvutites, kuid mitte kõigis.",0
remark2 latin1 "Kui süsteem ei käivitu, proovige lülitada kirje [b] välja. Kui see läheb",0
remark3 latin1 "kinni pärast käivitamist, võimaldama valik [c], keelake [d] ja teha foto.",0
remarks dw remark1, remark2, remark3
num_remarks = 3
remark1:latin1 "Vaikimisi maaratud vaartused on valitud mugavuse enamikes, kuid mitte koik.",0
remark2:latin1 "Kui susteem ei kaivitu, proovige lulitada kirje [b].",0
remarks dw remark1, remark2
num_remarks = 2
/kernel/branches/Kolibri-acpi/boot/bootge.inc
15,8 → 15,10
 
 
d80x25_bottom:
db 186,' KolibriOS wird ohne jegliche Garantie vertrieben. Details stehen in der ',186
db 186,' Datei COPYING. Bitte melden Sie Fehler bei: http://board.kolibrios.org ',186
db 186,' KolibriOS wird ohne jegliche Garantie vertrieben. '
db ' ',186
db 186,' Details stehen in der Datei COPYING '
db ' ',186
line_full_bottom
d80x25_bottom_num = 3
 
79,7 → 81,7
pdm1 db "Echte Diskette",13,10,0
pdm2 db "kolibri.img",13,10,0
else
preboot_device_msgs dw 0,pdm1,pdm2,pdm3,pdm4,0
preboot_device_msgs dw 0,pdm1,pdm2,pdm3
pdm1 db "Echte Diskette",13,10,0
pdm2 db "C:\kolibri.img (FAT32)",13,10,0
pdm3 db "Nutze bereits geladenes Image",13,10,0
93,15 → 95,13
loader_block_error db "Bootloader Daten ungueltig, Kann nicht fortfahren. Angehalten.",0
end if
 
_st latin1 '║ ┌───────────────────────────────┬─┐',13,10,0
_r1 latin1 '║ │ 320x200 EGA/CGA 256 colors │ │',13,10,0
_r2 latin1 '║ │ 640x480 VGA 16 colors │ │',13,10,0
_rs latin1 '║ │ ????x????@?? SVGA VESA │ │',13,10,0
_bt latin1 '║ └───────────────────────────────┴─┘',13,10,0
_st:latin1 '║ ┌───────────────────────────────┬─┐',13,10,0
_r1:latin1 '║ │ 320x200 EGA/CGA 256 colors │ │',13,10,0
_r2:latin1 '║ │ 640x480 VGA 16 colors │ │',13,10,0
_rs:latin1 '║ │ ????x????@?? SVGA VESA │ │',13,10,0
_bt:latin1 '║ └───────────────────────────────┴─┘',13,10,0
 
remark1 db "Die Standardwerte sind fur die meisten gewahlt, aber nicht fur jedermann.",0
remark2 db "Wenn das System nicht bootet, das Option [b] deaktivieren versuchen. Wenn es",0
remark3 db "nach dem Booten hangen bleibt, aktivieren Sie Option [c], deaktivieren [d]",0
remark4 db "und machen Fotos.",0
remarks dw remark1, remark2, remark3, remark4
num_remarks = 4
remark2 db "Wenn das System nicht bootet, versuchen, das Element [b] deaktivieren.",0
remarks dw remark1, remark2
num_remarks = 2
/kernel/branches/Kolibri-acpi/boot/bootru.inc
15,90 → 15,89
 
 
d80x25_bottom:
cp866 '║ KolibriOS НЕ ПРЕДОСТАВЛЯЕТ НИКАКИХ ГАРAНТИЙ. Подробнее смотрите в файле ║'
cp866 '║ COPYING.TXT. О найденных ошибках сообщайте на http://board.kolibrios.org ║'
cp866 '║ KolibriOS НЕ ПРЕДОСТАВЛЯЕТ НИКАКИХ ГАРAНТИЙ. ║'
cp866 '║ Подробнее смотрите в файле COPYING.TXT ║'
line_full_bottom
d80x25_bottom_num = 3
 
msg_apm cp866 " APM x.x ", 0
novesa cp866 "Видеокарта: EGA/CGA",13,10,0
s_vesa cp866 "Версия VESA: "
msg_apm: cp866 " APM x.x ", 0
novesa: cp866 "Видеокарта: EGA/CGA",13,10,0
s_vesa: cp866 "Версия VESA: "
.ver db "?.?",13,10,0
 
gr_mode cp866 "Выберите видеорежим: ",13,10,0
gr_mode: cp866 "Выберите видеорежим: ",13,10,0
 
ask_bd cp866 "Добавить диски, видимые через BIOS в режиме V86? [1-да, 2-нет]: ",0
ask_bd: cp866 "Добавить диски, видимые через BIOS в режиме V86? [1-да, 2-нет]: ",0
 
if defined extended_primary_loader
bdev cp866 "Загрузить образ из [1-дискета; 2-kolibri.img из папки загрузки]: ",0
bdev: cp866 "Загрузить образ из [1-дискета; 2-kolibri.img из папки загрузки]: ",0
else
bdev cp866 "Загрузить образ из [1-дискета; 2-C:\kolibri.img (FAT32);",13,10
bdev: cp866 "Загрузить образ из [1-дискета; 2-C:\kolibri.img (FAT32);",13,10
cp866 "║ 3-использовать уже загруженный образ;",13,10
cp866 "║ 4-создать чистый образ]: ",0
end if
 
prnotfnd cp866 "Ошибка - Видеорежим не найден.",0
prnotfnd: cp866 "Ошибка - Видеорежим не найден.",0
 
not386 cp866 "Ошибка - Требуется процессор 386+.",0
fatalsel cp866 "Ошибка - Выбранный видеорежим не поддерживается.",0
pres_key cp866 "Нажимите любую клавишу, для перехода в выбор режимов.",0
badsect cp866 13,10,"║ Ошибка - Дискета повреждена. Попробуйте другую.",0
memmovefailed cp866 13,10,"║ Ошибка - Int 0x15 move failed.",0
okt cp866 " ... OK"
linef cp866 13,10,0
diskload cp866 "Загрузка дискеты: 00 %",8,8,8,8,0
pros cp866 "00"
backspace2 cp866 8,8,0
not386: cp866 "Ошибка - Требуется процессор 386+.",0
fatalsel: cp866 "Ошибка - Выбранный видеорежим не поддерживается.",0
pres_key: cp866 "Нажимите любую клавишу, для перехода в выбор режимов.",0
badsect: cp866 13,10,"║ Ошибка - Дискета повреждена. Попробуйте другую.",0
memmovefailed:cp866 13,10,"║ Ошибка - Int 0x15 move failed.",0
okt: cp866 " ... OK"
linef: cp866 13,10,0
diskload: cp866 "Загрузка дискеты: 00 %",8,8,8,8,0
pros: cp866 "00"
backspace2:cp866 8,8,0
boot_dev db 0
start_msg cp866 "Нажмите [abcde] для изменения настроек, [Enter] для продолжения загрузки",13,10,0
time_msg cp866 " или подождите "
time_str cp866 " 5 секунд "
start_msg:cp866 "Нажмите [abcde] для изменения настроек, [Enter] для продолжения загрузки",13,10,0
time_msg: cp866 " или подождите "
time_str: cp866 " 5 секунд "
cp866 " до автоматического продолжения",13,10,0
current_cfg_msg cp866 "Текущие настройки:",13,10,0
curvideo_msg cp866 " [a] Видеорежим: ",0
current_cfg_msg:cp866 "Текущие настройки:",13,10,0
curvideo_msg:cp866 " [a] Видеорежим: ",0
 
mode0 cp866 "320x200, EGA/CGA 256 цветов",13,10,0
mode9 cp866 "640x480, VGA 16 цветов",13,10,0
mode0: cp866 "320x200, EGA/CGA 256 цветов",13,10,0
mode9: cp866 "640x480, VGA 16 цветов",13,10,0
 
usebd_msg cp866 " [b] Добавить диски, видимые через BIOS:",0
on_msg cp866 " вкл",13,10,0
off_msg cp866 " выкл",13,10,0
usebd_msg:cp866 " [b] Добавить диски, видимые через BIOS:",0
on_msg: cp866 " вкл",13,10,0
off_msg: cp866 " выкл",13,10,0
 
debug_mode_msg cp866 " [c] Дублировать дебаг-вывод на экран монитора:",0
ask_debug cp866 "Дублировать дебаг-вывод на экран монитора? [1-да, 2-нет]: ",0
debug_mode_msg: cp866 " [c] Дублировать дебаг-вывод на экран монитора:",0
ask_debug: cp866 "Дублировать дебаг-вывод на экран монитора? [1-да, 2-нет]: ",0
 
launcher_msg cp866 " [d] Запустить программу LAUNCHER после загрузки ядра:",0
ask_launcher cp866 "Запустить первую программу (LAUNCHER) после загрузки ядра? [1-да, 2-нет]: ",0
launcher_msg: cp866 " [d] Запустить программу LAUNCHER после загрузки ядра:",0
ask_launcher: cp866 "Запустить первую программу (LAUNCHER) после загрузки ядра? [1-да, 2-нет]: ",0
 
preboot_device_msg cp866 " [e] Образ дискеты: ",0
preboot_device_msg:cp866 " [e] Образ дискеты: ",0
 
if defined extended_primary_loader
preboot_device_msgs dw 0,pdm1,pdm2,0
pdm1 cp866 "настоящая дискета",13,10,0
pdm2 cp866 "kolibri.img из папки загрузки",13,10,0
pdm1: cp866 "настоящая дискета",13,10,0
pdm2: cp866 "kolibri.img из папки загрузки",13,10,0
else
preboot_device_msgs dw 0,pdm1,pdm2,pdm3,pdm4,0
pdm1 cp866 "настоящая дискета",13,10,0
pdm2 cp866 "C:\kolibri.img (FAT32)",13,10,0
pdm3 cp866 "использовать уже загруженный образ",13,10,0
pdm4 cp866 "создать чистый образ",13,10,0
preboot_device_msgs dw 0,pdm1,pdm2,pdm3,pdm4
pdm1: cp866 "настоящая дискета",13,10,0
pdm2: cp866 "C:\kolibri.img (FAT32)",13,10,0
pdm3: cp866 "использовать уже загруженный образ",13,10,0
pdm4: cp866 "создать чистый образ",13,10,0
end if
 
loading_msg cp866 "Идёт загрузка KolibriOS...",0
loading_msg:cp866 "Идёт загрузка KolibriOS...",0
 
if ~ defined extended_primary_loader ; saving not supported in this case
save_quest cp866 "Запомнить текущие настройки? [y/n]: ",0
loader_block_error cp866 "Ошибка в данных начального загрузчика, продолжение невозможно.",0
save_quest:cp866 "Запомнить текущие настройки? [y/n]: ",0
loader_block_error:cp866 "Ошибка в данных начального загрузчика, продолжение невозможно.",0
end if
 
_st cp866 '║ ┌───────────────────────────────┬─┐ ',13,10,0
_r1 cp866 '║ │ 320x200 EGA/CGA 256 цветов │ │ ',13,10,0
_r2 cp866 '║ │ 640x480 VGA 16 цветов │ │ ',13,10,0
_rs cp866 '║ │ ????x????@?? SVGA VESA │ │ ',13,10,0
_bt cp866 '║ └───────────────────────────────┴─┘ ',13,10,0
_st:cp866 '║ ┌───────────────────────────────┬─┐ ',13,10,0
_r1:cp866 '║ │ 320x200 EGA/CGA 256 цветов │ │ ',13,10,0
_r2:cp866 '║ │ 640x480 VGA 16 цветов │ │ ',13,10,0
_rs:cp866 '║ │ ????x????@?? SVGA VESA │ │ ',13,10,0
_bt:cp866 '║ └───────────────────────────────┴─┘ ',13,10,0
 
remark1 cp866 "Значения по умолчанию выбраны для удобства большинства, но не всех. Если у",0
remark2 cp866 "Вас не грузится система, попробуйте отключить пункт [b]. Если она зависла",0
remark3 cp866 "после запуска, включите пункт [c], отключите пункт [d] и сделайте фото лога.",0
remarks dw remark1, remark2, remark3
num_remarks = 3
remark1:cp866 "Значения по умолчанию выбраны для удобства большинства, но не всех.",0
remark2:cp866 "Если у Вас не грузится система, попробуйте отключить пункт [b].",0
remarks dw remark1, remark2
num_remarks = 2
/kernel/branches/Kolibri-acpi/boot/bootsp.inc
17,24 → 17,26
 
 
d80x25_bottom:
cp850 '║ KolibriOS viene ABSOLUTAMENTE SIN GARANTíA. Lee el archivo COPYING por más ║'
cp850 '║ detalles. Por favor, informar de los errores en: http://board.kolibrios.org ║'
cp850 '║ KolibriOS y viene ABSOLUTAMENTE SIN GARANTíA. '
cp850 ' ║'
cp850 '║ Lee el archivo COPYING por más detalles '
cp850 ' ║'
line_full_bottom
d80x25_bottom_num = 3
 
msg_apm cp850 " APM x.x ", 0
novesa cp850 "Monitor: EGA/CGA",13,10,0
s_vesa cp850 "Versión de VESA: "
msg_apm: cp850 " APM x.x ", 0
novesa: cp850 "Monitor: EGA/CGA",13,10,0
s_vesa: cp850 "Versión de VESA: "
.ver db "?.?",13,10,0
 
gr_mode cp850 "Selecciona un modo de video: ",13,10,0
gr_mode: cp850 "Selecciona un modo de video: ",13,10,0
 
ask_bd cp850 "¿Agregar discos visibles por el BIOS emulados en modo V86? [1-si, 2-no]: ",0
ask_bd: cp850 "¿Agregar discos visibles por el BIOS emulados en modo V86? [1-si, 2-no]: ",0
 
if defined extended_primary_loader
bdev cp850 "Cargar unidad ram desde [1-disquete; 2-kolibri.img]: ",0
bdev: cp850 "Cargar unidad ram desde [1-disquete; 2-kolibri.img]: ",0
else
bdev cp850 "Cargar unidad ram desde [1-disquete; 2-C:\kolibri.img (FAT32);"
bdev: cp850 "Cargar unidad ram desde [1-disquete; 2-C:\kolibri.img (FAT32);"
cp850 13,10,"║ "
cp850 "3-usar imagen precargada en el reinicio del núcleo;"
cp850 13,10,"║ "
41,68 → 43,67
cp850 "4-crear imagen vacía]: ",0
end if
 
prnotfnd cp850 "Fatal - Modo de video no encontrado.",0
prnotfnd: cp850 "Fatal - Modo de video no encontrado.",0
 
not386 cp850 "Fatal - CPU 386+ requerido.",0
fatalsel cp850 "Fatal - Modo de gráficos no soportado por hardware.",0
pres_key cp850 "Presiona una tecla para seleccionar otro modo de video.",0
badsect cp850 13,10,"║ Fatal - Sector mal. Reemplaze el disquete.",0
memmovefailed cp850 13,10,"║ Fatal - Int 0x15 move failed.",0
okt cp850 " ... BIEN"
linef cp850 13,10,0
diskload cp850 "Cargando disquete: 00 %",8,8,8,8,0
pros cp850 "00"
backspace2 cp850 8,8,0
not386: cp850 "Fatal - CPU 386+ requerido.",0
fatalsel: cp850 "Fatal - Modo de gráficos no soportado por hardware.",0
pres_key: cp850 "Presiona una tecla para seleccionar otro modo de video.",0
badsect: cp850 13,10,"║ Fatal - Sector mal. Reemplaze el disquete.",0
memmovefailed:cp850 13,10,"║ Fatal - Int 0x15 move failed.",0
okt: cp850 " ... BIEN"
linef: cp850 13,10,0
diskload: cp850 "Cargando disquete: 00 %",8,8,8,8,0
pros: cp850 "00"
backspace2:cp850 8,8,0
boot_dev db 0 ; 0=floppy, 1=hd
start_msg cp850 "Presiona [abcde] para cambiar la configuración, [Enter] para continuar",13,10,0
time_msg cp850 " o espera "
time_str cp850 " 5 segundos"
start_msg:cp850 "Presiona [abcde] para cambiar la configuración, [Enter] para continuar",13,10,0
time_msg: cp850 " o espera "
time_str: cp850 " 5 segundos"
cp850 " para que inicie automáticamente",13,10,0
current_cfg_msg cp850 "Configuración actual:",13,10,0
curvideo_msg cp850 " [a] Modo de video: ",0
current_cfg_msg:cp850 "Configuración actual:",13,10,0
curvideo_msg:cp850 " [a] Modo de video: ",0
 
mode0 cp850 "320x200, EGA/CGA 256 colores",13,10,0
mode9 cp850 "640x480, VGA 16 colores",13,10,0
mode0: cp850 "320x200, EGA/CGA 256 colores",13,10,0
mode9: cp850 "640x480, VGA 16 colores",13,10,0
 
usebd_msg cp850 " [b] Agregar discos visibles por el BIOS:",0
on_msg cp850 " activado",13,10,0
off_msg cp850 " desactivado",13,10,0
usebd_msg:cp850 " [b] Agregar discos visibles por el BIOS:",0
on_msg: cp850 " activado",13,10,0
off_msg: cp850 " desactivado",13,10,0
 
debug_mode_msg cp850 " [c] Duplicar depurar salida a la pantalla:",0
ask_debug cp850 "¿Duplicar depurar la salida a la pantalla? [1-si, 2-no]: ",0
debug_mode_msg: cp850 " [c] Duplicar depurar salida a la pantalla:",0
ask_debug: cp850 "¿Duplicar depurar la salida a la pantalla? [1-si, 2-no]: ",0
 
launcher_msg cp850 " [d] Iniciar LAUNCHER después de cargar kernel:",0
ask_launcher cp850 "¿Inicie la primera aplicación después de cargar el kernel? [1-si, 2-no]: ",0
launcher_msg: cp850 " [d] Iniciar LAUNCHER después de cargar kernel:",0
ask_launcher: cp850 "¿Inicie la primera aplicación después de cargar el kernel? [1-si, 2-no]: ",0
 
preboot_device_msg cp850 " [e] Imagen de disquete: ",0
preboot_device_msg:cp850 " [e] Imagen de disquete: ",0
 
if defined extended_primary_loader
preboot_device_msgs dw 0,pdm1,pdm2,0
pdm1 cp850 "disquete real",13,10,0
pdm2 cp850 "C:\kolibri.img (FAT32)",13,10,0
pdm1: cp850 "disquete real",13,10,0
pdm2: cp850 "C:\kolibri.img (FAT32)",13,10,0
else
preboot_device_msgs dw 0,pdm1,pdm2,pdm3,pdm4,0
pdm1 cp850 "disquete real",13,10,0
pdm2 cp850 "C:\kolibri.img (FAT32)",13,10,0
pdm3 cp850 "usar imagen ya cargada",13,10,0
pdm4 cp850 "crear imagen vacía",13,10,0
preboot_device_msgs dw 0,pdm1,pdm2,pdm3
pdm1: cp850 "disquete real",13,10,0
pdm2: cp850 "C:\kolibri.img (FAT32)",13,10,0
pdm3: cp850 "usar imagen ya cargada",13,10,0
pdm4: cp850 "crear imagen vacía",13,10,0
end if
 
loading_msg cp850 "Cargando KolibriOS...",0
loading_msg:cp850 "Cargando KolibriOS...",0
 
if ~ defined extended_primary_loader
save_quest cp850 "¿Recordar configuración actual? [s/n]: ",0
loader_block_error cp850 "Bootloader inválido, no puedo continuar. Detenido.",0
save_quest:cp850 "¿Recordar configuración actual? [s/n]: ",0
loader_block_error:cp850 "Bootloader inválido, no puedo continuar. Detenido.",0
end if
 
_st cp850 '║ ┌───────────────────────────────┬─┐',13,10,0
_r1 cp850 '║ │ 320x200 EGA/CGA 256 colores │ │',13,10,0
_r2 cp850 '║ │ 640x480 VGA 16 colores │ │',13,10,0
_rs cp850 '║ │ ????x????@?? SVGA VESA │ │',13,10,0
_bt cp850 '║ └───────────────────────────────┴─┘',13,10,0
_st:cp850 '║ ┌───────────────────────────────┬─┐',13,10,0
_r1:cp850 '║ │ 320x200 EGA/CGA 256 colores │ │',13,10,0
_r2:cp850 '║ │ 640x480 VGA 16 colores │ │',13,10,0
_rs:cp850 '║ │ ????x????@?? SVGA VESA │ │',13,10,0
_bt:cp850 '║ └───────────────────────────────┴─┘',13,10,0
 
remark1 cp850 "Los valores por defecto puede que no funcionen en algunas configuraciones.",0
remark2 cp850 "Si el sistema no inicia, prueba deshabilitar la opción [b]. Si se bloquea",0
remark3 cp850 "después de arrancar, habilite la opción [c], desactivar [d] y hacer fotos.",0
remarks dw remark1, remark2, remark3
num_remarks = 3
remark1:cp850 "Los valores por defecto puede que no funcionen en algunas configuraciones.",0
remark2:cp850 "Si el sistema no inicia, prueba deshabilitar la opción [b].",0
remarks dw remark1, remark2
num_remarks = 2
/kernel/branches/Kolibri-acpi/boot/bootvesa.inc
79,7 → 79,6
modes_table:
end virtual
cursor_pos dw 0 ;временное хранение курсора.
cursor_pos_old dw 0
home_cursor dw 0 ;current shows rows a table
end_cursor dw 0 ;end of position current shows rows a table
scroll_start dw 0 ;start position of scroll bar
/kernel/branches/Kolibri-acpi/boot/et.inc
9,7 → 9,7
 
 
; Full ASCII code font
; only õ,ä,ü added
; only õ and ä added
; Kaitz
ET_FNT:
fontfile file "ETFONT.FNT"
/kernel/branches/Kolibri-acpi/core/clipboard.inc
File deleted
/kernel/branches/Kolibri-acpi/core/dll.inc
458,6 → 458,7
push edi
push ebx
 
 
lea eax, [attr]
stdcall get_fileinfo, [file_name], eax ;find file and get info
test eax, eax
483,26 → 484,11
 
mov ebx, [eax+4] ;get real size of file
mov [file_size], ebx
stdcall user_alloc, ebx ;and allocate space from user heap
stdcall user_alloc, ebx ;and allocate memory from user heap
mov [um_file], eax
test eax, eax
jz .err_2
 
mov edx, [file_size] ;preallocate page memory
shr eax, 10
lea edi, [page_tabs+eax]
add edx, 4095
shr edx, 12
@@:
call alloc_page
test eax, eax
jz .err_3
 
or eax, PG_UW
stosd
dec edx
jnz @B
 
pushad
mov ecx, unpack_mutex
call mutex_lock
515,22 → 501,8
 
stdcall kernel_free, [km_file] ;we don't need packed file anymore
.exit:
 
mov edi, [um_file]
mov esi, [um_file]
mov eax, [file_size]
mov edx, eax
 
add edi, eax ;cleanup remain space
mov ecx, 4096 ;from file end
and eax, 4095
jz @f
sub ecx, eax
xor eax, eax
cld
rep stosb
@@:
mov eax, [um_file]
mov edx, [file_size]
 
pop ebx
pop edi
537,6 → 509,7
pop esi
ret
 
 
.raw_file: ; sometimes we load unpacked file
stdcall user_alloc, ebx ; allocate space from user heap
mov [um_file], eax
560,14 → 533,13
@@:
lodsd
and eax, 0xFFFFF000
or eax, PG_UW
or eax, PG_USER
stosd
loop @B
 
stdcall free_kernel_space, [km_file] ; release allocated kernel space
jmp .exit ; physical pages still in use
.err_3:
stdcall user_free, [um_file]
 
.err_2:
stdcall kernel_free, [km_file]
.err_1:
/kernel/branches/Kolibri-acpi/core/exports.inc
82,8 → 82,6
delete_keyboard, 'DelKeyboard', \
get_cpu_freq, 'GetCpuFreq', \
\
new_sys_threads, 'CreateThread', \ ; ebx, ecx, edx
\
srv_handler, 'ServiceHandler', \
fpu_save, 'FpuSave', \
fpu_restore, 'FpuRestore', \
/kernel/branches/Kolibri-acpi/core/sys32.inc
247,84 → 247,7
DEBUGF 1, "K : EDX : %x ESI : %x EDI : %x\n", [reg_edx+4], [reg_esi+4], [reg_edi+4]
DEBUGF 1, "K : EBP : %x EIP : %x ESP : %x\n", [reg_ebp+4], [reg_eip+4], ebx
DEBUGF 1, "K : Flags : %x CS : %x (%s)\n", [reg_eflags+4], eax, edi
 
DEBUGF 1, "K : Stack dump:\n"
push eax ebx ecx edx
call .check_ESP
test eax, eax
jnz .error_ESP
DEBUGF 1, "K : [ESP+00]: %x",[ebx]
add ebx, 4
call .check_ESP
test eax, eax
jnz .error_ESP
DEBUGF 1, " [ESP+04]: %x",[ebx]
add ebx, 4
call .check_ESP
test eax, eax
jnz .error_ESP
DEBUGF 1, " [ESP+08]: %x\n",[ebx]
add ebx, 4
call .check_ESP
test eax, eax
jnz .error_ESP
DEBUGF 1, "K : [ESP+12]: %x",[ebx]
add ebx, 4
call .check_ESP
test eax, eax
jnz .error_ESP
DEBUGF 1, " [ESP+16]: %x",[ebx]
add ebx, 4
call .check_ESP
test eax, eax
jnz .error_ESP
DEBUGF 1, " [ESP+20]: %x\n",[ebx]
add ebx, 4
call .check_ESP
test eax, eax
jnz .error_ESP
DEBUGF 1, "K : [ESP+24]: %x",[ebx]
add ebx, 4
call .check_ESP
test eax, eax
jnz .error_ESP
DEBUGF 1, " [ESP+28]: %x",[ebx]
add ebx, 4
call .check_ESP
test eax, eax
jnz .error_ESP
DEBUGF 1, " [ESP+32]: %x\n",[ebx]
pop edx ecx ebx eax
ret
.error_ESP:
pop edx ecx ebx eax
DEBUGF 1, "\n"
DEBUGF 1, "K : Unexpected end of the stack\n"
ret
;--------------------------------------
.check_ESP:
push ebx
shr ebx, 12
mov ecx, ebx
shr ecx, 10
mov edx, [master_tab+ecx*4]
test edx, PG_MAP
jz .fail ;page table is not created
;incorrect address in the program
 
mov eax, [page_tabs+ebx*4]
test eax, 2
jz .fail ;address not reserved for use. error
pop ebx
xor eax, eax
ret
.fail:
pop ebx
xor eax, eax
dec eax
ret
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 
restore reg_ss
/kernel/branches/Kolibri-acpi/core/syscall.inc
184,7 → 184,7
dd syscall_threads ; 51-Threads
dd undefined_syscall ; 52- deprecated Stack driver status
dd undefined_syscall ; 53- deprecated Socket interface
dd sys_clipboard ; 54-Custom clipboard
dd undefined_syscall ; 54-reserved
dd sound_interface ; 55-Sound interface
dd undefined_syscall ; 56-reserved
dd sys_pcibios ; 57-PCI BIOS32
/kernel/branches/Kolibri-acpi/core/taskman.inc
924,17 → 924,10
ret
endp
 
;ebx = 1 - kernel thread
;ecx=thread entry point
;edx=thread stack pointer
;creation flags 0x01 - debugged
; 0x02 - kernel
 
align 4
proc new_sys_threads
locals
slot dd ?
flags dd ?
app_cmdline dd ? ;0x00
app_path dd ? ;0x04
app_eip dd ? ;0x08
942,8 → 935,8
app_mem dd ? ;0x10
endl
 
shl ebx, 1
mov [flags], ebx
cmp ebx, 1
jne .failed ;other subfunctions
 
xor eax, eax
mov [app_eip], ecx
950,7 → 943,8
mov [app_cmdline], eax
mov [app_esp], edx
mov [app_path], eax
 
;mov esi,new_process_loading
;call sys_msg_board_str
call lock_application_table
 
call get_new_process_place
1004,8 → 998,10
 
lea eax, [app_cmdline]
stdcall set_app_params , [slot], eax, dword 0, \
dword 0, [flags]
dword 0,dword 0
 
;mov esi,new_process_running
;call sys_msg_board_str ;output information about succefull startup
mov eax, [process_number] ;set result
call unlock_application_table
ret
1211,13 → 1207,14
mov [ebx+REG_EIP], eax;app_entry
mov [ebx+REG_CS], dword app_code
mov ecx, USER_PRIORITY
 
test byte [flags], 2
jz @F
 
mov eax, [CURRENT_TASK]
shl eax, 8 ; created by kernel?
cmp [SLOT_BASE+eax+APPDATA.dir_table], sys_pgdir - OS_BASE
jnz @f
cmp [app_path], 0 ; it is a thread?
jnz @f
mov [ebx+REG_CS], dword os_code ; kernel thread
mov ecx, MAX_PRIORITY
 
@@:
mov [ebx+REG_EFLAGS], dword EFL_IOPL1+EFL_IF
 
1241,6 → 1238,8
mov [CURRENT_TASK+ebx+TASKDATA.state], dl
lea edx, [SLOT_BASE+ebx*8]
call scheduler_add_thread
;mov esi,new_process_running
;call sys_msg_board_str ;output information about succefull startup
ret
endp
 
/kernel/branches/Kolibri-acpi/core/conf_lib-sp.inc
1,11 → 1,11
; Éste archivo debe ser editado con codificación CP866
 
ugui_mouse_speed cp850 'velocidad del ratón',0
ugui_mouse_delay cp850 'demora del ratón',0
ugui_mouse_speed:cp850 'velocidad del ratón',0
ugui_mouse_delay:cp850 'demora del ratón',0
 
udev cp850 'disp',0
unet cp850 'red',0
unet_active cp850 'activa',0
unet_addr cp850 'direc',0
unet_mask cp850 'másc',0
unet_gate cp850 'puer',0
udev:cp850 'disp',0
unet:cp850 'red',0
unet_active:cp850 'activa',0
unet_addr:cp850 'direc',0
unet_mask:cp850 'másc',0
unet_gate:cp850 'puer',0
/kernel/branches/Kolibri-acpi/core/sys32-sp.inc
1,4 → 1,4
; Éste archivo debe ser editado con codificación CP866
 
msg_sel_ker cp850 "núcleo", 0
msg_sel_app cp850 "aplicación", 0
msg_sel_ker: cp850 "núcleo", 0
msg_sel_app: cp850 "aplicación", 0
/kernel/branches/Kolibri-acpi/data32.inc
49,50 → 49,48
 
 
if lang eq ru
boot_initirq cp866 'Инициализация IRQ',0
boot_picinit cp866 'Инициализация PIC',0
boot_v86machine cp866 'Инициализация системы V86 машины',0
boot_inittimer cp866 'Инициализация системного таймера (IRQ0)',0
boot_initapic cp866 'Попытка инициализации APIC',0
boot_enableirq cp866 'Включить прерывания 2, 13',0
boot_disabling_ide cp866 'Запрещение прерываний в контроллере IDE',0
boot_enabling_ide cp866 'Разрешение прерываний в контроллере IDE',0
boot_set_int_IDE cp866 'Установка обработчиков прерываний IDE',0
boot_detectfloppy cp866 'Поиск floppy дисководов',0
boot_detecthdcd cp866 'Поиск жестких дисков и ATAPI приводов',0
boot_getcache cp866 'Получение памяти для кэша',0
boot_detectpart cp866 'Поиск разделов на дисковых устройствах',0
boot_init_sys cp866 'Инициализация системного каталога /sys',0
boot_loadlibs cp866 'Загрузка библиотек (.obj)',0
boot_memdetect cp866 'Количество оперативной памяти',' ',' Мб',0
boot_tss cp866 'Установка TSSs',0
boot_cpuid cp866 'Чтение CPUIDs',0
; boot_devices cp866 'Поиск устройств',0
boot_timer cp866 'Установка таймера',0
boot_irqs cp866 'Переопределение IRQ',0
boot_setmouse cp866 'Установка мыши',0
boot_windefs cp866 'Установка настроек окон по умолчанию',0
boot_bgr cp866 'Установка фона',0
boot_resirqports cp866 'Резервирование IRQ и портов',0
boot_setrports cp866 'Установка адресов IRQ',0
boot_setostask cp866 'Создание процесса ядра',0
boot_allirqs cp866 'Открытие всех IRQ',0
boot_tsc cp866 'Чтение TSC',0
boot_cpufreq cp866 'Частота процессора ',' ',' МГц',0
boot_pal_ega cp866 'Установка EGA/CGA 320x200 палитры',0
boot_pal_vga cp866 'Установка VGA 640x480 палитры',0
boot_failed cp866 'Загрузка первого приложения не удалась',0
boot_mtrr cp866 'Установка MTRR',0
boot_initirq: cp866 'Инициализация IRQ',0
boot_picinit: cp866 'Инициализация PIC',0
boot_v86machine: cp866 'Инициализация системы V86 машины',0
boot_inittimer: cp866 'Инициализация системного таймера (IRQ0)',0
boot_initapic: cp866 'Попытка инициализации APIC',0
boot_enableirq: cp866 'Включить прерывания 2, 13',0
boot_disabling_ide:cp866 'Запрещение прерываний в контроллере IDE',0
boot_enabling_ide:cp866 'Разрешение прерываний в контроллере IDE',0
boot_set_int_IDE: cp866 'Установка обработчиков прерываний IDE',0
boot_detectfloppy:cp866 'Поиск floppy дисководов',0
boot_detecthdcd: cp866 'Поиск жестких дисков и ATAPI приводов',0
boot_getcache: cp866 'Получение памяти для кэша',0
boot_detectpart: cp866 'Поиск разделов на дисковых устройствах',0
boot_init_sys: cp866 'Инициализация системного каталога /sys',0
boot_loadlibs: cp866 'Загрузка библиотек (.obj)',0
boot_memdetect: cp866 'Количество оперативной памяти',' ',' Мб',0
boot_tss: cp866 'Установка TSSs',0
boot_cpuid: cp866 'Чтение CPUIDs',0
; boot_devices: cp866 'Поиск устройств',0
boot_timer: cp866 'Установка таймера',0
boot_irqs: cp866 'Переопределение IRQ',0
boot_setmouse: cp866 'Установка мыши',0
boot_windefs: cp866 'Установка настроек окон по умолчанию',0
boot_bgr: cp866 'Установка фона',0
boot_resirqports: cp866 'Резервирование IRQ и портов',0
boot_setrports: cp866 'Установка адресов IRQ',0
boot_setostask: cp866 'Создание процесса ядра',0
boot_allirqs: cp866 'Открытие всех IRQ',0
boot_tsc: cp866 'Чтение TSC',0
boot_cpufreq: cp866 'Частота процессора ',' ',' МГц',0
boot_pal_ega: cp866 'Установка EGA/CGA 320x200 палитры',0
boot_pal_vga: cp866 'Установка VGA 640x480 палитры',0
boot_failed: cp866 'Загрузка первого приложения не удалась',0
boot_mtrr: cp866 'Установка MTRR',0
 
boot_APIC_found cp866 'APIC включен', 0
boot_APIC_nfound cp866 'APIC не найден', 0
boot_APIC_found: cp866 'APIC включен', 0
boot_APIC_nfound: cp866 'APIC не найден', 0
if preboot_blogesc
boot_tasking cp866 'Все готово для запуска, нажмитре ESC для старта',0
boot_tasking: cp866 'Все готово для запуска, нажмитре ESC для старта',0
end if
else if lang eq sp
include 'data32sp.inc'
else if lang eq et
include 'data32et.inc'
else
boot_initirq db 'Initialize IRQ',0
boot_picinit db 'Initialize PIC',0
165,7 → 163,7
firstapp db 'LAUNCHER',0
notifyapp db '@notify',0
if lang eq ru
ud_user_message cp866 'Ошибка: неподдерживаемая инструкция процессора',0
ud_user_message: cp866 'Ошибка: неподдерживаемая инструкция процессора',0
else if ~ lang eq sp
ud_user_message db 'Error: unsupported processor instruction',0
end if
387,7 → 385,7
REDRAW_BACKGROUND rb 4
 
align 4
draw_data: rb 32*256
draw_data: rb 16*256
BPSLine_calc_area rd 1440
d_width_calc_area rd 1140
 
/kernel/branches/Kolibri-acpi/detect/vortex86.inc
File deleted
\ No newline at end of file
/kernel/branches/Kolibri-acpi/docs/events_subsystem.txt
File deleted
\ No newline at end of file
/kernel/branches/Kolibri-acpi/docs/usbapi_ru.txt
File deleted
\ No newline at end of file
/kernel/branches/Kolibri-acpi/docs/sysfuncr.txt
34,7 → 34,7
вызов функции с такими Y игнорируется
* RR, GG, BB = соответственно красная, зеленая, синяя
составляющие цвета рабочей области окна
(игнорируется для стиля Y=1)
(игнорируется для стиля Y=2)
* X = DCBA (биты)
* A = 1 - у окна есть заголовок; для стилей Y=3,4 адрес строки
заголовка задаётся в edi, для прочих стилей
47,7 → 47,7
игнорируются для стилей Y=1,3:
* esi = 0xXYRRGGBB - цвет заголовка
* RR, GG, BB определяют сам цвет
* Y=0 - обычное окно, Y=1 - неперемещаемое окно (работает для всех стилей окон)
* Y=0 - обычное окно, Y=1 - неперемещаемое окно
* X определяет градиент заголовка: X=0 - нет градиента,
X=8 - обычный градиент,
для окон типа II X=4 - негативный градиент
372,7 → 372,6
* бит 1 (маска 2): окно минимизировано в панель задач
* бит 2 (маска 4): окно свёрнуто в заголовок
* +71 = +0x47: dword: маска событий
* +75 = +0x4B: byte: режим ввода с клавиатуры(ASCII = 0; SCAN = 1)
Замечания:
* Слоты нумеруются с 1.
* Возвращаемое значение не есть общее число потоков, поскольку
417,7 → 416,7
положение и размеры этого окна полагаются нулями.
* Координаты клиентской области окна берутся относительно окна.
* В данный момент используется только часть буфера размером
76 = 0x4C байта. Тем не менее рекомендуется использовать буфер
71 = 0x47 байта. Тем не менее рекомендуется использовать буфер
размером 1 Кб для будущей совместимости, в будущем могут быть
добавлены некоторые поля.
 
1804,7 → 1803,7
sysdir_path rb 64
Пример:
dir_name1 db 'KolibriOS',0
rb 64-10
rb 64-8
dir_path1 db 'HD0/1',0
rb 64-6
Возвращаемое значение:
2028,14 → 2027,6
* eax = 40 - номер функции
* ebx = маска: бит i соответствует событию i+1 (см. список событий)
(установленный бит разрешает извещение о событии)
bit 31: фильтр активности событий мыши
bit 31 = 0 - неактивное окно всегда получает события от мыши
bit 31 = 1 - неактивное окно не получает события от мыши
bit 30: фильтр позиции курсора
bit 30 = 0 - окно принимает события мыши, если курсор
за пределами окна
bit 30 = 1 - окно не принимает события мыши, если курсор
за пределами окна
Возвращаемое значение:
* eax = предыдущее значение маски
Замечания:
2429,70 → 2420,6
* иначе eax = TID - идентификатор потока
 
======================================================================
====================== Функция 54, подфункция 0 ======================
============== Узнать количество слотов в буфере обмена. =============
======================================================================
Параметры:
* eax = 54 - номер функции
* ebx = 0 - номер подфункции
Возвращаемое значение:
* eax = количество слотов в буфере
* eax = -1 - отсутствует область главного списка
 
======================================================================
====================== Функция 54, подфункция 1 ======================
================== Считать данные из буфера обмена. ==================
======================================================================
Параметры:
* eax = 54 - номер функции
* ebx = 1 - номер подфункции
* eсx = номер слота
Возвращаемое значение:
* eax = если успешно - указатель на область памяти с данными
* eax = 1 - ошибка
* eax = -1 - отсутствует область главного списка
======================================================================
====================== Функция 54, подфункция 2 ======================
================== Записать данные в буфер обмена. ===================
======================================================================
Параметры:
* eax = 54 - номер функции
* ebx = 2 - номер подфункции
* eсx = количество копируемых байт
* edx = указатель на буфер под копируемые данные
Возвращаемое значение:
* eax = 0 - успешно
* eax = 1 - ошибка
* eax = -1 - отсутствует область главного списка
 
======================================================================
====================== Функция 54, подфункция 3 ======================
========= Удалить последний слот с данными в буфере обмена ===========
======================================================================
Параметры:
* eax = 54 - номер функции
* ebx = 3 - номер подфункции
Возвращаемое значение:
* eax = 0 - успешно
* eax = 1 - ошибка
* eax = -1 - отсутствует область главного списка
 
======================================================================
====================== Функция 54, подфункция 4 ======================
=================== Аварийный сброс блокировки буфера ================
======================================================================
Параметры:
* eax = 54 - номер функции
* ebx = 4 - номер подфункции
Возвращаемое значение:
* eax = 0 - успешно
* eax = -1 - отсутствует область главного списка или нет блокировки
Замечания:
* Используется в исключительных случаях, когда зависшее или убитое
приложение заблокировало работу с буфером обмена.
 
======================================================================
====================== Функция 55, подфункция 55 =====================
========== Начать проигрывать данные на встроенном спикере. ==========
======================================================================
3568,32 → 3495,6
номер сигнала соответствует номеру исключения.
 
======================================================================
= Функция 68, подфункция 26 - освободить страницы памяти ============
======================================================================
Параметры:
* eax = 68 - номер функции
* ebx = 26 - номер подфункции
* ecx = указатель на блок памяти выделенный подфункцией 12
* edx = смещение от начала блока
* esi = размер высвобождаемого блока памяти, в байтах
Примечания:
* функция освобождает страницы с ecx+edx по ecx+edx+esi
и устанавливает виртуальную память в зарезервированное состояние.
 
======================================================================
= Функция 68, подфункция 27 - загрузить файл ===================
======================================================================
Параметры:
* eax = 68 - номер функции
* ebx = 27 - номер подфункции
* ecx = указатель на ASCIIZ-строку с именем файла
Возвращаемое значение:
* eax = указатель на загруженный файл или 0
* edx = размер загруженного файла или 0
Примечания:
* функция загружает и, при необходимости, распаковывает файл (kunpack)
 
======================================================================
======================== Функция 69 - отладка. =======================
======================================================================
Процесс может загрузить другой процесс как отлаживаемый установкой
/kernel/branches/Kolibri-acpi/docs/sysfuncs.txt
33,7 → 33,7
* other possible values (from 5 up to 15) are reserved,
function call with such Y is ignored
* RR, GG, BB = accordingly red, green, blue components of a color
of the working area of the window (are ignored for style Y=1)
of the working area of the window (are ignored for style Y=2)
* X = DCBA (bits)
* A = 1 - window has caption; for styles Y=3,4 caption string
must be passed in edi, for other styles use
46,7 → 46,7
of a type I and II, and ignored for styles Y=1,3:
* esi = 0xXYRRGGBB - color of the header
* RR, GG, BB define color
* Y=0 - usual window, Y=1 - unmovable window (works for all window styles)
* Y=0 - usual window, Y=1 - unmovable window
* X defines a gradient of header: X=0 - no gradient,
X=8 - usual gradient,
for windows of a type II X=4 - negative gradient
367,7 → 367,6
* bit 1 (mask 2): window is minimized to panel
* bit 2 (mask 4): window is rolled up
* +71 = +0x47: dword: event mask
* +75 = +0x4B: byte: keyboard mode(ASCII = 0; SCAN = 1)
Remarks:
* Slots are numbered starting from 1.
* Returned value is not a total number of threads, because there
412,7 → 411,7
of its window are considered to be zero.
* Coordinates of the client area are relative to the window.
* At the moment only the part of the buffer by a size
76 = 0x4C bytes is used. Nevertheless it is recommended to use
71 = 0x37 bytes is used. Nevertheless it is recommended to use
1-Kb buffer for the future compatibility, in the future
some fields can be added.
 
1786,7 → 1785,7
sysdir_path rb 64
For example:
dir_name1 db 'KolibriOS',0
rb 64-10
rb 64-8
dir_path1 db 'HD0/1',0
rb 64-6
Returned value:
2011,7 → 2010,7
* eax = 40 - function number
* ebx = mask: bit i corresponds to event i+1 (see list of events)
(set bit permits notice on event)
bit 31: mouse active/inactive filter
bit 31: active/inactive filter
bit 31 = 0 - inactive window receive mouse events
bit 31 = 1 - inactive window does not receive mouse events
bit 30: cursor position filter
2412,70 → 2411,6
</UL>
 
======================================================================
==================== Function 54, subfunction 0 ======================
============== Get the number of slots in the clipboard. =============
======================================================================
Parameters:
* eax = 54 - function number
* ebx = 0 - subfunction number
Returned value:
* eax = slots in the clipboard
* eax = -1 - main list area not found
 
======================================================================
==================== Function 54, subfunction 1 ======================
================= Read the data from the clipboard. ==================
======================================================================
Parameters:
* eax = 54 - function number
* ebx = 1 - subfunction number
* eсx = slot number
Returned value:
* eax = if successful - pointer to a memory with data
* eax = 1 - error
* eax = -1 - main list area not found
 
======================================================================
==================== Function 54, subfunction 2 ======================
================= Write the data to the clipboard. ===================
======================================================================
Parameters:
* eax = 54 - function number
* ebx = 2 - subfunction number
* eсx = the number of bytes to be copied
* edx = a pointer to a buffer for data to be copied
Returned value:
* eax = 0 - success
* eax = 1 - error
* eax = -1 - main list area not found
======================================================================
===================== Function 54, subfunction 3 =====================
================ Delete the last slot in the clipboard ===============
======================================================================
Parameters:
* eax = 54 - function number
* ebx = 3 - subfunction number
Returned value:
* eax = 0 - success
* eax = 1 - error
* eax = -1 - main list area not found
======================================================================
===================== Function 54, subfunction 4 =====================
===================== Alarm reset the lock buffer ====================
======================================================================
Parameters:
* eax = 54 - function number
* ebx = 4 - subfunction number
Returned value:
* eax = 0 - success
* eax = -1 - main list area not found or no blocking
Remarks:
* Used in exceptional cases, where no responsible or killed
application blocked the clipboard operations.
 
======================================================================
Function 55, subfunction 55 - begin to play data on built-in speaker.
======================================================================
Parameters:
4018,7 → 3953,7
* +0: dword: 2 = subfunction number
* +4: dword: 0 (reserved)
* +8: dword: 0 (reserved)
* +12 = +0xC: dword: number of bytes to write
* +12 = +0xC: dword: number of bytes to read
* +16 = +0x10: dword: pointer to data
* +20 = +0x14: ASCIIZ-name of file, the rules of names forming are
given in the general description
/kernel/branches/Kolibri-acpi/drivers/imports.inc
60,7 → 60,6
CreateRingBuffer,\
\
GetPid,\
CreateThread,\
CreateObject,\
DestroyObject,\
CreateEvent,\
/kernel/branches/Kolibri-acpi/drivers/usbstor.asm
1002,12 → 1002,13
; to allow the USB thread to continue working and handling those requests.
; 4. Thus, create a temporary kernel thread which would do it.
mov edx, [esp+8]
push ebx ecx esi edi
push ebx ecx
movi eax, 51
movi ebx, 1
mov ecx, new_disk_thread
; edx = parameter
call CreateThread
pop edi esi ecx ebx
int 0x40
pop ecx ebx
cmp eax, -1
jnz .nothing
; on error, reverse step 3
/kernel/branches/Kolibri-acpi/fs/xfs.asm
File deleted
/kernel/branches/Kolibri-acpi/fs/fs-et.inc
File deleted
\ No newline at end of file
/kernel/branches/Kolibri-acpi/fs/xfs.inc
File deleted
/kernel/branches/Kolibri-acpi/fs/ext2/blocks.inc
File deleted
/kernel/branches/Kolibri-acpi/fs/ext2/inode.inc
File deleted
/kernel/branches/Kolibri-acpi/fs/ext2/ext2.inc
File deleted
\ No newline at end of file
/kernel/branches/Kolibri-acpi/fs/ext2/resource.inc
File deleted
\ No newline at end of file
/kernel/branches/Kolibri-acpi/fs/ext2/ext2.asm
File deleted
/kernel/branches/Kolibri-acpi/fs/ext2
Property changes:
Deleted: tsvn:logminsize
-5
\ No newline at end of property
/kernel/branches/Kolibri-acpi/fs/ext2.inc
0,0 → 1,1343
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; 02.02.2010 turbanoff - support 70.5 ;;
;; 23.01.2010 turbanoff - support 70.0 70.1 ;;
;; 21.06.2013 yogev_ezra - Translate Russian comments ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
EXT2_BAD_INO = 1
EXT2_ROOT_INO = 2
EXT2_ACL_IDX_INO = 3
EXT2_ACL_DATA_INO = 4
EXT2_BOOT_LOADER_INO = 5
EXT2_UNDEL_DIR_INO = 6
 
;RUS: флаги, указываемые в inode файла ;ENG: flags specified in file inode
EXT2_S_IFREG = 0x8000
EXT2_S_IFDIR = 0x4000
EXT2_S_IFMT = 0xF000 ;RUS: маска для типа файла ;ENG: mask for file type
 
;RUS: флаги, указываемые в linked list родительской папки
;ENG: flags specified in linked list of parent folder
EXT2_FT_REG_FILE = 1 ;RUS: это файл, запись в родительском каталоге
;ENG: this is a file, record in parent catalog
EXT2_FT_DIR = 2 ;RUS: это папка ;ENG: this is a folder
 
;RUS: флаги используемые KolibriOS ;ENG: flags used by KolibriOS
FS_FT_HIDDEN = 2
FS_FT_DIR = 0x10 ;RUS: это папка ;ENG: this is a folder
FS_FT_ASCII = 0 ;RUS: имя в ascii ;ENG: name in ASCII
FS_FT_UNICODE = 1 ;RUS: имя в unicode ;ENG: name in UNICODE
 
EXT2_FEATURE_INCOMPAT_FILETYPE = 0x0002 ;RUS: тип файла должен указываться в директории
;ENG: file type must be specified in the folder
EXT4_FEATURE_INCOMPAT_EXTENTS = 0x0040 ;RUS: экстенты ;ENG: extents
EXT4_FEATURE_INCOMPAT_FLEX_BG = 0x0200 ;RUS: гибкие группы блоков ;ENG: flexible block groups
 
;RUS: реализованные ext[234] features ;ENG: implemented ext[234] features
EXT4_FEATURE_INCOMPAT_SUPP = EXT2_FEATURE_INCOMPAT_FILETYPE \
or EXT4_FEATURE_INCOMPAT_EXTENTS \
or EXT4_FEATURE_INCOMPAT_FLEX_BG
 
;RUS: флаги, указываемые для inode в i_flags ;ENG: flags specified for inode in i_flags
EXT2_EXTENTS_FL = 0x00080000
 
struct EXT2_INODE_STRUC
i_mode dw ?
i_uid dw ?
i_size dd ?
i_atime dd ?
i_ctime dd ?
i_mtime dd ?
i_dtime dd ?
i_gid dw ?
i_links_count dw ?
i_blocks dd ?
i_flags dd ?
i_osd1 dd ?
i_block rd 15
i_generation dd ?
i_file_acl dd ?
i_dir_acl dd ?
i_faddr dd ?
i_osd2 dd ? ; 1..12
ends
 
struct EXT2_DIR_STRUC
inode dd ?
rec_len dw ?
name_len db ?
file_type db ?
name db ? ; 0..255
ends
 
struct EXT2_BLOCK_GROUP_DESC
block_bitmap dd ? ;+0
inode_bitmap dd ? ;+4
inode_table dd ? ;+8
free_blocks_count dw ? ;+12
free_inodes_count dw ? ;+14
used_dirs_count dw ? ;+16
pad dw ? ;+18
reserved rb 12;+20
ends
 
struct EXT2_SB_STRUC
inodes_count dd ? ;+0
blocks_count dd ? ;+4
r_block_count dd ? ;+8
free_block_count dd ? ;+12
free_inodes_count dd ? ;+16
first_data_block dd ? ;+20
log_block_size dd ? ;+24
log_frag_size dd ? ;+28
blocks_per_group dd ? ;+32
frags_per_group dd ? ;+36
inodes_per_group dd ? ;+40
mtime dd ? ;+44
wtime dd ? ;+48
mnt_count dw ? ;+52
max_mnt_count dw ? ;+54
magic dw ? ;+56
state dw ? ;+58
errors dw ? ;+60
minor_rev_level dw ? ;+62
lastcheck dd ? ;+64
check_intervals dd ? ;+68
creator_os dd ? ;+72
rev_level dd ? ;+76
def_resuid dw ? ;+80
def_resgid dw ? ;+82
first_ino dd ? ;+84
inode_size dw ? ;+88
block_group_nr dw ? ;+90
feature_compat dd ? ;+92
feature_incompat dd ? ;+96
feature_ro_compat dd ? ;+100
uuid rb 16 ;+104
volume_name rb 16 ;+120
last_mounted rb 64 ;+136
algo_bitmap dd ? ;+200
prealloc_blocks db ? ;+204
preallock_dir_blocks db ? ;+205
reserved_gdt_blocks dw ? ;+206
journal_uuid rb 16 ;+208
journal_inum dd ? ;+224
journal_dev dd ? ;+228
last_orphan dd ? ;+232
hash_seed rd 4 ;+236
def_hash_version db ? ;+252
rb 3 ;+253 reserved
default_mount_options dd ? ;+256
first_meta_bg dd ? ;+260
mkfs_time dd ? ;+264
jnl_blocks rd 17 ;+268
blocks_count_hi dd ? ;+336
r_blocks_count_hi dd ? ;+340
free_blocks_count_hi dd ? ;+344
min_extra_isize dw ? ;+348
want_extra_isize dw ? ;+350
flags dd ? ;+352
raid_stride dw ? ;+356
mmp_interval dw ? ;+358
mmp_block dq ? ;+360
raid_stripe_width dd ? ;+368
log_groups_per_flex db ? ;+372
ends
 
struct EXT4_EXTENT_HEADER ;RUS: заголовок блока экстентов/индексов
eh_magic dw ? ;RUS: в текущей реализации ext4 должно быть 0xF30A
eh_entries dw ? ;RUS: количество экстентов/индексов в блоке
eh_max dw ? ;RUS: max количество (используется при записи)
eh_depth dw ? ;RUS: глубина дерева (0, если это блок экстентов)
eh_generation dd ? ;???
ends
 
struct EXT4_EXTENT ;RUS: экстент ;ENG: extent
ee_block dd ? ;RUS: номер ext4 блока ;ENG: number of ext4 block
ee_len dw ? ;RUS: длина экстента ;ENG: extent length
ee_start_hi dw ? ;RUS: старшие 16 бит 48-битного адреса (пока не используются в KOS)
;ENG: upper 16 bits of the 48-bit address (not used in KolibriOS yet)
ee_start_lo dd ? ;RUS: младшие 32 бита 48-битного адреса
;ENG: lower 32 bits of the 48-bit address
ends
 
struct EXT4_EXTENT_IDX ;RUS: индекс - указатель на блок с экстентами/индексами
;ENG: index - pointer to block of extents/indexes
ei_block dd ? ;RUS: номер ext4 блока ;ENG: number of ext4 block
ei_leaf_lo dd ? ;RUS: младшие 32 бит 48-битного адреса
;ENG: lower 32 bits of the 48-bit address
ei_leaf_hi dw ? ;RUS: старшие 16 бит 48-битного адреса (пока не используются в KOS)
;ENG: upper 16 bits of the 48-bit address (not used in KolibriOS yet)
ei_unused dw ? ;RUS: зарезервировано ;ENG: reserved
ends
 
struct EXTFS PARTITION
Lock MUTEX
log_block_size dd ?
block_size dd ?
count_block_in_block dd ?
blocks_per_group dd ?
global_desc_table dd ?
root_inode dd ? ; pointer to root inode in memory
inode_size dd ?
count_pointer_in_block dd ? ; block_size / 4
count_pointer_in_block_square dd ? ; (block_size / 4)**2
ext2_save_block dd ? ;RUS: блок на глобальную 1 процедуру ;ENG: block for 1 global procedure
ext2_temp_block dd ? ;RUS: блок для мелких процедур ;ENG: block for small procedures
ext2_save_inode dd ? ;RUS: inode на глобальную процедуру ;ENG: inode for global procedure
ext2_temp_inode dd ? ;RUS: inode для мелких процедур ;ENG: inode for small procedures
groups_count dd ?
superblock rd 512/4
ends
 
iglobal
align 4
ext2_user_functions:
dd ext2_free
dd (ext2_user_functions_end - ext2_user_functions - 4) / 4
dd ext2_Read
dd ext2_ReadFolder
dd ext2_Rewrite
dd ext2_Write
dd ext2_SetFileEnd
dd ext2_GetFileInfo
dd ext2_SetFileInfo
dd 0
dd ext2_Delete
dd ext2_CreateFolder
ext2_user_functions_end:
endg
 
proc ext2_create_partition
push ebx
 
mov eax, 2 ;superblock start at 1024b
add ebx, 512 ; get pointer to fs-specific buffer
call fs_read32_sys
 
cmp [ebx + EXT2_SB_STRUC.log_block_size], 3 ;0,1,2,3
ja .no
cmp [ebx + EXT2_SB_STRUC.magic], 0xEF53
jne .no
cmp [ebx + EXT2_SB_STRUC.state], 1 ;EXT_VALID_FS=1
jne .no
cmp [ebx + EXT2_SB_STRUC.inodes_per_group], 0
je .no
mov eax, [ebx + EXT2_SB_STRUC.feature_incompat]
test eax, EXT2_FEATURE_INCOMPAT_FILETYPE
jz .no
test eax, not EXT4_FEATURE_INCOMPAT_SUPP
jz ext2_setup
 
.no:
; No, this superblock isn't EXT2
pop ebx
xor eax, eax
ret
 
; OK, this is correct EXT2 superblock
ext2_setup:
movi eax, sizeof.EXTFS
call malloc
test eax, eax
jz ext2_create_partition.no
 
mov ecx, dword [ebp+PARTITION.FirstSector]
mov dword [eax+EXTFS.FirstSector], ecx
mov ecx, dword [ebp+PARTITION.FirstSector+4]
mov dword [eax+EXTFS.FirstSector+4], ecx
mov ecx, dword [ebp+PARTITION.Length]
mov dword [eax+EXTFS.Length], ecx
mov ecx, dword [ebp+PARTITION.Length+4]
mov dword [eax+EXTFS.Length+4], ecx
mov ecx, [ebp+PARTITION.Disk]
mov [eax+EXTFS.Disk], ecx
mov [eax+EXTFS.FSUserFunctions], ext2_user_functions
push ebp esi edi
mov ebp, eax
lea ecx, [eax+EXTFS.Lock]
call mutex_init
 
mov esi, ebx
lea edi, [ebp+EXTFS.superblock]
mov ecx, 512/4
rep movsd ; copy sb to reserved mem
 
mov eax, [ebx + EXT2_SB_STRUC.blocks_count]
sub eax, [ebx + EXT2_SB_STRUC.first_data_block]
dec eax
xor edx, edx
div [ebx + EXT2_SB_STRUC.blocks_per_group]
inc eax
mov [ebp+EXTFS.groups_count], eax
 
mov ecx, [ebx + EXT2_SB_STRUC.log_block_size]
inc ecx
mov [ebp+EXTFS.log_block_size], ecx ; 1, 2, 3, 4 equ 1kb, 2kb, 4kb, 8kb
 
mov eax, 1
shl eax, cl
mov [ebp+EXTFS.count_block_in_block], eax
 
shl eax, 7
mov [ebp+EXTFS.count_pointer_in_block], eax
mov edx, eax ;RUS: потом еще квадрат найдем ;ENG: we'll find a square later
 
shl eax, 2
mov [ebp+EXTFS.block_size], eax
 
push eax eax ; 2 kernel_alloc
 
mov eax, edx
mul edx
mov [ebp+EXTFS.count_pointer_in_block_square], eax
 
call kernel_alloc
mov [ebp+EXTFS.ext2_save_block], eax ; and for temp block
call kernel_alloc
mov [ebp+EXTFS.ext2_temp_block], eax ; and for get_inode proc
 
movzx eax, word [ebx + EXT2_SB_STRUC.inode_size]
mov ecx, [ebx + EXT2_SB_STRUC.blocks_per_group]
 
mov [ebp+EXTFS.inode_size], eax
mov [ebp+EXTFS.blocks_per_group], ecx
 
push eax eax eax ;3 kernel_alloc
call kernel_alloc
mov [ebp+EXTFS.ext2_save_inode], eax
call kernel_alloc
mov [ebp+EXTFS.ext2_temp_inode], eax
call kernel_alloc
mov [ebp+EXTFS.root_inode], eax
 
mov ebx, eax
mov eax, EXT2_ROOT_INO
call ext2_get_inode ; read root inode
 
mov eax, ebp ; return pointer to EXTFS
pop edi esi ebp ebx
ret
endp
 
proc ext2_free
push ebp
xchg ebp, eax
stdcall kernel_free, [ebp+EXTFS.ext2_save_block]
stdcall kernel_free, [ebp+EXTFS.ext2_temp_block]
stdcall kernel_free, [ebp+EXTFS.ext2_save_inode]
stdcall kernel_free, [ebp+EXTFS.ext2_temp_inode]
stdcall kernel_free, [ebp+EXTFS.root_inode]
xchg ebp, eax
call free
pop ebp
ret
endp
 
proc ext2_lock
lea ecx, [ebp+EXTFS.Lock]
jmp mutex_lock
endp
 
proc ext2_unlock
lea ecx, [ebp+EXTFS.Lock]
jmp mutex_unlock
endp
 
;==================================================================
;read ext2 block form FS to memory
;in: eax = i_block (address of block in ext2 terms)
; ebx = pointer to return memory
; ebp = pointer to EXTFS
;out: eax - error code (0 = no_error)
ext2_get_block:
push ebx ecx
mov ecx, [ebp+EXTFS.log_block_size]
shl eax, cl
mov ecx, eax
push [ebp+EXTFS.count_block_in_block]
@@:
mov eax, ecx
call fs_read32_sys
test eax, eax
jnz .fail
inc ecx
add ebx, 512
dec dword [esp]
jnz @B
pop ecx
xor eax, eax
@@:
pop ecx ebx
ret
.fail:
mov eax, ERROR_DEVICE
jmp @B
 
;===================================================================
;RUS: получает номер блока из extent inode ;ENG: receives block number from extent inode
;RUS: in: ecx = номер блока по порядку ;ENG: in: ecx = consecutive block number
;RUS: esi = адрес extent header`а ;ENG: esi = address of extent header
;RUS: ebp = указатель на структуру EXTFS ;ENG: ebp = pointer to EXTFS
;RUS: out: ecx - адрес очередного блока в случае успеха ;ENG: out: ecx - address of next block, if successful
;RUS: eax - номер ошибки (если равно 0, то ошибки нет) ;ENG: eax - error number (0 - no error)
ext4_block_recursive_search:
cmp word [esi + EXT4_EXTENT_HEADER.eh_magic], 0xF30A ;EXT4_EXT_MAGIC
jne .fail
movzx ebx, [esi + EXT4_EXTENT_HEADER.eh_entries]
add esi, sizeof.EXT4_EXTENT_HEADER
cmp word [esi - sizeof.EXT4_EXTENT_HEADER + EXT4_EXTENT_HEADER.eh_depth], 0
je .leaf_block ;листовой ли это блок?
;не листовой блок, а индексный ; eax - ext4_extent_idx
test ebx, ebx
jz .fail ;пустой индексный блок -> ошибка
 
;цикл по индексам экстентов
@@:
cmp ebx, 1 ;у индексов не хранится длина,
je .end_search_index ;поэтому, если остался последний - то это нужный
cmp ecx, [esi + EXT4_EXTENT_IDX.ei_block]
jb .fail
cmp ecx, [esi + sizeof.EXT4_EXTENT_IDX + EXT4_EXTENT_IDX.ei_block] ;блок слeдующего индекса
jb .end_search_index ;следующий дальше - значит текущий, то что нам нужен
add esi, sizeof.EXT4_EXTENT_IDX
dec ebx
jmp @B
.end_search_index:
;ebp указывает на нужный extent_idx, считываем следующий блок
mov ebx, [ebp+EXTFS.ext2_temp_block]
mov eax, [esi + EXT4_EXTENT_IDX.ei_leaf_lo]
call ext2_get_block
test eax, eax
jnz .fail
mov esi, ebx
jmp ext4_block_recursive_search ;рекурсивно прыгаем в начало
.leaf_block: ;листовой блок esi - ext4_extent
;цикл по экстентам
@@:
test ebx, ebx
jz .fail ;ни один узел не подошел - ошибка
 
mov edx, [esi + EXT4_EXTENT.ee_block]
cmp ecx, edx
jb .fail ;если меньше, значит он был в предыдущих блоках -> ошибка
 
movzx edi, [esi + EXT4_EXTENT.ee_len]
add edx, edi
cmp ecx, edx
jb .end_search_extent ;нашли нужный блок
add esi, sizeof.EXT4_EXTENT
dec ebx
jmp @B
.end_search_extent:
mov edx, [esi + EXT4_EXTENT.ee_start_lo]
sub ecx, [esi + EXT4_EXTENT.ee_block] ;разница в ext4 блоках
add ecx, edx
xor eax, eax
ret
 
.fail:
mov eax, ERROR_FS_FAIL
ret
 
;===================================================================
;получает адрес ext2 блока из inode с определнным номером
;RUS: in: ecx = номер блока в inode (0..) ;ENG: in: ecx = number of block in inode (0..)
;RUS: esi = адрес inode ;ENG: esi = inode address
;RUS: ebp = указатель на структуру EXTFS;ENG: ebp = pointer to EXTFS
;RUS: out: ecx = адрес очередного блока ;ENG: out: ecx = next block address
;RUS: eax - error code ;ENG: eax - error code
ext2_get_inode_block:
test [esi + EXT2_INODE_STRUC.i_flags], EXT2_EXTENTS_FL
jz @F
 
pushad
add esi, EXT2_INODE_STRUC.i_block ;esi - extent_header
call ext4_block_recursive_search
mov PUSHAD_ECX, ecx
mov PUSHAD_EAX, eax
popad
ret
 
@@:
cmp ecx, 12 ; 0..11 - direct block address
jb .get_direct_block
 
sub ecx, 12
cmp ecx, [ebp+EXTFS.count_pointer_in_block] ; 12.. - indirect blocks
jb .get_indirect_block
 
sub ecx, [ebp+EXTFS.count_pointer_in_block]
cmp ecx, [ebp+EXTFS.count_pointer_in_block_square]
jb .get_double_indirect_block
 
sub ecx, [ebp+EXTFS.count_pointer_in_block_square]
;triple indirect block
push edx ebx
 
mov eax, [esi + EXT2_INODE_STRUC.i_block + 14*4]
mov ebx, [ebp+EXTFS.ext2_temp_block]
call ext2_get_block
test eax, eax
jnz .fail
 
xor edx, edx
mov eax, ecx
div [ebp+EXTFS.count_pointer_in_block_square]
 
;RUS: eax - номер в полученном блоке edx - номер дальше
;ENG: eax - current block number, edx - next block number
mov eax, [ebx + eax*4]
call ext2_get_block
test eax, eax
jnz .fail
 
mov eax, edx
jmp @F
 
.get_double_indirect_block:
push edx ebx
 
mov eax, [esi + EXT2_INODE_STRUC.i_block + 13*4]
mov ebx, [ebp+EXTFS.ext2_temp_block]
call ext2_get_block
test eax, eax
jnz .fail
 
mov eax, ecx
@@:
xor edx, edx
div [ebp+EXTFS.count_pointer_in_block]
 
mov eax, [ebx + eax*4]
call ext2_get_block
test eax, eax
jnz .fail
 
mov ecx, [ebx + edx*4]
.fail:
pop ebx edx
ret
 
.get_indirect_block:
push ebx
mov eax, [esi + EXT2_INODE_STRUC.i_block + 12*4]
mov ebx, [ebp+EXTFS.ext2_temp_block]
call ext2_get_block
test eax, eax
jnz @F ;RUS: если не было ошибки ;ENG: if there was no error
 
mov ecx, [ebx + ecx*4] ;RUS: заносим результат ;ENG: ???
@@:
pop ebx
ret
 
.get_direct_block:
mov ecx, [esi + EXT2_INODE_STRUC.i_block + ecx*4]
xor eax, eax
ret
 
;===================================================================
;get content inode by num
;in: eax = inode_num
; ebx = address of inode content
; ebp = pointer to EXTFS
;out: eax - error code
ext2_get_inode:
pushad
mov edi, ebx ;сохраним адрес inode
dec eax
xor edx, edx
div [ebp + EXT2_SB_STRUC.inodes_per_group + EXTFS.superblock]
 
push edx ;locale num in group
 
mov edx, 32
mul edx ; address block_group in global_desc_table
 
;RUS: в eax - смещение группы с inode-ом относительно начала глобальной дескрипторной таблицы
;RUS: найдем блок в котором он находится
;ENG: in eax - inode group offset relative to global descriptor table start
;ENG: let's find the block this inode is in
div [ebp+EXTFS.block_size]
add eax, [ebp + EXT2_SB_STRUC.first_data_block + EXTFS.superblock]
inc eax
mov ebx, [ebp+EXTFS.ext2_temp_block]
call ext2_get_block
test eax, eax
jnz .fail
 
add ebx, edx ;RUS: локальный номер в блоке ;ENG: local number inside block
mov eax, [ebx + EXT2_BLOCK_GROUP_DESC.inode_table] ;RUS: номер блока - в терминах ext2
;ENG: block number - in ext2 terms
mov ecx, [ebp+EXTFS.log_block_size]
shl eax, cl
;RUS: eax - указывает на таблицу inode-ов на hdd ;ENG: eax - points to inode table on HDD
mov esi, eax ;RUS: сохраним его пока в esi ;ENG: let's save it in esi for now
 
;RUS: прибавим локальный адрес inode-а ;ENG: add local address of inode
pop eax ; index
mov ecx, [ebp+EXTFS.inode_size]
mul ecx ; (index * inode_size)
;RUS: поделим на размер блока ;ENG: divide by block size
mov ecx, eax
and ecx, 512 - 1
shrd eax, edx, 9
 
add eax, esi ;RUS: нашли адрес блока для чтения ;ENG: found block address to read
mov ebx, [ebp+EXTFS.ext2_temp_block]
call fs_read32_sys
test eax, eax
jnz .fail
 
mov esi, ecx ;RUS: добавим "остаток" ;ENG: add the "remainder"
mov ecx, [ebp+EXTFS.inode_size]
add esi, ebx ;RUS: к адресу ;ENG: to the address
rep movsb ;RUS: копируем inode ;ENG: copy inode
xor eax, eax
.fail:
mov PUSHAD_EAX, eax
popad
ret
 
;----------------------------------------------------------------
; ext2_ReadFolder - EXT2FS implementation of reading a folder
; in: ebp = pointer to EXTFS structure
; in: esi+[esp+4] = name
; in: ebx = pointer to parameters from sysfunc 70
; out: eax, ebx = return values for sysfunc 70
;----------------------------------------------------------------
ext2_ReadFolder:
call ext2_lock
cmp byte [esi], 0
jz .root_folder
 
push ebx
stdcall ext2_find_lfn, [esp+4+4] ;вернет в esi адрес inode
pop ebx
test eax, eax
jnz .error_ret
test [esi + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR
jz .error_not_found
jmp @F
 
.root_folder:
mov esi, [ebp+EXTFS.root_inode]
test [esi + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR
jz .error_root
;придется копировать inode
mov edi, [ebp+EXTFS.ext2_save_inode]
mov ecx, [ebp+EXTFS.inode_size]
shr ecx, 2
push edi
rep movsd
pop esi
@@:
cmp [esi + EXT2_INODE_STRUC.i_size], 0 ;папка пуста
je .error_empty_dir
mov edx, [ebx + 16]
push edx ;адрес результата [edi + 28]
push 0 ;конец очередного блока папки [edi + 24]
push dword [ebx +12];сколько файлов нужно прочитать [edi + 20]
push dword [ebx + 4];первый "нужный" файл [edi + 16]
push dword [ebx + 8];флаги [edi + 12]
push 0 ;[EXT2_read_in_folder] [edi + 8]
push 0 ;[EXT2_files_in_folder] [edi + 4]
push 0 ;номер блока по порядку [edi]
 
mov edi, edx
mov ecx, 32/4
rep stosd ; fill header zero
mov edi, esp ; edi - указатель на локальные переменные
add edx, 32 ; edx = current mem for return
 
xor ecx, ecx ; получим номер первого блока
call ext2_get_inode_block
test eax, eax
jnz .error_get_block
 
mov eax, ecx
mov ebx, [ebp+EXTFS.ext2_save_block]
call ext2_get_block ; и считываем блок с hdd
test eax, eax
jnz .error_get_block
 
mov eax, ebx ; ebx = current dir record
add eax, [ebp+EXTFS.block_size]
mov [edi + 24], eax ; запомним конец очередного блока
 
mov ecx, [edi + 16] ; ecx = first wanted (flags ommited)
 
.find_wanted_start:
jecxz .find_wanted_end
.find_wanted_cycle:
cmp [ebx + EXT2_DIR_STRUC.inode], 0 ; if (inode = 0) => not used
jz @F
inc dword [edi + 4] ; EXT2_files_in_folder
dec ecx
@@:
movzx eax, [ebx + EXT2_DIR_STRUC.rec_len]
 
cmp eax, 12 ; минимальная длина записи
jb .error_bad_len
test eax, 0x3 ; длина записи должна делиться на 4
jnz .error_bad_len
 
sub [esi + EXT2_INODE_STRUC.i_size], eax ;вычитаем напрямую из структуры inode
add ebx, eax ; к следующей записи
cmp ebx, [edi + 24] ; сравниваем с концом блока
jb .find_wanted_start
 
push .find_wanted_start
.end_block: ;вылетели из цикла
cmp [esi + EXT2_INODE_STRUC.i_size], 0
jle .end_dir
 
inc dword [edi] ;получаем новый блок
push ecx
mov ecx, [edi]
call ext2_get_inode_block
test eax, eax
jnz .error_get_block
 
mov eax, ecx
mov ebx, [ebp+EXTFS.ext2_save_block]
call ext2_get_block
test eax, eax
jnz .error_get_block
 
pop ecx
mov eax, ebx
add eax, [ebp+EXTFS.block_size]
mov [edi + 24], eax ;запомним конец блока
ret ; опять в цикл
 
.wanted_end:
loop .find_wanted_cycle ; ecx 0 => -1 нужно посчитать сколько файлов
 
;дошли до первого "нужного" файла
.find_wanted_end:
mov ecx, [edi + 20]
.wanted_start: ; ищем first_wanted+count
jecxz .wanted_end
cmp [ebx + EXT2_DIR_STRUC.inode], 0 ; if (inode = 0) => not used
jz .empty_rec
inc dword [edi + 8]
inc dword [edi + 4]
 
push edi ecx
mov edi, edx ;обнуляем место под очереное имя файла/папки
xor eax, eax
mov ecx, 40 / 4
rep stosd
pop ecx edi
 
push ebx edi edx
mov eax, [ebx + EXT2_DIR_STRUC.inode] ;получим дочерний inode
mov ebx, [ebp+EXTFS.ext2_temp_inode]
call ext2_get_inode
test eax, eax
jnz .error_read_subinode
 
lea edi, [edx + 8]
 
mov eax, [ebx + EXT2_INODE_STRUC.i_ctime] ; переведем время в ntfs формат
xor edx, edx
add eax, 3054539008 ;(369 * 365 + 89) * 24 * 3600
adc edx, 2
call ntfs_datetime_to_bdfe.sec
 
mov eax, [ebx + EXT2_INODE_STRUC.i_atime]
xor edx, edx
add eax, 3054539008
adc edx, 2
call ntfs_datetime_to_bdfe.sec
 
mov eax, [ebx + EXT2_INODE_STRUC.i_mtime]
xor edx, edx
add eax, 3054539008
adc edx, 2
call ntfs_datetime_to_bdfe.sec
 
pop edx ; пока достаем только буфер
test [ebx + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR ; для папки размер
jnz @F ; не возвращаем
 
mov eax, [ebx + EXT2_INODE_STRUC.i_size] ;low size
stosd
mov eax, [ebx + EXT2_INODE_STRUC.i_dir_acl] ;high size
stosd
xor dword [edx], FS_FT_DIR ;помечаем, что это файл(2 раза xor)
@@:
xor dword [edx], FS_FT_DIR ;помечаем, что это файл
 
;теперь скопируем имя, сконвертировав из UTF-8 в CP866
push ecx esi ;edi уже сохранен в стеке
mov esi, [esp+12]
movzx ecx, [esi + EXT2_DIR_STRUC.name_len]
lea edi, [edx + 40]
lea esi, [esi + EXT2_DIR_STRUC.name]
call utf8_to_cp866
and byte [edi], 0
pop esi ecx edi ebx
 
cmp byte [edx + 40], '.' ; в linux файл, начинающийся с точки - скрытый
jne @F
or dword [edx], FS_FT_HIDDEN
@@:
 
add edx, 40 + 264 ; go to next record
dec ecx ; если запись пустая ecx не надо уменьшать
.empty_rec:
movzx eax, [ebx + EXT2_DIR_STRUC.rec_len]
cmp eax, 12 ; минимальная длина записи
jb .error_bad_len
test eax, 0x3 ; длина записи должна делиться на 4
jnz .error_bad_len
 
sub [esi + EXT2_INODE_STRUC.i_size], eax ;вычитаем напрямую из структуры inode
add ebx, eax
cmp ebx, [edi + 24] ;дошли ли до конца блока?
jb .wanted_start
 
push .wanted_start ; дошли
jmp .end_block
 
.end_dir: ;конец папки, когда еще не дошли до нужного файла
call ext2_unlock
mov edx, [edi + 28] ;адрес структуры результата
mov ebx, [edi + 8] ;EXT2_read_in_folder
mov ecx, [edi + 4] ;EXT2_files_in_folder
mov dword [edx], 1 ;version
mov [edx + 4], ebx
mov [edx + 8], ecx
lea esp, [edi + 32]
xor eax, eax ;RUS: зарезервировано: нули в текущей реализации
;ENG: reserved: zeros in current implementation
lea edi, [edx + 12]
mov ecx, 20 / 4
rep stosd
ret
 
.error_bad_len:
mov eax, ERROR_FS_FAIL
.error_read_subinode:
.error_get_block:
lea esp, [edi + 32]
.error_ret:
or ebx, -1
push eax
call ext2_unlock
pop eax
ret
.error_empty_dir: ;RUS: inode папки без блоков ;ENG: inode of folder without blocks
.error_root: ;RUS: root - не папка ;ENG: root is not a folder
mov eax, ERROR_FS_FAIL
jmp .error_ret
 
.error_not_found: ;RUS: файл не найден ;ENG: file not found
mov eax, ERROR_FILE_NOT_FOUND
jmp .error_ret
;============================================
;convert UTF-8 string to ASCII-string (codepage 866)
;in: ecx = length source
; esi = source
; edi = buffer
; destroys: eax,esi,edi
utf8_to_cp866:
jecxz .ret
.start:
lodsw
cmp al, 0x80
jb .ascii
 
xchg al, ah ; big-endian
cmp ax, 0xd080
jz .yo1
cmp ax, 0xd191
jz .yo2
cmp ax, 0xd090
jb .unk
cmp ax, 0xd180
jb .rus1
cmp ax, 0xd190
jb .rus2
.unk:
mov al, '_'
jmp .doit
.yo1:
mov al, 0xf0 ; Ё capital
jmp .doit
.yo2:
mov al, 0xf1 ; ё small
jmp .doit
.rus1:
sub ax, 0xd090 - 0x80
jmp .doit
.rus2:
sub ax, 0xd18f - 0xEF
.doit:
stosb
sub ecx, 2
ja .start
ret
 
.ascii:
stosb
dec esi
dec ecx
jnz .start
.ret:
ret
 
;----------------------------------------------------------------
; ext2_Read - EXT2FS implementation of reading a file
; in: ebp = pointer to FAT structure
; in: esi+[esp+4] = name
; in: ebx = pointer to parameters from sysfunc 70
; out: eax, ebx = return values for sysfunc 70
;----------------------------------------------------------------
ext2_Read:
call ext2_lock
cmp byte [esi], 0
jnz @F
 
.this_is_nofile:
call ext2_unlock
or ebx, -1
mov eax, ERROR_ACCESS_DENIED
ret
 
@@:
push ebx
stdcall ext2_find_lfn, [esp+4+4]
pop ebx
test eax, eax
jz @F
 
call ext2_unlock
or ebx, -1
mov eax, ERROR_FILE_NOT_FOUND
ret
 
@@:
mov ax, [esi + EXT2_INODE_STRUC.i_mode]
and ax, EXT2_S_IFMT ;оставляем только тип inode в ax
cmp ax, EXT2_S_IFREG
jne .this_is_nofile
 
mov edi, [ebx+16] ; edi = pointer to return mem
mov ecx, [ebx+12]
 
mov eax, [ebx+4]
mov edx, [ebx+8] ;RUS: edx : eax - стартовый номер байта ;ENG: edx : eax - start byte number
 
;RUS: ///// сравним хватит ли нам файла или нет ;ENG: ///// check if file is big enough for us
cmp [esi + EXT2_INODE_STRUC.i_dir_acl], edx
ja .size_great
jb .size_less
 
cmp [esi + EXT2_INODE_STRUC.i_size], eax
ja .size_great
 
.size_less:
call ext2_unlock
xor ebx, ebx
mov eax, ERROR_END_OF_FILE
ret
.size_great:
add eax, ecx ;RUS: add to first_wanted кол-во байт для чтения
;ENG: add to first_wanted number of bytes to read
adc edx, 0
 
cmp [esi + EXT2_INODE_STRUC.i_dir_acl], edx
ja .size_great_great
jb .size_great_less
cmp [esi + EXT2_INODE_STRUC.i_size], eax
jae .size_great_great ; and if it's equal, no matter where we jump
 
.size_great_less:
push 1 ;RUS: читаем по границе размера ;ENG: reading till the end of file
mov ecx, [esi + EXT2_INODE_STRUC.i_size]
sub ecx, [ebx+4] ;RUS: (размер - старт) = сколько читать ;ENG: to read = (size - start)
jmp @F
 
.size_great_great:
push 0 ;RUS: читаем столько, сколько запросили ;ENG: reading as much as requested
 
@@:
;здесь мы точно знаем сколько байт читать - ecx
;edi - return memory
;esi -> first wanted
 
push ecx ;количество считанных байт
 
;получим кусок из первого блока
mov edx, [ebx+8]
mov eax, [ebx+4]
div [ebp+EXTFS.block_size]
 
push eax ;счетчик блоков ложим в стек
push ecx
mov ecx, eax
call ext2_get_inode_block
test eax, eax
jnz .error_at_first_block
mov ebx, [ebp+EXTFS.ext2_save_block]
mov eax, ecx
call ext2_get_block
test eax, eax
jnz .error_at_first_block
pop ecx
add ebx, edx
 
neg edx
add edx, [ebp+EXTFS.block_size] ;RUS: block_size - стартовый байт = сколько байт 1-го блока
;ENG: block_size - start byte = number of bytes in 1st block
cmp ecx, edx
jbe .only_one_block
 
mov eax, ecx
sub eax, edx
mov ecx, edx
 
push esi
mov esi, ebx
rep movsb ;RUS: кусок 1-го блока ;ENG: part of 1st block
pop esi
 
;теперь в eax кол-во оставшихся байт для чтения
.calc_blocks_count:
mov ebx, edi ;чтение блока прям в ->ebx
xor edx, edx
div [ebp+EXTFS.block_size] ;кол-во байт в последнем блоке (остаток) в edx
mov edi, eax ;кол-во целых блоков в edi
@@:
test edi, edi
jz .finish_block
inc dword [esp]
mov ecx, [esp]
call ext2_get_inode_block
test eax, eax
jnz .error_at_read_cycle
 
mov eax, ecx ;а ebx уже забит нужным значением
call ext2_get_block
test eax, eax
jnz .error_at_read_cycle
add ebx, [ebp+EXTFS.block_size]
 
dec edi
jmp @B
 
.finish_block: ;в edx - кол-во байт в последнем блоке
test edx, edx
jz .end_read
 
pop ecx ;счетчик блоков -> ecx
inc ecx
call ext2_get_inode_block
test eax, eax
jnz .error_at_finish_block
 
mov edi, ebx
mov eax, ecx
mov ebx, [ebp+EXTFS.ext2_save_block]
call ext2_get_block
test eax, eax
jnz .error_at_finish_block
 
mov ecx, edx
mov esi, ebx
rep movsb ;кусок last блока
jmp @F
 
.end_read:
pop ecx ;счетчик блоков, который хранился в стеке
@@:
pop ebx ;количество считанных байт
call ext2_unlock
pop eax ; 1 или 0 - достигли ли конца файла
test eax, eax
jz @F
 
mov eax, ERROR_END_OF_FILE
ret
@@:
xor eax, eax
ret
.only_one_block:
mov esi, ebx
rep movsb ;кусок last блока
jmp .end_read
.error_at_first_block:
pop edx
.error_at_read_cycle:
pop ebx
.error_at_finish_block:
pop ecx edx
or ebx, -1
push eax
call ext2_unlock
pop eax
ret
 
;----------------------------------------------------------------
; in: esi = file path
; ebx = pointer to dir block
; ebp = pointer to EXTFS structure
; out: esi - name without parent or not_changed
; ebx - dir_rec of inode children
ext2_test_block_by_name:
sub esp, 256 ;EXT2_filename
mov edx, ebx
add edx, [ebp+EXTFS.block_size] ;RUS: запомним конец блока ;ENG: save block end
 
.start_rec:
cmp [ebx + EXT2_DIR_STRUC.inode], 0
jz .next_rec
 
mov edi, esp
push esi
movzx ecx, [ebx + EXT2_DIR_STRUC.name_len]
lea esi, [ebx + EXT2_DIR_STRUC.name]
call utf8_to_cp866
 
mov ecx, edi
lea edi, [esp + 4]
sub ecx, edi ;RUS: кол-во байт в получившейся строке ;ENG: number of bytes in resulting string
 
mov esi, [esp]
@@:
jecxz .test_find
dec ecx
 
lodsb
call char_toupper
 
mov ah, [edi]
inc edi
xchg al, ah
call char_toupper
cmp al, ah
je @B
@@: ;RUS: не подошло ;ENG: didn't fit
pop esi
.next_rec:
movzx eax, [ebx + EXT2_DIR_STRUC.rec_len]
add ebx, eax ;RUS: к след. записи ;ENG: go to next record
cmp ebx, edx ;RUS: проверим конец ли ;ENG: check if this is the end
jb .start_rec
add esp, 256
ret
 
.test_find:
cmp byte [esi], 0
je .ret ;RUS: нашли конец ;ENG: the end reached
cmp byte [esi], '/'
jne @B
inc esi
.ret:
add esp, 256 + 4
ret
 
;========================
;Ищет inode по строке пути
;in: esi+[esp+4] = name
; ebp = pointer to EXTFS
;out: eax - error code
; esi = inode
; dl - первый байт из имени файла/папки
ext2_find_lfn:
mov edx, [ebp+EXTFS.root_inode]
cmp [edx + EXT2_INODE_STRUC.i_blocks], 0
je .error_empty_root
.next_path_part:
push [edx + EXT2_INODE_STRUC.i_blocks]
xor ecx, ecx
.folder_block_cycle:
push ecx
xchg esi, edx
call ext2_get_inode_block
xchg esi, edx
test eax, eax
jnz .error_get_inode_block
mov eax, ecx
mov ebx, [ebp+EXTFS.ext2_save_block] ;ebx = cur dir record
call ext2_get_block
test eax, eax
jnz .error_get_block
push esi
push edx
call ext2_test_block_by_name
pop edx
pop edi ecx
 
cmp edi, esi ;RUS: нашли имя? ;ENG: did we find a name?
je .next_folder_block ;RUS: не нашли -> к след. блоку ;ENG: we didn't -> moving to next block
cmp byte [esi], 0 ;RUS: дошли до "конца" пути -> возваращаемся
;ENG: reached the "end" of path -> returning
jnz @f
cmp dword [esp+8], 0
jz .get_inode_ret
mov esi, [esp+8]
mov dword [esp+8], 0
@@:
 
cmp [ebx + EXT2_DIR_STRUC.file_type], EXT2_FT_DIR ;RUS: нашли, но это не папка
jne .not_found ;ENG: found, but it's not a folder
 
mov eax, [ebx + EXT2_DIR_STRUC.inode]
mov ebx, [ebp+EXTFS.ext2_save_inode] ;RUS: все же папка. ;ENG: it's a folder afterall
call ext2_get_inode
test eax, eax
jnz .error_get_inode
pop ecx ;RUS: в стеке лежит кол-во блоков ;ENG: stack top contains number of blocks
mov edx, ebx
jmp .next_path_part
.next_folder_block:
;к следующему блоку в текущей папке
pop eax ;RUS: счетчик блоков ;ENG: blocks counter
sub eax, [ebp+EXTFS.count_block_in_block]
jle .not_found
push eax
inc ecx
jmp .folder_block_cycle
 
.not_found:
mov eax, ERROR_FILE_NOT_FOUND
ret 4
 
.get_inode_ret:
pop ecx ;RUS: в стеке лежит кол-во блоков ;ENG: stack top contains number of blocks
mov dl, [ebx + EXT2_DIR_STRUC.name] ;RUS: в dl - первый символ () ;ENG: ???
mov eax, [ebx + EXT2_DIR_STRUC.inode]
mov ebx, [ebp+EXTFS.ext2_save_inode]
call ext2_get_inode
mov esi, ebx
xor eax, eax
ret 4
 
.error_get_inode_block:
.error_get_block:
pop ecx
.error_get_inode:
pop ebx
.error_empty_root:
mov eax, ERROR_FS_FAIL
ret 4
 
;----------------------------------------------------------------
; ext2_GetFileInfo - EXT2 implementation of getting file info
; in: ebp = pointer to EXTFS structure
; in: esi+[esp+4] = name
; in: ebx = pointer to parameters from sysfunc 70
; out: eax, ebx = return values for sysfunc 70
;----------------------------------------------------------------
ext2_GetFileInfo:
call ext2_lock
mov edx, [ebx+16]
cmp byte [esi], 0
jz .is_root
 
push edx
stdcall ext2_find_lfn, [esp+4+4]
mov ebx, edx
pop edx
test eax, eax
jz @F
push eax
call ext2_unlock
pop eax
ret
 
.is_root:
xor ebx, ebx ;RUS: root не может быть скрытым ;ENG: root cannot be hidden
mov esi, [ebp+EXTFS.root_inode]
@@:
xor eax, eax
mov edi, edx
mov ecx, 40/4
rep stosd ; fill zero
 
cmp bl, '.'
jne @F
or dword [edx], FS_FT_HIDDEN
@@:
 
test [esi + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR
jnz @F
mov eax, [esi + EXT2_INODE_STRUC.i_size] ;low size
mov ebx, [esi + EXT2_INODE_STRUC.i_dir_acl] ;high size
mov dword [edx+32], eax
mov dword [edx+36], ebx
xor dword [edx], FS_FT_DIR
@@:
xor dword [edx], FS_FT_DIR
 
lea edi, [edx + 8]
mov eax, [esi + EXT2_INODE_STRUC.i_ctime]
xor edx, edx
add eax, 3054539008
adc edx, 2
call ntfs_datetime_to_bdfe.sec
 
mov eax, [esi + EXT2_INODE_STRUC.i_atime]
xor edx, edx
add eax, 3054539008
adc edx, 2
call ntfs_datetime_to_bdfe.sec
 
mov eax, [esi + EXT2_INODE_STRUC.i_mtime]
xor edx, edx
add eax, 3054539008
adc edx, 2
call ntfs_datetime_to_bdfe.sec
 
call ext2_unlock
xor eax, eax
ret
 
ext2_Rewrite:
ext2_Write:
ext2_SetFileEnd:
ext2_SetFileInfo:
ext2_Delete:
ext2_CreateFolder:
xor ebx, ebx
mov eax, ERROR_UNSUPPORTED_FS
ret
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/fs/fs.inc
24,8 → 24,6
 
if lang eq sp
include 'fs/fs-sp.inc'
else if lang eq et
include 'fs/fs-et.inc'
else
dir0:
db 'HARDDISK '
/kernel/branches/Kolibri-acpi/gui/font.inc
233,8 → 233,6
FONT_I:
if lang eq sp
file 'char_sp.mt'
else if lang eq et
file 'char_et.mt'
else
file 'char.mt'
end if
243,8 → 241,6
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
/kernel/branches/Kolibri-acpi/kernel.asm
144,8 → 144,6
 
if lang eq sp
include "kernelsp.inc" ; spanish kernel messages
else if lang eq et
version db 'Kolibri OS versioon 0.7.7.0+ ',13,10,13,10,0
else
version db 'Kolibri OS version 0.7.7.0+ ',13,10,13,10,0
end if
698,19 → 696,6
mov [mem_BACKGROUND], 4
mov [img_background], static_background_data
 
; set clipboard
 
xor eax, eax
mov [clipboard_slots], eax
mov [clipboard_write_lock], eax
stdcall kernel_alloc, 4096
test eax, eax
jnz @f
 
dec eax
@@:
mov [clipboard_main_list], eax
 
; SET UP OS TASK
 
mov esi, boot_setostask
1108,8 → 1093,6
@@:
DEBUGF 1, "K : %d CPU detected\n", eax
 
include "detect/vortex86.inc" ; Vortex86 SoC detection code
 
DEBUGF 1, "K : BAR0 %x \n", [IDE_BAR0_val]:4
DEBUGF 1, "K : BAR1 %x \n", [IDE_BAR1_val]:4
DEBUGF 1, "K : BAR2 %x \n", [IDE_BAR2_val]:4
1117,7 → 1100,6
DEBUGF 1, "K : BAR4 %x \n", [IDEContrRegsBaseAddr]:4
DEBUGF 1, "K : IDEContrProgrammingInterface %x \n", [IDEContrProgrammingInterface]:4
DEBUGF 1, "K : IDE_Interrupt %x \n", [IDE_Interrupt]:4
 
; START MULTITASKING
 
; A 'All set - press ESC to start' messages if need
3266,10 → 3248,6
mov EAX, dword [ECX+CURRENT_TASK+TASKDATA.event_mask]
stosd
 
; Keyboard mode (+75)
mov al, byte [ecx*8 + SLOT_BASE + APPDATA.keyboard_mode]
stosb
 
pop esi
pop edi
 
3812,6 → 3790,10
 
mov eax, [edi + WDATA.box.left]
mov ebx, [edi + WDATA.box.top]
mov ecx, [edi + WDATA.box.width]
mov edx, [edi + WDATA.box.height]
add ecx, eax
add edx, ebx
 
mov ecx, [draw_limits.bottom] ; ecx = area y end ebx = window y start
cmp ecx, ebx
3910,65 → 3892,7
align 4
newdw8:
nobgrd:
;--------------------------------------
push eax edi ebp
mov edi, [esp+12]
cmp edi, 1
je .found
 
mov eax, [draw_limits.left]
mov ebx, [draw_limits.top]
mov ecx, [draw_limits.right]
sub ecx, eax
test ecx, ecx
jz .not_found
 
mov edx, [draw_limits.bottom]
sub edx, ebx
test edx, edx
jz .not_found
 
; eax - x, ebx - y
; ecx - size x, edx - size y
add ebx, edx
;--------------------------------------
align 4
.start_y:
push ecx
;--------------------------------------
align 4
.start_x:
add eax, ecx
mov ebp, [d_width_calc_area + ebx*4]
add ebp, [_WinMapAddress]
movzx ebp, byte[eax+ebp] ; get value for current point
cmp ebp, edi
jne @f
 
pop ecx
jmp .found
;--------------------------------------
align 4
@@:
sub eax, ecx
 
dec ecx
jnz .start_x
 
pop ecx
dec ebx
dec edx
jnz .start_y
;--------------------------------------
align 4
.not_found:
pop ebp edi eax
jmp ricino
;--------------------------------------
align 4
.found:
pop ebp edi eax
 
mov [eax + WDATA.fl_redraw], byte 1 ; mark as redraw
;--------------------------------------
align 4
5587,13 → 5511,13
 
align 4
syscall_threads: ; CreateThreads
; eax=1 create thread
;
; ecx=thread entry point
; edx=thread stack pointer
; ebx=thread start
; ecx=thread stack value
;
; on return : eax = pid
 
xor ebx, ebx
call new_sys_threads
 
mov [esp+32], eax
/kernel/branches/Kolibri-acpi/network/IPv4.inc
18,7 → 18,7
 
$Revision: 3515 $
 
IPv4_MAX_FRAGMENTS = 64
MAX_FRAGMENTS = 64
 
struct IPv4_header
 
35,7 → 35,7
 
ends
 
struct IPv4_FRAGMENT_slot
struct FRAGMENT_slot
 
ttl dw ? ; Time to live for this entry, 0 for empty slot's
id dw ? ; Identification field from IP header
45,7 → 45,7
 
ends
 
struct IPv4_FRAGMENT_entry ; This structure will replace the ethernet header in fragmented ip packets
struct FRAGMENT_entry ; This structure will replace the ethernet header in fragmented ip packets
 
PrevPtr dd ? ; Pointer to previous fragment entry (-1 for first packet)
NextPtr dd ? ; Pointer to next fragment entry (-1 for last packet)
64,11 → 64,11
GATEWAY_LIST rd NET_DEVICES_MAX
BROADCAST_LIST rd NET_DEVICES_MAX
 
IPv4_packets_tx rd NET_DEVICES_MAX
IPv4_packets_rx rd NET_DEVICES_MAX
IPv4_packets_dumped rd NET_DEVICES_MAX
IP_packets_tx rd NET_DEVICES_MAX
IP_packets_rx rd NET_DEVICES_MAX
IP_packets_dumped rd NET_DEVICES_MAX
 
IPv4_FRAGMENT_LIST rb IPv4_MAX_FRAGMENTS * sizeof.IPv4_FRAGMENT_slot
FRAGMENT_LIST rb MAX_FRAGMENTS * sizeof.FRAGMENT_slot
 
endg
 
84,7 → 84,7
 
xor eax, eax
mov edi, IP_LIST
mov ecx, 7*NET_DEVICES_MAX + (sizeof.IPv4_FRAGMENT_slot*IPv4_MAX_FRAGMENTS)/4
mov ecx, 7*NET_DEVICES_MAX + (sizeof.FRAGMENT_slot*MAX_FRAGMENTS)/4
rep stosd
 
}
99,15 → 99,15
 
local .loop, .next
 
mov esi, IPv4_FRAGMENT_LIST
mov ecx, IPv4_MAX_FRAGMENTS
mov esi, FRAGMENT_LIST
mov ecx, MAX_FRAGMENTS
.loop:
cmp [esi + IPv4_FRAGMENT_slot.ttl], 0
cmp [esi + FRAGMENT_slot.ttl], 0
je .next
dec [esi + IPv4_FRAGMENT_slot.ttl]
dec [esi + FRAGMENT_slot.ttl]
jz .died
.next:
add esi, sizeof.IPv4_FRAGMENT_slot
add esi, sizeof.FRAGMENT_slot
dec ecx
jnz .loop
jmp .done
263,7 → 263,7
; Now we can update stats
 
.ip_ok:
inc [IPv4_packets_rx + edi]
inc [IP_packets_rx + edi]
 
;----------------------------------
; Check if the packet is fragmented
304,7 → 304,7
 
.dump:
DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: dumping\n"
inc [IPv4_packets_dumped] ; FIXME: use correct interface
inc [IP_packets_dumped] ; FIXME: use correct interface
call NET_packet_free
add esp, 4 ; pop (balance stack)
ret
319,7 → 319,7
xchg al, ah
shl ax, 3
 
DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: fragmented packet offset=%u id=%x ptr=0x%x\n", ax, [edx + IPv4_header.Identification]:4, edx
DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: fragmented packet offset=%u id=%x\n", ax, [edx + IPv4_header.Identification]:4
 
test ax, ax ; Is this the first packet of the fragment?
jz .is_first_fragment
334,14 → 334,14
cmp esi, -1
je .dump
 
mov [esi + IPv4_FRAGMENT_slot.ttl], 15 ; Reset the ttl
mov esi, [esi + IPv4_FRAGMENT_slot.ptr]
mov [esi + FRAGMENT_slot.ttl], 15 ; Reset the ttl
mov esi, [esi + FRAGMENT_slot.ptr]
or edi, -1
.find_last_entry: ; The following routine will try to find the last entry
cmp edi, [esi + IPv4_FRAGMENT_entry.PrevPtr]
cmp edi, [esi + FRAGMENT_entry.PrevPtr]
jne .destroy_slot ; Damn, something screwed up, remove the whole slot (and free buffers too if possible!)
mov edi, esi
mov esi, [esi + IPv4_FRAGMENT_entry.NextPtr]
mov esi, [esi + FRAGMENT_entry.NextPtr]
cmp esi, -1
jne .find_last_entry
; We found the last entry (pointer is now in edi)
348,10 → 348,10
; We are going to overwrite the ethernet header in received packet with a FRAGMENT_entry structure
 
pop eax ; pointer to packet
mov [edi + IPv4_FRAGMENT_entry.NextPtr], eax ; update pointer of previous entry to the new entry
mov [eax + IPv4_FRAGMENT_entry.NextPtr], -1
mov [eax + IPv4_FRAGMENT_entry.PrevPtr], edi
mov [eax + IPv4_FRAGMENT_entry.Owner], ebx
mov [edi + FRAGMENT_entry.NextPtr], eax ; update pointer of previous entry to the new entry
mov [eax + FRAGMENT_entry.NextPtr], -1
mov [eax + FRAGMENT_entry.PrevPtr], edi
mov [eax + FRAGMENT_entry.Owner], ebx
 
add esp, 4
ret
363,29 → 363,29
.is_first_fragment:
DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: First fragment packet received!\n"
; try to locate a free slot..
mov ecx, IPv4_MAX_FRAGMENTS
mov esi, IPv4_FRAGMENT_LIST
mov ecx, MAX_FRAGMENTS
mov esi, FRAGMENT_LIST
.find_free_slot:
cmp word [esi + IPv4_FRAGMENT_slot.ttl], 0
cmp word [esi + FRAGMENT_slot.ttl], 0
je .found_free_slot
add esi, sizeof.IPv4_FRAGMENT_slot
add esi, sizeof.FRAGMENT_slot
loop .find_free_slot
jmp .dump ; If no free slot was found, dump the packet
 
.found_free_slot: ; We found a free slot, let's fill in the FRAGMENT_slot structure
mov [esi + IPv4_FRAGMENT_slot.ttl], 15 ; RFC recommends 15 secs as ttl
mov [esi + FRAGMENT_slot.ttl], 15 ; RFC recommends 15 secs as ttl
mov ax, [edx + IPv4_header.Identification]
mov [esi + IPv4_FRAGMENT_slot.id], ax
mov [esi + FRAGMENT_slot.id], ax
mov eax, [edx + IPv4_header.SourceAddress]
mov [esi + IPv4_FRAGMENT_slot.SrcIP], eax
mov [esi + FRAGMENT_slot.SrcIP], eax
mov eax, [edx + IPv4_header.DestinationAddress]
mov [esi + IPv4_FRAGMENT_slot.DstIP], eax
mov [esi + FRAGMENT_slot.DstIP], eax
pop eax
mov [esi + IPv4_FRAGMENT_slot.ptr], eax
mov [esi + FRAGMENT_slot.ptr], eax
; Now, replace ethernet header in original buffer with a FRAGMENT_entry structure
mov [eax + IPv4_FRAGMENT_entry.NextPtr], -1
mov [eax + IPv4_FRAGMENT_entry.PrevPtr], -1
mov [eax + IPv4_FRAGMENT_entry.Owner], ebx
mov [eax + FRAGMENT_entry.NextPtr], -1
mov [eax + FRAGMENT_entry.PrevPtr], -1
mov [eax + FRAGMENT_entry.Owner], ebx
 
add esp, 4 ; balance stack and exit
ret
401,33 → 401,33
cmp esi, -1
je .dump
 
mov esi, [esi + IPv4_FRAGMENT_slot.ptr] ; We found the first entry, let's calculate total size of the packet in eax, so we can allocate a buffer
mov esi, [esi + FRAGMENT_slot.ptr] ; We found the first entry, let's calculate total size of the packet in eax, so we can allocate a buffer
push esi
xor eax, eax
or edi, -1
 
.count_bytes:
cmp [esi + IPv4_FRAGMENT_entry.PrevPtr], edi
cmp [esi + FRAGMENT_entry.PrevPtr], edi
jne .destroy_slot_pop ; Damn, something screwed up, remove the whole slot (and free buffers too if possible!)
mov cx, [esi + sizeof.IPv4_FRAGMENT_entry + IPv4_header.TotalLength] ; Add total length
mov cx, [esi + sizeof.FRAGMENT_entry + IPv4_header.TotalLength] ; Add total length
xchg cl, ch
DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: Packet size=%u\n", cx
add ax, cx
movzx cx, [esi + sizeof.IPv4_FRAGMENT_entry + IPv4_header.VersionAndIHL] ; Sub Header length
movzx cx, [esi + sizeof.FRAGMENT_entry + IPv4_header.VersionAndIHL] ; Sub Header length
and cx, 0x000F
shl cx, 2
DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: Header size=%u\n", cx
sub ax, cx
mov edi, esi
mov esi, [esi + IPv4_FRAGMENT_entry.NextPtr]
mov esi, [esi + FRAGMENT_entry.NextPtr]
cmp esi, -1
jne .count_bytes
 
mov esi, [esp+4]
mov [edi + IPv4_FRAGMENT_entry.NextPtr], esi ; Add this packet to the chain, this simplifies the following code
mov [esi + IPv4_FRAGMENT_entry.NextPtr], -1
mov [esi + IPv4_FRAGMENT_entry.PrevPtr], edi
mov [esi + IPv4_FRAGMENT_entry.Owner], ebx
mov [edi + FRAGMENT_entry.NextPtr], esi ; Add this packet to the chain, this simplifies the following code
mov [esi + FRAGMENT_entry.NextPtr], -1
mov [esi + FRAGMENT_entry.PrevPtr], edi
mov [esi + FRAGMENT_entry.Owner], ebx
 
mov cx, [edx + IPv4_header.TotalLength] ; Note: This time we dont substract Header length
xchg cl, ch
454,18 → 454,18
mov edx, [esp+4] ; Get pointer to first fragment entry back in edx
 
.rebuild_packet_loop:
movzx ecx, [edx + sizeof.IPv4_FRAGMENT_entry + IPv4_header.FlagsAndFragmentOffset] ; Calculate the fragment offset
movzx ecx, [edx + sizeof.FRAGMENT_entry + IPv4_header.FlagsAndFragmentOffset] ; Calculate the fragment offset
xchg cl, ch ; intel byte order
shl cx, 3 ; multiply by 8 and clear first 3 bits
DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: Fragment offset=%u\n", cx
 
lea edi, [eax + ecx] ; Notice that edi will be equal to eax for first fragment
movzx ebx, [edx + sizeof.IPv4_FRAGMENT_entry + IPv4_header.VersionAndIHL] ; Find header size (in ebx) of fragment
movzx ebx, [edx + sizeof.FRAGMENT_entry + IPv4_header.VersionAndIHL] ; Find header size (in ebx) of fragment
and bx, 0x000F ;
shl bx, 2 ;
 
lea esi, [edx + sizeof.IPv4_FRAGMENT_entry] ; Set esi to the correct begin of fragment
movzx ecx, [edx + sizeof.IPv4_FRAGMENT_entry + IPv4_header.TotalLength] ; Calculate total length of fragment
lea esi, [edx + sizeof.FRAGMENT_entry] ; Set esi to the correct begin of fragment
movzx ecx, [edx + sizeof.FRAGMENT_entry + IPv4_header.TotalLength] ; Calculate total length of fragment
xchg cl, ch ; intel byte order
 
cmp edi, eax ; Is this packet the first fragment ?
474,8 → 474,6
add esi, ebx ;
.first_fragment:
 
 
DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: Copying %u bytes from 0x%x to 0x%x\n", ecx, esi, edi
push cx ; First copy dword-wise, then byte-wise
shr cx, 2 ;
rep movsd ;
484,12 → 482,11
rep movsb ;
 
push eax
push [edx + IPv4_FRAGMENT_entry.Owner] ; we need to remeber the owner, in case this is the last packet
push [edx + IPv4_FRAGMENT_entry.NextPtr] ; Set edx to the next pointer
push edx ; Push pointer to fragment onto stack
DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: Next Fragment: 0x%x\n", edx
mov ebx, [edx + FRAGMENT_entry.Owner] ; we need to remeber the owner, in case this is the last packet
mov edx, [edx + FRAGMENT_entry.NextPtr] ; Set edx to the next pointer
call NET_packet_free ; free the previous fragment buffer (this uses the value from stack)
pop edx ebx eax
pop eax
cmp edx, -1 ; Check if it is last fragment in chain
jne .rebuild_packet_loop
 
497,9 → 494,11
xchg cl, ch
mov edx, eax
mov [edx + IPv4_header.TotalLength], cx
add esp, 12
add esp, 8
xchg cl, ch
push ecx edx ; size and pointer
push ecx
 
push eax
jmp .handle_it ; edx = buf ptr, ecx = size, [esp] buf ptr, [esp+4], total size, ebx=device ptr
 
.destroy_slot_pop:
528,19 → 527,19
 
push eax ebx ecx edx
mov ax, [edx + IPv4_header.Identification]
mov ecx, IPv4_MAX_FRAGMENTS
mov esi, IPv4_FRAGMENT_LIST
mov ecx, MAX_FRAGMENTS
mov esi, FRAGMENT_LIST
mov ebx, [edx + IPv4_header.SourceAddress]
mov edx, [edx + IPv4_header.DestinationAddress]
.find_slot:
cmp [esi + IPv4_FRAGMENT_slot.id], ax
cmp [esi + FRAGMENT_slot.id], ax
jne .try_next
cmp [esi + IPv4_FRAGMENT_slot.SrcIP], ebx
cmp [esi + FRAGMENT_slot.SrcIP], ebx
jne .try_next
cmp [esi + IPv4_FRAGMENT_slot.DstIP], edx
cmp [esi + FRAGMENT_slot.DstIP], edx
je .found_slot
.try_next:
add esi, sizeof.IPv4_FRAGMENT_slot
add esi, sizeof.FRAGMENT_slot
loop .find_slot
 
or esi, -1
553,9 → 552,10
;
; IPv4_output
;
; IN: eax = Destination IP
; IN: eax = dest ip
; ebx = output device ptr/0 for automatic choice
; ecx = data length
; edx = Source IP
; edx = source ip
; di = TTL shl 8 + protocol
;
; OUT: eax = pointer to buffer start
573,10 → 573,10
cmp ecx, 65500 ; Max IPv4 packet size
ja .too_large
 
push ecx di eax
call IPv4_route ; outputs device number in edi, dest ip in eax, source IP in edx
push edx
push ecx eax edx di
 
call IPv4_route ; outputs device number in edi, dest ip in eax
 
test edi, edi
jz .loopback
 
586,12 → 586,12
push ebx ; push the mac onto the stack
push ax
 
inc [IPv4_packets_tx + edi] ; update stats
inc [IP_packets_tx + edi] ; update stats
 
mov ebx, [NET_DRV_LIST + edi]
lea eax, [ebx + ETH_DEVICE.mac]
mov edx, esp
mov ecx, [esp + 6 + 8 + 2]
mov ecx, [esp + 10 + 6]
add ecx, sizeof.IPv4_header
mov di, ETHER_PROTO_IPv4
call ETH_output
605,14 → 605,12
mov [edi + IPv4_header.TotalLength], cx
mov [edi + IPv4_header.Identification], 0 ; fragment id: FIXME
mov [edi + IPv4_header.FlagsAndFragmentOffset], 0
 
pop word [edi + IPv4_header.TimeToLive] ; ttl shl 8 + protocol
; [edi + IPv4_header.Protocol]
mov [edi + IPv4_header.HeaderChecksum], 0
popd [edi + IPv4_header.SourceAddress]
popd [edi + IPv4_header.DestinationAddress]
 
pop word[edi + IPv4_header.TimeToLive] ; ttl shl 8 + protocol
; [edi + IPv4_header.Protocol]
 
pop ecx
 
IPv4_checksum edi
679,7 → 677,7
push ebx ; push the mac
push ax
 
inc [IPv4_packets_tx + 4*edi]
inc [IP_packets_tx + 4*edi]
mov ebx, [NET_DRV_LIST + 4*edi]
lea eax, [ebx + ETH_DEVICE.mac]
mov edx, esp
859,44 → 857,40
; IPv4_route
;
; IN: eax = Destination IP
; edx = Source IP
; OUT: eax = Destination IP (or gateway IP)
; edx = Source IP
; edi = device number*4
; DESTROYED:
; ecx
; OUT: edi = device number*4
; eax = ip of gateway if nescessary, unchanged otherwise
;
;---------------------------------------------------------------------------
align 4
IPv4_route: ; TODO: return error if no valid route found
IPv4_route:
 
cmp eax, 0xffffffff
je .broadcast
 
xor edi, edi
mov ecx, NET_DEVICES_MAX
.loop:
mov ebx, [IP_LIST + edi]
and ebx, [SUBNET_LIST + edi]
jz .next
mov ecx, eax
and ecx, [SUBNET_LIST + edi]
cmp ebx, ecx
je .got_it
mov edx, eax
and edx, [SUBNET_LIST+edi]
 
cmp ebx, edx
jne .next
 
DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_route: %u\n", edi
ret
 
.next:
add edi, 4
cmp edi, 4*NET_DEVICES_MAX
jb .loop
dec ecx
jnz .loop
 
mov eax, [GATEWAY_LIST + 4] ; TODO: let user (or a user space daemon) configure default route
.invalid:
mov eax, [GATEWAY_LIST+4] ;;; FIXME
.broadcast:
mov edi, 4 ; TODO: same as above
.got_it:
DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_route: %u\n", edi
test edx, edx
jnz @f
mov edx, [IP_LIST + edi]
@@:
 
mov edi, 4 ; if none found, use device 1 as default ;;;; FIXME
ret
 
 
916,45 → 910,6
ret
 
 
;-----------------------------------------------------------------
;
; IPv4_connect
;
; IN: eax = socket pointer
; OUT: eax = 0 ok / -1 error
; ebx = error code
;
;-------------------------
align 4
IPv4_connect:
 
push eax edx
lea ecx, [eax + SOCKET.mutex]
call mutex_lock
pop edx eax
 
; Fill in local IP
cmp [eax + IP_SOCKET.LocalIP], 0
jne @f
push [IP_LIST + 4] ; FIXME: use correct local IP
pop [eax + IP_SOCKET.LocalIP]
 
; Fill in remote IP
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
 
xor eax, eax
ret
 
 
;---------------------------------------------------------------------------
;
; IPv4_API
997,11 → 952,11
ret
 
.packets_tx:
mov eax, [IPv4_packets_tx + eax]
mov eax, [IP_packets_tx + eax]
ret
 
.packets_rx:
mov eax, [IPv4_packets_rx + eax]
mov eax, [IP_packets_rx + eax]
ret
 
.read_ip:
/kernel/branches/Kolibri-acpi/network/ethernet.inc
17,7 → 17,6
$Revision: 3346 $
 
ETH_FRAME_MINIMUM = 60
ETH_QUEUE_SIZE = 255
 
struct ETH_header
 
33,14 → 32,6
 
ends
 
struct ETH_queue_entry
 
device dd ?
packet dd ?
size dd ?
 
ends
 
iglobal
align 4
 
47,26 → 38,6
ETH_BROADCAST dp 0xffffffffffff
endg
 
uglobal
align 4
ETH_input_event dd ?
ETH_queue rd (ETH_QUEUE_SIZE*sizeof.ETH_queue_entry + sizeof.queue)/4
endg
 
macro ETH_init {
 
init_queue ETH_queue
 
movi ebx, 1
mov ecx, ETH_process_input
call new_sys_threads
test eax, eax
jns @f
DEBUGF DEBUG_NETWORK_ERROR,'K : cannot create kernel thread for ethernet, error %d\n', eax
@@:
 
}
 
;-----------------------------------------------------------------
;
; ETH_input
82,61 → 53,9
;-----------------------------------------------------------------
align 4
ETH_input:
mov eax, [esp]
mov ecx, [esp+4]
 
push ebx
mov esi, esp
 
pushf
cli
add_to_queue ETH_queue, ETH_QUEUE_SIZE, sizeof.ETH_queue_entry, .fail
popf
 
add esp, sizeof.ETH_queue_entry
 
xor edx, edx
mov eax, [ETH_input_event]
mov ebx, [eax + EVENT.id]
xor esi, esi
call raise_event
 
ret
 
.fail:
popf
DEBUGF DEBUG_NETWORK_VERBOSE, "ETH incoming queue is full, discarding packet!\n"
 
add esp, sizeof.ETH_queue_entry - 8
call NET_packet_free
add esp, 4
 
ret
 
 
 
 
align 4
ETH_process_input:
 
xor esi, esi
mov ecx, MANUAL_DESTROY
call create_event
mov [ETH_input_event], eax
 
.wait:
mov eax, [ETH_input_event]
mov ebx, [eax + EVENT.id]
call wait_event
 
.loop:
get_from_queue ETH_queue, ETH_QUEUE_SIZE, sizeof.ETH_queue_entry, .wait
 
mov eax, [esi + ETH_queue_entry.packet]
mov ecx, [esi + ETH_queue_entry.size]
mov ebx, [esi + ETH_queue_entry.device]
 
pushd .loop ; return address
push ecx eax
 
DEBUGF DEBUG_NETWORK_VERBOSE, "ETH_input: size=%u\n", ecx
sub ecx, sizeof.ETH_header
jb .dump
159,7 → 78,7
cmp ax, ETHER_PROTO_PPP_SESSION
je PPPoE_session_input
 
DEBUGF DEBUG_NETWORK_VERBOSE, "ETH_input: Unknown packet type=%x\n", ax
DEBUGF DEBUG_NETWORK_ERROR, "ETH_input: Unknown packet type=%x\n", ax
 
.dump:
DEBUGF DEBUG_NETWORK_VERBOSE, "ETH_input: dumping\n"
/kernel/branches/Kolibri-acpi/network/icmp.inc
310,16 → 310,15
ret
 
 
if 0
;-----------------------------------------------------------------
;
; ICMP_output
;
; IN: eax = dest ip
; bh = type
; bl = code
; ebx = source ip
; ecx = data length
; edx = source ip
; dh = type
; dl = code
; esi = data offset
; edi = identifier shl 16 + sequence number
;
329,7 → 328,10
 
DEBUGF DEBUG_NETWORK_VERBOSE, "Creating ICMP Packet\n"
 
push esi edi bx
push esi edi dx
 
mov edx, [eax + IP_SOCKET.LocalIP]
mov eax, [eax + IP_SOCKET.RemoteIP]
add ecx, sizeof.ICMP_header
mov di, IP_PROTO_ICMP SHL 8 + 128 ; TTL
call IPv4_output
372,7 → 374,6
DEBUGF DEBUG_NETWORK_ERROR, "Creating ICMP Packet failed\n"
add esp, 2*4 + 2
ret
end if
 
 
 
379,7 → 380,7
 
;-----------------------------------------------------------------
;
; ICMP_output_raw
; ICMP_output
;
; IN: eax = socket ptr
; ecx = data length
/kernel/branches/Kolibri-acpi/network/socket.inc
39,7 → 39,6
 
snd_proc dd ?
rcv_proc dd ?
connect_proc dd ?
 
ends
 
132,7 → 131,6
timer_persist dd ?
timer_keepalive dd ? ; keepalive/syn timeout
timer_timed_wait dd ? ; also used as 2msl timer
timer_connect dd ?
 
; extra
 
144,7 → 142,6
temp_bits db ?
rb 3 ; align
 
 
ends
 
struct UDP_SOCKET IP_SOCKET
151,6 → 148,7
 
LocalPort dw ? ; network byte order
RemotePort dw ? ; network byte order
firstpacket db ?
 
ends
 
311,7 → 309,6
mov [eax + SOCKET.Domain], ecx
mov [eax + SOCKET.Type], edx
mov [eax + SOCKET.Protocol], esi
mov [eax + SOCKET.connect_proc], connect_notsupp
 
cmp ecx, AF_INET4
jne .no_inet4
360,7 → 357,6
mov [eax + SOCKET.Protocol], IP_PROTO_UDP
mov [eax + SOCKET.snd_proc], SOCKET_send_udp
mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram
mov [eax + SOCKET.connect_proc], UDP_connect
ret
 
align 4
368,7 → 364,6
mov [eax + SOCKET.Protocol], IP_PROTO_TCP
mov [eax + SOCKET.snd_proc], SOCKET_send_tcp
mov [eax + SOCKET.rcv_proc], SOCKET_receive_stream
mov [eax + SOCKET.connect_proc], TCP_connect
 
TCP_init_socket eax
ret
378,7 → 373,6
.raw_ip:
mov [eax + SOCKET.snd_proc], SOCKET_send_ip
mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram
mov [eax + SOCKET.connect_proc], IPv4_connect
ret
 
 
386,7 → 380,6
.raw_icmp:
mov [eax + SOCKET.snd_proc], SOCKET_send_icmp
mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram
mov [eax + SOCKET.connect_proc], IPv4_connect
ret
 
align 4
421,9 → 414,6
cmp esi, 2
jb .invalid
 
cmp [eax + UDP_SOCKET.LocalPort], 0 ; Socket can only be bound once
jnz .invalid
 
cmp word [edx], AF_INET4
je .af_inet4
 
459,21 → 449,17
 
.tcp:
.udp:
mov ebx, [edx + 4] ; First, fill in the IP
test ebx, ebx ; If IP is 0, use default
jnz @f
mov ebx, [IP_LIST + 4] ;;;;; FIXME !i!i!i
@@:
mov [eax + IP_SOCKET.LocalIP], ebx
 
pushd [edx + 4] ; First, fill in the IP
popd [eax + IP_SOCKET.LocalIP]
mov bx, [edx + 2] ; Now fill in the local port if it's still available
call SOCKET_check_port
jz .addrinuse ; ZF is set by socket_check_port, on error
 
mov bx, [edx + 2] ; Did caller specify a local port?
test bx, bx
jnz .just_check
call SOCKET_find_port ; Nope, find an ephemeral one
jmp .done
 
.just_check:
call SOCKET_check_port ; Yes, check if it's still available
jz .addrinuse ; ZF is set by socket_check_port on error
 
.done:
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_bind: local ip=%u.%u.%u.%u\n",\
[eax + IP_SOCKET.LocalIP + 0]:1,[eax + IP_SOCKET.LocalIP + 1]:1,\
[eax + IP_SOCKET.LocalIP + 2]:1,[eax + IP_SOCKET.LocalIP + 3]:1
510,19 → 496,9
cmp esi, 8
jb .invalid
 
cmp [eax + SOCKET.state], SS_ISCONNECTING
je .already
cmp word [edx], AF_INET4
je .af_inet4
 
test [eax + SOCKET.options], SO_ACCEPTCON
jnz .notsupp
 
call [eax + SOCKET.connect_proc]
 
mov dword[esp+20], ebx
mov dword[esp+32], eax
ret
 
 
.notsupp:
mov dword[esp+20], EOPNOTSUPP
mov dword[esp+32], -1
533,19 → 509,153
mov dword[esp+32], -1
ret
 
.already:
mov dword[esp+20], EALREADY
.af_inet4:
cmp [eax + IP_SOCKET.LocalIP], 0
jne @f
push [IP_LIST + 4] ; FIXME !i!i!i!
pop [eax + IP_SOCKET.LocalIP]
@@:
 
cmp [eax + SOCKET.Protocol], IP_PROTO_UDP
je .udp
 
cmp [eax + SOCKET.Protocol], IP_PROTO_TCP
je .tcp
 
cmp [eax + SOCKET.Protocol], IP_PROTO_IP
je .ip
 
cmp [eax + SOCKET.Protocol], IP_PROTO_ICMP
je .ip
 
jmp .notsupp
 
align 4
.udp:
pusha
lea ecx, [eax + SOCKET.mutex]
call mutex_lock
popa
 
pushw [edx + 2]
pop [eax + UDP_SOCKET.RemotePort]
 
pushd [edx + 4]
pop [eax + IP_SOCKET.RemoteIP]
 
cmp [eax + UDP_SOCKET.LocalPort], 0
jne @f
call SOCKET_find_port
@@:
 
mov [eax + UDP_SOCKET.firstpacket], 0
 
push eax
init_queue (eax + SOCKET_QUEUE_LOCATION) ; Set up data receiving queue
pop eax
 
lea ecx, [eax + SOCKET.mutex]
call mutex_unlock
 
mov dword[esp+32], 0
ret
 
align 4
.tcp:
pusha
lea ecx, [eax + SOCKET.mutex]
call mutex_lock
popa
 
pushw [edx + 2]
pop [eax + TCP_SOCKET.RemotePort]
 
pushd [edx + 4]
pop [eax + IP_SOCKET.RemoteIP]
 
cmp [eax + TCP_SOCKET.LocalPort], 0
jne @f
call SOCKET_find_port
@@:
 
mov [eax + TCP_SOCKET.timer_persist], 0
mov [eax + TCP_SOCKET.t_state], TCPS_SYN_SENT
 
push [TCP_sequence_num]
add [TCP_sequence_num], 6400
pop [eax + TCP_SOCKET.ISS]
mov [eax + TCP_SOCKET.timer_keepalive], TCP_time_keep_init
 
TCP_sendseqinit eax
; mov [ebx + TCP_SOCKET.timer_retransmission], ;; todo: create macro to set retransmission timer
 
mov ebx, eax
lea eax, [ebx + STREAM_SOCKET.snd]
call SOCKET_ring_create ; TODO: check if memory was available or not
 
lea eax, [ebx + STREAM_SOCKET.rcv]
call SOCKET_ring_create ; TODO: same here
 
pusha
lea ecx, [ebx + SOCKET.mutex]
call mutex_unlock
popa
 
push ebx
mov eax, ebx
call TCP_output
pop eax
 
.block:
test [eax + SOCKET.options], SO_NONBLOCK
jz .loop
 
mov dword[esp+20], EWOULDBLOCK
mov dword[esp+32], -1
ret
 
.loop:
cmp [eax + TCP_SOCKET.t_state], TCPS_CLOSED
je .fail
cmp [eax + TCP_SOCKET.t_state], TCPS_ESTABLISHED
je .established
ja .fail
 
connect_notsupp:
xor eax, eax
dec eax
mov ebx, EOPNOTSUPP
call SOCKET_block
jmp .loop
 
.fail:
mov eax, [eax + SOCKET.errorcode]
mov [esp+20], eax
mov dword[esp+32], -1
ret
 
.established:
mov dword[esp+32], 0
ret
 
 
align 4
.ip:
pusha
lea ecx, [eax + SOCKET.mutex]
call mutex_lock
popa
 
pushd [edx + 4]
pop [eax + IP_SOCKET.RemoteIP]
 
push eax
init_queue (eax + SOCKET_QUEUE_LOCATION) ; Set up data receiving queue
pop eax
 
lea ecx, [eax + SOCKET.mutex]
call mutex_unlock
 
mov dword[esp+32], 0
ret
 
 
;-----------------------------------------------------------------
;
; SOCKET_listen
755,9 → 865,6
call [eax + SOCKET.rcv_proc]
pop edi
 
test [eax + SOCKET.state], SS_CANTRCVMORE
jnz .return
 
cmp ebx, EWOULDBLOCK
jne .return
 
764,6 → 871,9
test edi, MSG_DONTWAIT
jnz .return_err
 
test [eax + SOCKET.state], SS_CANTRCVMORE
jnz .return_err
 
; test [eax + SOCKET.options], SO_NONBLOCK
; jnz .return_err
 
775,10 → 885,10
push EINVAL
pop ebx
.return_err:
mov ecx, -1
mov eax, -1
.return:
mov [esp+20], ebx
mov [esp+32], ecx
mov [esp+32], eax
ret
 
 
799,7 → 909,7
cmp ecx, ebx ; If data segment does not fit in applications buffer, abort
ja .too_small
 
push eax ecx
push ecx
push [esi + socket_queue_entry.buf_ptr] ; save the buffer addr so we can clear it later
mov esi, [esi + socket_queue_entry.data_ptr]
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_receive: Source buffer=%x real addr=%x\n", [esp], esi
820,12 → 930,12
.nd:
 
call NET_packet_free
pop ecx eax ; return number of bytes copied to application
pop eax ; return number of bytes copied to application
xor ebx, ebx
ret
 
.too_small:
mov ecx, -1
mov eax, -1
push EMSGSIZE
pop ebx
ret
870,12 → 980,11
mov edi, edx
xor edx, edx
 
push eax
add eax, STREAM_SOCKET.rcv
call SOCKET_ring_read ; copy data from kernel buffer to application buffer
call SOCKET_ring_free ; free read memory
pop eax
 
mov eax, ecx ; return number of bytes copied
xor ebx, ebx ; errorcode = 0 (no error)
ret
 
882,11 → 991,10
.wouldblock:
push EWOULDBLOCK
pop ebx
xor ecx, ecx
ret
 
.peek:
mov ecx, [eax + STREAM_SOCKET.rcv + RING_BUFFER.size]
mov eax, [eax + STREAM_SOCKET.rcv + RING_BUFFER.size]
xor ebx, ebx
ret
 
2085,7 → 2193,6
mov eax, [eax + SOCKET.NextPtr]
or eax, eax
jz .error
diff16 "tetten", 0, $
cmp [eax + SOCKET.Number], ecx
jne .next_socket
 
2214,11 → 2321,6
align 4
SOCKET_process_end:
 
cmp [net_sockets + SOCKET.NextPtr], 0 ; Are there any active sockets at all?
je .quickret ; nope, exit immediately
 
; TODO: run the following code in another thread, to avoid deadlock
 
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_process_end: %x\n", edx
 
pusha
2269,7 → 2371,6
call mutex_unlock
popa
 
.quickret:
ret
 
 
2289,10 → 2390,10
 
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_is_connecting: %x\n", eax
 
and [eax + SOCKET.state], not (SS_ISCONNECTED + SS_ISDISCONNECTING + SS_ISCONFIRMING)
or [eax + SOCKET.state], SS_ISCONNECTING
and [eax + SOCKET.options], not (SS_ISCONNECTED + SS_ISDISCONNECTING + SS_ISCONFIRMING)
or [eax + SOCKET.options], SS_ISCONNECTING
 
ret
jmp SOCKET_notify
 
 
 
/kernel/branches/Kolibri-acpi/network/stack.inc
115,7 → 115,6
 
; Error Codes
ENOBUFS = 1
EINPROGRESS = 2
EOPNOTSUPP = 4
EWOULDBLOCK = 6
ENOTCONN = 9
126,7 → 125,6
EADDRINUSE = 20
ECONNREFUSED = 61
ECONNRESET = 52
EISCONN = 56
ETIMEDOUT = 60
ECONNABORTED = 53
 
250,8 → 248,6
mov ecx, (NET_DEVICES_MAX + 2)
rep stosd
 
ETH_init
 
PPPoE_init
 
IPv4_init
/kernel/branches/Kolibri-acpi/network/udp.inc
182,7 → 182,7
;
; FIXME: UDP should check remote IP, but not under all circumstances!
 
cmp [eax + UDP_SOCKET.RemotePort], 0
cmp [eax + UDP_SOCKET.firstpacket], 0
je .updateport
 
cmp [eax + UDP_SOCKET.RemotePort], cx
211,6 → 211,8
 
DEBUGF DEBUG_NETWORK_VERBOSE, "UDP_input: new remote port=%x\n", cx ; FIXME: find a way to print big endian values with debugf
mov [eax + UDP_SOCKET.RemotePort], cx
inc [eax + UDP_SOCKET.firstpacket]
 
jmp .updatesock
 
.dump_:
260,6 → 262,7
 
sub esp, 8 ; Data ptr and data size will be placed here
push edx esi
mov ebx, [eax + SOCKET.device]
mov edx, [eax + IP_SOCKET.LocalIP]
mov eax, [eax + IP_SOCKET.RemoteIP]
mov di, IP_PROTO_UDP shl 8 + 128
308,84 → 311,6
 
 
 
 
;-----------------------------------------------------------------
;
; UDP_connect
;
; IN: eax = socket pointer
; OUT: eax = 0 ok / -1 error
; ebx = error code
;
;-------------------------
align 4
UDP_connect:
 
test [eax + SOCKET.state], SS_ISCONNECTED
jz @f
call UDP_disconnect
@@:
 
push eax edx
lea ecx, [eax + SOCKET.mutex]
call mutex_lock
pop edx eax
 
; Fill in local IP
cmp [eax + IP_SOCKET.LocalIP], 0
jne @f
push [IP_LIST + 4] ; FIXME: use correct local IP
pop [eax + IP_SOCKET.LocalIP]
 
; Fill in remote port and IP, overwriting eventually previous values
pushw [edx + 2]
pop [eax + UDP_SOCKET.RemotePort]
 
pushd [edx + 4]
pop [eax + IP_SOCKET.RemoteIP]
 
; Find a local port, if user didnt define one
cmp [eax + UDP_SOCKET.LocalPort], 0
jne @f
call SOCKET_find_port
@@:
 
push eax
init_queue (eax + SOCKET_QUEUE_LOCATION) ; Set up data receiving queue
pop eax
 
push eax
lea ecx, [eax + SOCKET.mutex]
call mutex_unlock
pop eax
 
call SOCKET_is_connected
 
xor eax, eax
ret
 
 
;-----------------------------------------------------------------
;
; UDP_disconnect
;
; IN: eax = socket pointer
; OUT: eax = socket pointer
;
;-------------------------
align 4
UDP_disconnect:
 
; TODO: remove the pending received data
 
call SOCKET_is_disconnected
 
ret
 
 
 
 
 
;---------------------------------------------------------------------------
;
; UDP_API
/kernel/branches/Kolibri-acpi/network/tcp.inc
71,8 → 71,6
TCP_time_srtt_default = 0 ;
TCP_time_max_idle = 8*TCP_time_keep_interval ; FIXME
 
TCP_time_connect = 300 ; in 1/100s (default=3s)
 
; timer constants
TCP_max_rxtshift = 12 ; max retransmissions waiting for ACK
TCP_max_keepcnt = 8 ; max keepalive probes
/kernel/branches/Kolibri-acpi/network/tcp_output.inc
437,6 → 437,8
; Create the IP packet
 
mov ecx, esi
 
mov ebx, [eax + SOCKET.device]
mov edx, [eax + IP_SOCKET.LocalIP] ; source ip
mov eax, [eax + IP_SOCKET.RemoteIP] ; dest ip
mov di, IP_PROTO_TCP shl 8 + 128
/kernel/branches/Kolibri-acpi/network/tcp_usreq.inc
74,139 → 74,8
ret
 
 
;-------------------------
;
; TCP_connect
;
; IN: eax = socket ptr
; OUT: eax = 0 ok / -1 error
; ebx = error code
;
;-------------------------
align 4
TCP_connect:
 
test [eax + SOCKET.state], SS_ISCONNECTED
jnz .eisconn
 
push eax edx
lea ecx, [eax + SOCKET.mutex]
call mutex_lock
pop edx eax
 
; Fill in local IP
cmp [eax + IP_SOCKET.LocalIP], 0
jne @f
push [IP_LIST + 4] ; FIXME: use correct local IP
pop [eax + IP_SOCKET.LocalIP]
 
; Fill in remote port and IP
pushw [edx + 2]
pop [eax + TCP_SOCKET.RemotePort]
 
pushd [edx + 4]
pop [eax + IP_SOCKET.RemoteIP]
 
; Find a local port, if user didnt define one
cmp [eax + TCP_SOCKET.LocalPort], 0
jne @f
call SOCKET_find_port
@@:
 
; Start the TCP sequence
mov [eax + TCP_SOCKET.timer_persist], 0
mov [eax + TCP_SOCKET.t_state], TCPS_SYN_SENT
 
push [TCP_sequence_num]
add [TCP_sequence_num], 6400
pop [eax + TCP_SOCKET.ISS]
mov [eax + TCP_SOCKET.timer_keepalive], TCP_time_keep_init
 
TCP_sendseqinit eax
 
mov ebx, eax
lea eax, [ebx + STREAM_SOCKET.snd]
call SOCKET_ring_create
test eax, eax
jz .nomem
 
lea eax, [ebx + STREAM_SOCKET.rcv]
call SOCKET_ring_create
test eax, eax
jz .nomem
 
push ebx
lea ecx, [ebx + SOCKET.mutex]
call mutex_unlock
pop eax
 
call SOCKET_is_connecting
 
; Now send the SYN packet to remote end
push eax
call TCP_output
pop eax
 
.block:
test [eax + SOCKET.options], SO_NONBLOCK
jz .waitforit
 
xor eax, eax
dec eax
mov ebx, EINPROGRESS
ret
 
.nomem:
xor eax, eax
dec eax
mov ebx, ENOMEM
ret
 
.eisconn:
xor eax, eax
dec eax
mov ebx, EISCONN
ret
 
.waitforit:
push eax
stdcall timer_hs, TCP_time_connect, 0, .timeout, eax
pop ebx
mov [ebx + TCP_SOCKET.timer_connect], eax
mov eax, ebx
 
.loop:
cmp [eax + SOCKET.errorcode], 0
jne .fail
cmp [eax + TCP_SOCKET.t_state], TCPS_ESTABLISHED
je .established
 
call SOCKET_block
jmp .loop
 
.timeout:
mov eax, [esp+4]
mov [eax + SOCKET.errorcode], ETIMEDOUT
and [eax + SOCKET.state], not SS_ISCONNECTING
call SOCKET_notify.unblock
ret 4
 
.fail:
mov ebx, [eax + SOCKET.errorcode]
mov [eax + SOCKET.errorcode], 0 ; Clear the error, we only need to send it to the caller once
xor eax, eax
dec eax
ret
 
.established:
stdcall cancel_timer_hs, [eax + TCP_SOCKET.timer_connect]
 
xor eax, eax
ret
 
 
 
 
;-------------------------
;
; TCP_disconnect
/kernel/branches/Kolibri-acpi/encoding.inc
97,12 → 97,6
end while
}
 
struc cp866 [arg]
{
common
cp866 arg
}
 
; Latin-1 encoding
; 0x00-0xFF - trivial map
macro latin1 [arg]
123,12 → 117,6
end while
}
 
struc latin1 [arg]
{
common
latin1 arg
}
 
; CP850 encoding
macro cp850 [arg]
{ local offs, char, graph
159,9 → 147,3
end if
end while
}
 
struc cp850 [arg]
{
common
cp850 arg
}
/kernel/branches/Kolibri-acpi/kernel32.inc
171,7 → 171,6
include "core/irq.inc" ; irq handling functions
include "core/apic.inc" ; Interrupt Controller functions
include "core/timers.inc"
include "core/clipboard.inc" ; custom clipboard
 
; GUI stuff
include "gui/window.inc"
192,8 → 191,7
include "blkdev/rd.inc" ; ramdisk read /write
include "fs/fs_lfn.inc" ; syscall, version 2
include "fs/iso9660.inc" ; read for iso9660 filesystem CD
include "fs/ext2/ext2.asm" ; read / write for ext2 filesystem
include "fs/xfs.asm" ; read / write for xfs filesystem
include "fs/ext2.inc" ; read / write for ext2 filesystem
 
; sound
 
/kernel/branches/Kolibri-acpi/kernelsp.inc
1,4 → 1,4
; Éste archivo debe ser editado con codificación CP866
 
version cp850 'Kolibri OS versión 0.7.7.0+ ',13,10,13,10,0
version: cp850 'Kolibri OS versión 0.7.7.0+ ',13,10,13,10,0
diff16 "fin del código del kernel",0,$