Subversion Repositories Kolibri OS

Compare Revisions

No changes between revisions

Ignore whitespace Rev 3186 → Rev 3187

/kernel/branches/net/blkdev/disk.inc
347,14 → 347,16
push eax ; save allocated pointer to DISK
xor eax, eax ; the argument of malloc() is in eax
@@:
inc eax
cmp byte [ebx+eax-1], 0
jnz @b
; 2b. Call the heap manager.
call malloc
; 2c. Check the result. If allocation failed, go to 7.
pop esi ; restore allocated pointer to DISK
test eax, eax
inc eax
cmp byte [ebx+eax-1], 0
jnz @b
; 2b. Call the heap manager. Note that it can change ebx.
push ebx
call malloc
pop ebx
; 2c. Check the result. If allocation failed, go to 7.
pop esi ; restore allocated pointer to DISK
test eax, eax
jz .free
; 2d. Store the allocated pointer to the DISK structure.
mov [esi+DISK.Name], eax
415,13 → 417,13
; [esp+4] = handle of the disk, i.e. the pointer to the DISK structure.
; Return value: none.
disk_del:
push esi ; save used registers to be stdcall
; 1. Force media to be removed. If the media is already removed, the
; call does nothing.
mov esi, [esp+4+8] ; esi = handle of the disk
stdcall disk_media_changed, esi, 0
; 2. Delete the structure from the global list.
; 2a. Acquire the mutex.
push esi ; save used registers to be stdcall
; 1. Force media to be removed. If the media is already removed, the
; call does nothing.
mov esi, [esp+4+4] ; esi = handle of the disk
stdcall disk_media_changed, esi, 0
; 2. Delete the structure from the global list.
; 2a. Acquire the mutex.
mov ecx, disk_list_mutex
call mutex_lock
; 2b. Delete item from double-linked list.
621,14 → 623,14
disk_default_flush:
xor eax, eax
ret 4
 
; The default implementation of DISKFUNC.adjust_cache_size.
disk_default_adjust_cache_size:
mov eax, [esp+4]
ret 4
 
; This is an internal function called from 'disk_media_changed' when a new media
; is detected. It creates the list of partitions for the media.
 
; The default implementation of DISKFUNC.adjust_cache_size.
disk_default_adjust_cache_size:
mov eax, [esp+8]
ret 8
 
; This is an internal function called from 'disk_media_changed' when a new media
; is detected. It creates the list of partitions for the media.
; If media is not partitioned, then the list consists of one partition which
; covers all the media.
; esi = pointer to the DISK structure.
972,31 → 974,53
; with ebp-based frame arguments start from ebp+8, since [ebp]=saved ebp
; and [ebp+4]=return address.
virtual at ebp+8
.start dq ?
.length dq ?
end virtual
; Currently no file systems are supported, so just allocate the PARTITION
; structure without extra fields.
; 1. Allocate and check result.
push sizeof.PARTITION
pop eax
call malloc
test eax, eax
jz .nothing
; 2. Fill the common fields: copy .start and .length.
mov edx, dword [.start]
mov dword [eax+PARTITION.FirstSector], edx
mov edx, dword [.start+4]
.start dq ?
.length dq ?
end virtual
; When disk_add_partition is called, ebx contains a pointer to
; a two-sectors-sized buffer. This function saves ebx in the stack
; immediately before ebp.
virtual at ebp-4
.buffer dd ?
end virtual
; 1. Read the bootsector to the buffer.
mov al, DISKFUNC.read
mov ebx, [.buffer]
add ebx, 512
push 1
stdcall disk_call_driver, ebx, dword [.start], dword [.start+4], esp
; 2. Run tests for all supported filesystems. If at least one test succeeded,
; go to 4.
; For tests: qword [ebp+8] = partition start, qword [ebp+10h] = partition
; length, [esp] = 0 if reading bootsector failed or 1 if succeeded,
; ebx points to the buffer for bootsector.
call fat_create_partition
test eax, eax
jnz .success
; 3. No file system has recognized the volume, so just allocate the PARTITION
; structure without extra fields.
push sizeof.PARTITION
pop eax
call malloc
test eax, eax
jz .nothing
mov edx, dword [.start]
mov dword [eax+PARTITION.FirstSector], edx
mov edx, dword [.start+4]
mov dword [eax+PARTITION.FirstSector+4], edx
mov edx, dword [.length]
mov dword [eax+PARTITION.Length], edx
mov edx, dword [.length+4]
mov dword [eax+PARTITION.Length+4], edx
.nothing:
; 3. Return with eax = pointer to PARTITION or NULL.
ret
 
; This function is called from file_system_lfn.
mov dword [eax+PARTITION.Length], edx
mov edx, dword [.length+4]
mov dword [eax+PARTITION.Length+4], edx
mov [eax+PARTITION.Disk], esi
and [eax+PARTITION.FSUserFunctions], 0
.success:
.nothing:
; 4. Return with eax = pointer to PARTITION or NULL.
pop ecx
ret
 
; This function is called from file_system_lfn.
; This handler gets the control each time when fn 70 is called
; with unknown item of root subdirectory.
; in: esi -> name
1058,12 → 1082,13
; We found the addressed DISK structure.
; 5. Reference the disk.
lock inc [ebx+DISK.RefCount]
; 6. Now we are sure that the DISK structure is not going to die at least
; while we are working with it, so release the global mutex.
call mutex_unlock
; 7. Acquire the mutex for media object.
pop edi ; restore edi
lea ecx, [ebx+DISK.MediaLock]
; 6. Now we are sure that the DISK structure is not going to die at least
; while we are working with it, so release the global mutex.
call mutex_unlock
pop ecx ; pop from the stack saved value of esi
; 7. Acquire the mutex for media object.
pop edi ; restore edi
lea ecx, [ebx+DISK.MediaLock]
call mutex_lock
; 8. Get the media object. If it is not NULL, reference it.
xor edx, edx
1172,30 → 1197,50
pop edx edx edx eax ; edx = pointer to DISK, eax = NULL or edx
test eax, eax
jz .nomedia
.main:
cmp ecx, [edx+DISK.NumPartitions]
jae .notfound
mov dword [esp+32], ERROR_UNKNOWN_FS
.cleanup:
mov esi, edx
call disk_media_dereference
call disk_dereference
ret
.notfound:
mov dword [esp+32], ERROR_FILE_NOT_FOUND
jmp .cleanup
.nomedia:
test ecx, ecx
jnz .notfound
.main:
cmp ecx, [edx+DISK.NumPartitions]
jae .notfound
mov eax, [edx+DISK.Partitions]
mov eax, [eax+ecx*4]
mov edi, [eax+PARTITION.FSUserFunctions]
test edi, edi
jz .nofs
mov ecx, [ebx]
cmp [edi], ecx
jbe .unsupported
push edx
push ebp
mov ebp, eax
call dword [edi+4+ecx*4]
pop ebp
pop edx
mov dword [esp+32], eax
mov dword [esp+20], ebx
.cleanup:
mov esi, edx
call disk_media_dereference
call disk_dereference
ret
.nofs:
mov dword [esp+32], ERROR_UNKNOWN_FS
jmp .cleanup
.notfound:
mov dword [esp+32], ERROR_FILE_NOT_FOUND
jmp .cleanup
.unsupported:
mov dword [esp+32], ERROR_UNSUPPORTED_FS
jmp .cleanup
.nomedia:
test ecx, ecx
jnz .notfound
test byte [edx+DISK.DriverFlags], DISK_NO_INSERT_NOTIFICATION
jz .deverror
; if the driver does not support insert notifications and we are the only fs
; operation with this disk, issue the fake insert notification; if media is
; still not inserted, 'disk_media_changed' will detect this and do nothing
;;; push ebx
lea ecx, [edx+DISK.MediaLock]
call mutex_lock
cmp [edx+DISK.MediaRefCount], 1
; if the driver does not support insert notifications and we are the only fs
; operation with this disk, issue the fake insert notification; if media is
; still not inserted, 'disk_media_changed' will detect this and do nothing
lea ecx, [edx+DISK.MediaLock]
call mutex_lock
cmp [edx+DISK.MediaRefCount], 1
jnz .noluck
call mutex_unlock
push edx
/kernel/branches/net/blkdev/disk_cache.inc
15,15 → 15,17
; out: eax = error code; 0 = ok
fs_read32_sys:
; Compatibility hack: if PARTITION.Disk is 'old', there is no DISK structure,
; this request should be processed by hd_read.
cmp [ebp+PARTITION.Disk], 'old'
jnz @f
mov [hdd_appl_data], 0
call hd_read
mov [hdd_appl_data], 1 ; restore to default state
ret
@@:
; In the normal case, save ecx, set ecx to SysCache and let the common part
; this request should be processed by hd_read.
cmp [ebp+PARTITION.Disk], 'old'
jnz @f
add eax, dword [ebp+PARTITION.FirstSector]
mov [hdd_appl_data], 0
call hd_read
mov [hdd_appl_data], 1 ; restore to default state
mov eax, [hd_error]
ret
@@:
; In the normal case, save ecx, set ecx to SysCache and let the common part
; do its work.
push ecx
mov ecx, [ebp+PARTITION.Disk]
38,14 → 40,17
; out: eax = error code; 0 = ok
fs_read32_app:
; Compatibility hack: if PARTITION.Disk is 'old', there is no DISK structure,
; this request should be processed by hd_read.
cmp [ebp+PARTITION.Disk], 'old'
jnz @f
mov [hdd_appl_data], 1
jmp hd_read
@@:
; In the normal case, save ecx, set ecx to AppCache and let the common part
; do its work.
; this request should be processed by hd_read.
cmp [ebp+PARTITION.Disk], 'old'
jnz @f
add eax, dword [ebp+PARTITION.FirstSector]
mov [hdd_appl_data], 1
call hd_read
mov eax, [hd_error]
ret
@@:
; In the normal case, save ecx, set ecx to AppCache and let the common part
; do its work.
push ecx
mov ecx, [ebp+PARTITION.Disk]
add ecx, DISK.AppCache
60,33 → 65,34
ja @f
mov eax, DISK_STATUS_END_OF_MEDIA
pop ecx
ret
@@:
; 2. Get the absolute sector on the disk.
push edx
xor edx, edx
add eax, dword [ebp+PARTITION.FirstSector]
adc edx, dword [ebp+PARTITION.FirstSector+4]
ret
@@:
; 2. Get the absolute sector on the disk.
push edx esi
xor edx, edx
add eax, dword [ebp+PARTITION.FirstSector]
adc edx, dword [ebp+PARTITION.FirstSector+4]
; 3. If there is no cache for this disk, just pass the request to the driver.
cmp [ecx+DISKCACHE.pointer], 0
jnz .scancache
push 1
push esp ; numsectors
push edx ; startsector
push eax ; startsector
push ebx ; buffer
mov al, DISKFUNC.read
call disk_call_driver
pop ecx
pop edx
pop ecx
ret
.scancache:
; 4. Scan the cache.
push esi edi ecx ; scan cache
push edx eax
virtual at esp
.sector_lo dd ?
push edx ; startsector
push eax ; startsector
push ebx ; buffer
mov esi, [ebp+PARTITION.Disk]
mov al, DISKFUNC.read
call disk_call_driver
pop ecx
pop esi edx
pop ecx
ret
.scancache:
; 4. Scan the cache.
push edi ecx ; scan cache
push edx eax
virtual at esp
.sector_lo dd ?
.sector_hi dd ?
.cache dd ?
end virtual
126,13 → 132,13
jnz .read_done
 
push 1
push esp
push edx
push [.sector_lo+12]
mov ecx, [.cache]
mov eax, edi
shl eax, 9
add eax, [ecx+DISKCACHE.data]
push esp
push edx
push [.sector_lo+12]
mov ecx, [.cache+16]
mov eax, edi
shl eax, 9
add eax, [ecx+DISKCACHE.data]
push eax
mov esi, [ebp+PARTITION.Disk]
mov al, DISKFUNC.read
180,15 → 186,17
; out: eax = error code; 0 = ok
fs_write32_sys:
; Compatibility hack: if PARTITION.Disk is 'old', there is no DISK structure,
; this request should be processed by hd_write.
cmp [ebp+PARTITION.Disk], 'old'
jnz @f
mov [hdd_appl_data], 0
call hd_write
mov [hdd_appl_data], 1 ; restore to default state
ret
@@:
; In the normal case, save ecx, set ecx to SysCache and let the common part
; this request should be processed by hd_write.
cmp [ebp+PARTITION.Disk], 'old'
jnz @f
add eax, dword [ebp+PARTITION.FirstSector]
mov [hdd_appl_data], 0
call hd_write
mov [hdd_appl_data], 1 ; restore to default state
mov eax, [hd_error]
ret
@@:
; In the normal case, save ecx, set ecx to SysCache and let the common part
; do its work.
push ecx
mov ecx, [ebp+PARTITION.Disk]
203,14 → 211,17
; out: eax = error code; 0 = ok
fs_write32_app:
; Compatibility hack: if PARTITION.Disk is 'old', there is no DISK structure,
; this request should be processed by hd_write.
cmp [ebp+PARTITION.Disk], 'old'
jnz @f
mov [hdd_appl_data], 1
jmp hd_write
@@:
; In the normal case, save ecx, set ecx to AppCache and let the common part
; do its work.
; this request should be processed by hd_write.
cmp [ebp+PARTITION.Disk], 'old'
jnz @f
add eax, dword [ebp+PARTITION.FirstSector]
mov [hdd_appl_data], 1
call hd_write
mov eax, [hd_error]
ret
@@:
; In the normal case, save ecx, set ecx to AppCache and let the common part
; do its work.
push ecx
mov ecx, [ebp+PARTITION.Disk]
add ecx, DISK.AppCache
224,13 → 235,13
cmp dword [ebp+PARTITION.Length], eax
ja @f
mov eax, DISK_STATUS_END_OF_MEDIA
pop ecx
ret
@@:
push edx
; 2. Get the absolute sector on the disk.
xor edx, edx
add eax, dword [ebp+PARTITION.FirstSector]
pop ecx
ret
@@:
push edx esi
; 2. Get the absolute sector on the disk.
xor edx, edx
add eax, dword [ebp+PARTITION.FirstSector]
adc edx, dword [ebp+PARTITION.FirstSector+4]
; 3. If there is no cache for this disk, just pass request to the driver.
cmp [ecx+DISKCACHE.pointer], 0
237,21 → 248,22
jnz .scancache
push 1
push esp ; numsectors
push edx ; startsector
push eax ; startsector
push ebx ; buffer
mov al, DISKFUNC.write
call disk_call_driver
pop ecx
pop edx
pop ecx
ret
.scancache:
; 4. Scan the cache.
push esi edi ecx ; scan cache
push edx eax
virtual at esp
.sector_lo dd ?
push edx ; startsector
push eax ; startsector
push ebx ; buffer
mov esi, [ebp+PARTITION.Disk]
mov al, DISKFUNC.write
call disk_call_driver
pop ecx
pop esi edx
pop ecx
ret
.scancache:
; 4. Scan the cache.
push edi ecx ; scan cache
push edx eax
virtual at esp
.sector_lo dd ?
.sector_hi dd ?
.cache dd ?
end virtual
302,13 → 314,13
mov edx, [.sector_hi]
mov [esi], eax ; sector number
mov [esi+4], edx ; sector number
 
.yes_in_cache_write:
 
mov dword [esi+4], 2 ; write - differs from hd
 
shl edi, 9
mov ecx, [.cache]
 
.yes_in_cache_write:
 
mov dword [esi+8], 2 ; write - differs from hd
 
shl edi, 9
mov ecx, [.cache]
add edi, [ecx+DISKCACHE.data]
 
mov esi, ebx
345,30 → 357,31
shl eax, 2
add eax, [esi+DISKCACHE.pointer]
cmp dword [eax+8], 2
jb .found_slot ; it's empty or read
dec ecx
jnz .search_for_empty
call write_cache64 ; no empty slots found, write all
test eax, eax
jne .found_slot_access_denied
jmp .search_again ; and start again
jb .found_slot ; it's empty or read
dec ecx
jnz .search_for_empty
stdcall write_cache64, [ebp+PARTITION.Disk] ; no empty slots found, write all
test eax, eax
jne .found_slot_access_denied
jmp .search_again ; and start again
.found_slot:
mov [esi+DISKCACHE.search_start], edi
xor eax, eax ; success
.found_slot_access_denied:
ret
 
; This function is intended to replace the old 'write_cache' function.
proc write_cache64 uses ecx edx esi edi
locals
cache_chain_started dd ?
cache_chain_size dd ?
cache_chain_pos dd ?
cache_chain_ptr dd ?
endl
; If there is no cache for this disk, nothing to do.
cmp [esi+DISKCACHE.pointer], 0
jz .flush
ret
 
; This function is intended to replace the old 'write_cache' function.
proc write_cache64 uses ecx edx esi edi, disk:dword
locals
cache_chain_started dd 0
cache_chain_size dd ?
cache_chain_pos dd ?
cache_chain_ptr dd ?
endl
saved_esi_pos = 16+12 ; size of local variables + size of registers before esi
; If there is no cache for this disk, nothing to do.
cmp [esi+DISKCACHE.pointer], 0
jz .flush
;-----------------------------------------------------------
; write all changed sectors to disk
;-----------------------------------------------------------
429,14 → 442,13
dec ecx
jnz .write_cache_more
call .flush_cache_chain
test eax, eax
jnz .nothing
.flush:
mov esi, [ebp]
mov esi, [esi+PARTITION.Disk]
mov al, DISKFUNC.flush
call disk_call_driver
.nothing:
test eax, eax
jnz .nothing
.flush:
mov esi, [disk]
mov al, DISKFUNC.flush
call disk_call_driver
.nothing:
ret
 
.flush_cache_chain:
451,13 → 463,13
.write_cache_sector:
mov [cache_chain_size], 1
mov [cache_chain_pos], edi
.write_cache_chain:
pusha
mov edi, [cache_chain_pos]
mov ecx, [ebp-12]
shl edi, 9
add edi, [ecx+DISKCACHE.data]
mov ecx, [cache_chain_size]
.write_cache_chain:
pusha
mov edi, [cache_chain_pos]
mov ecx, [ebp-saved_esi_pos]
shl edi, 9
add edi, [ecx+DISKCACHE.data]
mov ecx, [cache_chain_size]
push ecx
push esp ; numsectors
mov eax, [cache_chain_ptr]
535,13 → 547,13
imul eax, 7
mov [esi+DISK.AppCache.data_size], eax
mov [esi+DISK.AppCache.pointer], edx
 
mov eax, [esi+DISK.SysCache.data_size]
push ebx
call calculate_for_hd
pop ebx
add eax, [esi+DISK.SysCache.pointer]
mov [esi+DISK.SysCache.data], eax
 
mov eax, [esi+DISK.SysCache.data_size]
push ebx
call calculate_for_hd64
pop ebx
add eax, [esi+DISK.SysCache.pointer]
mov [esi+DISK.SysCache.data], eax
mov [esi+DISK.SysCache.sad_size], ecx
 
push edi
550,13 → 562,13
xor eax, eax
rep stosd
pop edi
 
mov eax, [esi+DISK.AppCache.data_size]
push ebx
call calculate_for_hd
pop ebx
add eax, [esi+DISK.AppCache.pointer]
mov [esi+DISK.AppCache.data], eax
 
mov eax, [esi+DISK.AppCache.data_size]
push ebx
call calculate_for_hd64
pop ebx
add eax, [esi+DISK.AppCache.pointer]
mov [esi+DISK.AppCache.data], eax
mov [esi+DISK.AppCache.sad_size], ecx
 
push edi
576,17 → 588,56
.nocache:
mov [esi+DISK.SysCache.pointer], eax
mov [esi+DISK.AppCache.pointer], eax
mov al, 1
ret
 
; This internal function is called from disk_media_dereference to free the
; allocated cache, if there is one.
; esi = pointer to DISK structure
mov al, 1
ret
 
calculate_for_hd64:
push eax
mov ebx, eax
shr eax, 9
lea eax, [eax*3]
shl eax, 2
sub ebx, eax
shr ebx, 9
mov ecx, ebx
shl ebx, 9
pop eax
sub eax, ebx
dec ecx
ret
 
 
; This internal function is called from disk_media_dereference to free the
; allocated cache, if there is one.
; esi = pointer to DISK structure
disk_free_cache:
; The algorithm is straightforward.
mov eax, [esi+DISK.SysCache.pointer]
test eax, eax
jz .nothing
stdcall kernel_free, eax
.nothing:
ret
stdcall kernel_free, eax
.nothing:
ret
 
; This function flushes all modified data from both caches for the given DISK.
; esi = pointer to DISK
disk_sync:
; Compatibility hack: if PARTITION.Disk is 'old', there is no DISK structure,
; this request should be processed by write_cache.
cmp esi, 'old'
jnz @f
mov [hdd_appl_data], 0
call write_cache
mov [hdd_appl_data], 1
jmp write_cache
@@:
; The algorithm is straightforward.
push esi
push esi ; for second write_cache64
push esi ; for first write_cache64
add esi, DISK.SysCache
call write_cache64
add esi, DISK.AppCache - DISK.SysCache
call write_cache64
pop esi
ret
/kernel/branches/net/blkdev/hd_drv.inc
942,6 → 942,86
test byte [int13_regs_out+v86_regs.eflags], 1
jnz @f
mov edx, ecx
@@:
ret
; \end{diamond}
@@:
ret
; \end{diamond}
 
reserve_hd1:
 
cli
cmp [hd1_status], 0
je reserve_ok1
 
sti
call change_task
jmp reserve_hd1
 
reserve_ok1:
 
push eax
mov eax, [CURRENT_TASK]
shl eax, 5
mov eax, [eax+CURRENT_TASK+TASKDATA.pid]
mov [hd1_status], eax
pop eax
sti
ret
;********************************************
 
uglobal
hd_in_cache db ?
endg
 
reserve_hd_channel:
; BIOS disk accesses are protected with common mutex hd1_status
; This must be modified when hd1_status will not be valid!
cmp [hdpos], 0x80
jae .ret
cmp [hdbase], 0x1F0
jne .IDE_Channel_2
.IDE_Channel_1:
cli
cmp [IDE_Channel_1], 0
je .reserve_ok_1
sti
call change_task
jmp .IDE_Channel_1
.IDE_Channel_2:
cli
cmp [IDE_Channel_2], 0
je .reserve_ok_2
sti
call change_task
jmp .IDE_Channel_2
.reserve_ok_1:
mov [IDE_Channel_1], 1
push eax
mov al, 1
jmp @f
.reserve_ok_2:
mov [IDE_Channel_2], 1
push eax
mov al, 3
@@:
cmp [hdid], 1
sbb al, -1
mov [hd_in_cache], al
pop eax
sti
.ret:
ret
 
free_hd_channel:
; see comment at reserve_hd_channel
cmp [hdpos], 0x80
jae .ret
cmp [hdbase], 0x1F0
jne .IDE_Channel_2
.IDE_Channel_1:
mov [IDE_Channel_1], 0
.ret:
ret
.IDE_Channel_2:
mov [IDE_Channel_2], 0
ret
;********************************************
/kernel/branches/net/blkdev/ide_cache.inc
134,14 → 134,12
call calculate_cache_5
found_slot_access_denied:
ret
;--------------------------------------------------------------------
align 4
clear_hd_cache:
mov [fat_in_cache], -1
mov [fat_change], 0
ret
;--------------------------------------------------------------------
align 4
;--------------------------------------------------------------------
align 4
clear_hd_cache:
ret
;--------------------------------------------------------------------
align 4
calculate_cache:
; mov ecx,cache_max ; entries in cache
; mov esi,HD_CACHE+8
/kernel/branches/net/boot/preboot.inc
33,6 → 33,6
 
if $>0x200
ERROR: prebooting parameters must fit in first sector!!!
end if
end if
hdsysimage db 'KOLIBRI IMG' ; load from
image_save db 'KOLIBRI IMG' ; save to
/kernel/branches/net/boot/rdload.inc
86,19 → 86,28
jz image_present
ret
image_present:
mov [image_retrieved],1
ret
 
read_image:
mov eax, hdsysimage+OS_BASE+0x10000
mov ebx, 1474560/512
mov ecx, RAMDISK
mov esi, 0
mov edi, 12
call file_read
ret
 
image_retrieved db 0
mov [image_retrieved], 1
ret
 
iglobal
align 4
read_image_fsinfo:
dd 0 ; function: read
dq 0 ; offset: zero
dd 1474560/512 ; size
dd RAMDISK ; buffer
db 0
dd hdsysimage+OS_BASE+0x10000
endg
 
read_image:
mov ebx, read_image_fsinfo
pushad
call file_system_lfn
popad
ret
 
image_retrieved db 0
counter_of_partitions db 0
no_sys_on_hd:
; test_to_format_ram_disk (need if not using ram disk)
/kernel/branches/net/const.inc
260,16 → 260,13
MOUSE_BACKGROUND equ (OS_BASE+0x000FFF4)
DONT_DRAW_MOUSE equ (OS_BASE+0x000FFF5)
DONT_SWITCH equ (OS_BASE+0x000FFFF)
 
TMP_STACK_TOP equ 0x006CC00
 
sys_pgdir equ (OS_BASE+0x006F000)
 
DRIVE_DATA equ (OS_BASE+0x0070000)
 
TMP_STACK_TOP equ 0x006CC00
 
FONT_II equ (OS_BASE+0x006DC00)
FONT_I equ (OS_BASE+0x006E600)
 
sys_pgdir equ (OS_BASE+0x006F000)
 
DRIVE_DATA equ (OS_BASE+0x0070000)
 
SLOT_BASE equ (OS_BASE+0x0080000)
 
;unused
/kernel/branches/net/core/dll.inc
807,21 → 807,13
mov ebx, [start]
stdcall ebx, DRV_ENTRY
test eax, eax
jnz .ok
 
stdcall kernel_free, [img_base]
cmp dword [file_name+13], 'SOUN'
jnz @f
cmp dword [file_name+17], 'D.ob'
jnz @f
cmp word [file_name+21], 'j'
jnz @f
mov esi, aHDA
jmp .redo
@@:
xor eax, eax
ret
.ok:
jnz .ok
 
stdcall kernel_free, [img_base]
 
xor eax, eax
ret
.ok:
mov ebx, [img_base]
mov [eax+SRV.base], ebx
mov ecx, [start]
/kernel/branches/net/core/exports.inc
69,12 → 69,15
szSysMsgBoardChar db 'SysMsgBoardChar', 0
szGetCurrentTask db 'GetCurrentTask',0
szLFBAddress db 'LFBAddress',0
szLoadFile db 'LoadFile',0
szSendEvent db 'SendEvent',0
szSetMouseData db 'SetMouseData',0
szSleep db 'Sleep',0
szGetTimerTicks db 'GetTimerTicks',0
 
szLoadFile db 'LoadFile',0
szSendEvent db 'SendEvent',0
szSetMouseData db 'SetMouseData',0
szSetKeyboardData db 'SetKeyboardData',0
szRegKeyboard db 'RegKeyboard',0
szDelKeyboard db 'DelKeyboard',0
szSleep db 'Sleep',0
szGetTimerTicks db 'GetTimerTicks',0
 
szGetDisplay db 'GetDisplay',0
szSetScreen db 'SetScreen',0
 
158,12 → 161,15
dd szSysMsgBoardStr , sys_msg_board_str
dd szSysMsgBoardChar , sys_msg_board
dd szGetCurrentTask , get_curr_task
dd szLoadFile , load_file ;retval eax, ebx
dd szSendEvent , send_event ;see EVENT.inc for specification
dd szSetMouseData , set_mouse_data ;stdcall
dd szSleep , delay_ms
dd szGetTimerTicks , get_timer_ticks
 
dd szLoadFile , load_file ;retval eax, ebx
dd szSendEvent , send_event ;see EVENT.inc for specification
dd szSetMouseData , set_mouse_data ;stdcall
dd szSetKeyboardData , set_keyboard_data
dd szRegKeyboard , register_keyboard
dd szDelKeyboard , delete_keyboard
dd szSleep , delay_ms
dd szGetTimerTicks , get_timer_ticks
 
dd szGetDisplay , get_display
dd szSetScreen , set_screen
 
/kernel/branches/net/core/malloc.inc
338,17 → 338,16
 
mov [esi+edi], esi
 
; insert_chunk(p,psize);
; insert_chunk(p,psize);
 
mov eax, esi
mov ecx, edi
call insert_chunk
jmp .fail2
.unl_large:
 
; unlink_large_chunk((tchunkptr)next);
 
mov eax, esi
pop esi
mov ecx, edi
pop edi
jmp insert_chunk
.unl_large:
 
; unlink_large_chunk((tchunkptr)next);
 
mov edx, ebx
call unlink_large_chunk
; p->head = psize|PINUSE_BIT;
361,16 → 360,15
 
mov [esi+edi], esi
 
; insert_chunk(p,psize);
 
mov eax, esi
pop esi
mov ecx, edi
pop edi
jmp insert_chunk
.fix_next:
 
; (p+psize)->prev_foot = psize;
; insert_chunk(p,psize);
 
mov eax, esi
mov ecx, edi
call insert_chunk
jmp .fail2
.fix_next:
 
; (p+psize)->prev_foot = psize;
; next->head &= ~PINUSE_BIT;
; p->head = psize|PINUSE_BIT;
 
383,16 → 381,15
; (p+psize)->prev_foot = psize;
 
mov [esi+edi], esi
; insert_chunk(p,psize);
 
mov eax, esi
pop esi
mov ecx, edi
pop edi
jmp insert_chunk
 
; param
; ecx = chunk
; insert_chunk(p,psize);
 
mov eax, esi
mov ecx, edi
call insert_chunk
jmp .fail2
 
; param
; ecx = chunk
; eax = size
 
insert_chunk:
415,21 → 412,17
mov edx, [eax+8] ;F = B->fd
mov [eax+8], esi ;B->fd = P
mov [edx+12], esi ;F->bk = P
mov [esi+8], edx ;P->fd = F
mov [esi+12], eax ;P->bk = B
pop esi
mov ecx, mst.mutex
call mutex_unlock
ret
.large:
mov ebx, eax
call insert_large_chunk
pop esi
mov ecx, mst.mutex
call mutex_unlock
ret
 
 
mov [esi+8], edx ;P->fd = F
mov [esi+12], eax ;P->bk = B
pop esi
ret
.large:
mov ebx, eax
call insert_large_chunk
pop esi
ret
 
 
; param
; esi= chunk
; ebx= size
/kernel/branches/net/core/memory.inc
439,79 → 439,90
ret
endp
 
align 4
proc new_mem_resize stdcall, new_size:dword
 
mov ecx, pg_data.mutex
call mutex_lock
 
mov edi, [new_size]
add edi, 4095
and edi, not 4095
mov [new_size], edi
 
mov edx, [current_slot]
cmp [edx+APPDATA.heap_base], 0
jne .exit
 
mov esi, [edx+APPDATA.mem_size]
add esi, 4095
and esi, not 4095
 
cmp edi, esi
jae .expand
 
shr edi, 12
shr esi, 12
@@:
mov eax, [app_page_tabs+edi*4]
test eax, 1
jz .next
mov dword [app_page_tabs+edi*4], 2
mov ebx, edi
shl ebx, 12
push eax
invlpg [ebx]
pop eax
call free_page
 
.next:
add edi, 1
cmp edi, esi
jb @B
 
.update_size:
mov ebx, [new_size]
call update_mem_size
 
mov ecx, pg_data.mutex
call mutex_unlock
 
xor eax, eax
ret
.expand:
 
push esi
align 4
proc new_mem_resize stdcall, new_size:dword
 
push ebx
push esi
push edi
 
mov edx, [current_slot]
cmp [edx+APPDATA.heap_base], 0
jne .exit
 
mov edi, [new_size]
add edi, 4095
and edi, not 4095
mov [new_size], edi
 
mov esi, [edx+APPDATA.mem_size]
add esi, 4095
and esi, not 4095
 
cmp edi, esi
ja .expand
je .exit
 
mov ebx, edi
shr edi, 12
shr esi, 12
 
mov ecx, pg_data.mutex
call mutex_lock
@@:
mov eax, [app_page_tabs+edi*4]
test eax, 1
jz .next
 
mov dword [app_page_tabs+edi*4], 0
invlpg [ebx]
call free_page
 
.next:
inc edi
add ebx, 0x1000
cmp edi, esi
jb @B
 
mov ecx, pg_data.mutex
call mutex_unlock
 
.update_size:
mov edx, [current_slot]
mov ebx, [new_size]
call update_mem_size
.exit:
pop edi
pop esi
pop ebx
xor eax, eax
ret
 
.expand:
 
mov ecx, pg_data.mutex
call mutex_lock
 
xchg esi, edi
 
push esi ;new size
push edi ;old size
 
add edi, 0x3FFFFF
and edi, not(0x3FFFFF)
add esi, 0x3FFFFF
and esi, not(0x3FFFFF)
 
cmp edi, esi
jae .grow
@@:
call alloc_page
test eax, eax
jz .exit_fail
 
stdcall map_page_table, edi, eax
 
push edi
 
add edi, 0x3FFFFF
and edi, not(0x3FFFFF)
add esi, 0x3FFFFF
and esi, not(0x3FFFFF)
 
cmp esi, edi
jae .grow
 
xchg esi, edi
 
@@:
call alloc_page
test eax, eax
jz .exit_pop
 
stdcall map_page_table, edi, eax
 
push edi
shr edi, 10
add edi, page_tabs
mov ecx, 1024
521,57 → 532,44
pop edi
 
add edi, 0x00400000
cmp edi, esi
jb @B
.grow:
;//-
pop edi
push edi
mov esi, [pg_data.pages_free]
sub esi, 1
shr edi, 12
cmp esi, edi
jle .out_of_memory
;//-
pop edi
pop esi
@@:
call alloc_page
test eax, eax
jz .exit
stdcall map_page, esi, eax, dword PG_UW
 
push edi
mov edi, esi
xor eax, eax
mov ecx, 1024
cld
rep stosd
pop edi
 
add esi, 0x1000
cmp esi, edi
jb @B
 
jmp .update_size
;//-
.exit_pop:
.out_of_memory:
;//-
pop edi
pop esi
.exit:
mov ecx, pg_data.mutex
call mutex_unlock
 
xor eax, eax
inc eax
ret
endp
 
update_mem_size:
; in: edx = slot base
; ebx = new memory size
cmp edi, esi
jb @B
.grow:
pop edi ;old size
pop ecx ;new size
 
shr edi, 10
shr ecx, 10
sub ecx, edi
shr ecx, 2 ;pages count
mov eax, 2
 
add edi, app_page_tabs
rep stosd
 
mov ecx, pg_data.mutex
call mutex_unlock
 
jmp .update_size
 
.exit_fail:
mov ecx, pg_data.mutex
call mutex_unlock
 
add esp, 8
pop edi
pop esi
pop ebx
xor eax, eax
inc eax
ret
endp
 
 
align 4
update_mem_size:
; in: edx = slot base
; ebx = new memory size
; destroys eax,ecx,edx
 
mov [APPDATA.mem_size+edx], ebx
605,16 → 603,20
;
; retval
; eax= phisical page address
 
align 4
get_pg_addr:
sub eax, OS_BASE
cmp eax, 0x400000
jb @f
shr eax, 12
mov eax, [page_tabs+(eax+(OS_BASE shr 12))*4]
@@:
and eax, 0xFFFFF000
ret
 
 
align 4
get_pg_addr:
shr eax, 12
mov eax, [page_tabs+eax*4]
and eax, 0xFFFFF000
ret
 
 
align 4
; Now it is called from core/sys32::exc_c (see stack frame there)
proc page_fault_handler
 
1250,13 → 1252,13
mov [esp+32], eax
ret
.21:
cmp ecx, OS_BASE
jae .fail
 
cmp ebx, OS_BASE
jae .fail
 
mov edi, edx
cmp ecx, OS_BASE
jae .fail
 
cmp edx, OS_BASE
jae .fail
 
mov edi, edx
stdcall load_PE, ecx
mov esi, eax
test eax, eax
/kernel/branches/net/core/peload.inc
297,12 → 297,13
free_page, 'FreePage', \ ; eax
kernel_alloc, 'KernelAlloc', \ ; stdcall
kernel_free, 'KernelFree', \ ; stdcall
malloc, 'Kmalloc', \
free, 'Kfree', \
map_io_mem, 'MapIoMem', \ ; stdcall
get_pg_addr, 'GetPgAddr', \ ; eax
\
mutex_init, 'MutexInit', \ ; gcc fastcall
malloc, 'Kmalloc', \
free, 'Kfree', \
map_io_mem, 'MapIoMem', \ ; stdcall
map_page, 'MapPage', \ ; stdcall
get_pg_addr, 'GetPgAddr', \ ; eax
\
mutex_init, 'MutexInit', \ ; gcc fastcall
mutex_lock, 'MutexLock', \ ; gcc fastcall
mutex_unlock, 'MutexUnlock', \ ; gcc fastcall
\
/kernel/branches/net/core/sys32.inc
428,12 → 428,23
mov [eax+8], ecx
mov [eax+12], ecx
.cont:
add eax, 16
cmp eax, hotkey_list+256*16
jb .loop
; remove hotkeys in buffer
mov eax, hotkey_buffer
.loop2:
add eax, 16
cmp eax, hotkey_list+256*16
jb .loop
; get process PID
mov eax, esi
shl eax, 5
mov eax, [eax+CURRENT_TASK+TASKDATA.pid]
; compare current lock input with process PID
cmp eax, [PID_lock_input]
jne @f
 
xor eax, eax
mov [PID_lock_input], eax
@@:
; remove hotkeys in buffer
mov eax, hotkey_buffer
.loop2:
cmp [eax], esi
jnz .cont2
and dword [eax+4], 0
680,27 → 691,25
;mov esi,process_terminated
;call sys_msg_board_str
add esp, 4
ret
restore .slot
 
iglobal
if lang eq ru
boot_sched_1 db '‘®§¤ ­¨¥ GDT TSS 㪠§ â¥«ï',0
boot_sched_2 db '‘®§¤ ­¨¥ IDT â ¡«¨æë',0
else
boot_sched_1 db 'Building gdt tss pointer',0
boot_sched_2 db 'Building IDT table',0
end if
endg
 
 
build_scheduler:
 
mov esi, boot_sched_1
call boot_log
; call build_process_gdt_tss_pointer
 
; mov esi,boot_sched_2
; call boot_log
 
ret
ret
restore .slot
 
;iglobal
;if lang eq ru
; boot_sched_1 db '‘®§¤ ­¨¥ GDT TSS 㪠§ â¥«ï',0
; boot_sched_2 db '‘®§¤ ­¨¥ IDT â ¡«¨æë',0
;else
; boot_sched_1 db 'Building gdt tss pointer',0
; boot_sched_2 db 'Building IDT table',0
;end if
;endg
 
 
;build_scheduler:
; mov esi, boot_sched_1
; call boot_log
; call build_process_gdt_tss_pointer
 
; mov esi,boot_sched_2
; call boot_log
; ret
/kernel/branches/net/core/taskman.inc
81,20 → 81,22
hdr_mem dd ? ;0x10
hdr_i_end dd ? ;0x14
endl
 
pushad
 
cmp [SCR_MODE], word 0x13
jbe @f
pushad
stdcall set_cursor, [def_cursor_clock]
mov [handle], eax
mov [redrawmouse_unconditional], 1
call __sys_draw_pointer
popad
@@:
mov [flags], edx
 
; [ebp] pointer to filename
 
pushad
 
pushad
stdcall set_cursor, [def_cursor_clock]
mov [handle], eax
mov [redrawmouse_unconditional], 1
call __sys_draw_pointer
popad
 
mov [flags], edx
 
; [ebp] pointer to filename
 
lea edi, [filename]
lea ecx, [edi+1024]
mov al, '/'
182,13 → 184,13
 
lea esi, [eax+1]
test eax, eax
jnz @F
lea esi, [filename]
@@:
mov ecx, 8; 8 chars for name
mov edi, [slot_base]
.copy_process_name_loop:
lodsb
jnz @F
lea esi, [filename]
@@:
mov ecx, 11 ; 11 chars for name! 8 - is old value!
mov edi, [slot_base]
.copy_process_name_loop:
lodsb
cmp al, '.'
jz .copy_process_name_done
test al, al
258,17 → 260,20
stdcall kernel_free, [file_base]
.err_file:
xor eax, eax
mov [application_table_status], eax
mov eax, esi
.final:
pushad
stdcall set_cursor, [handle]
mov [redrawmouse_unconditional], 1
call __sys_draw_pointer
popad
ret
endp
 
mov [application_table_status], eax
mov eax, esi
.final:
cmp [SCR_MODE], word 0x13
jbe @f
pushad
stdcall set_cursor, [handle]
mov [redrawmouse_unconditional], 1
call __sys_draw_pointer
popad
@@:
ret
endp
 
align 4
test_app_header:
virtual at eax
/kernel/branches/net/core/test_malloc.asm
47,18 → 47,18
ret
 
run_test2:
ret
 
run_test3:
; 1024000 times run random operation.
; Randomly select malloc(random size from 1 to 1023)
; or free(random of previously allocated areas)
mov edi, 0x12345678
xor esi, esi ; 0 areas allocated
mov ebx, 1024000
.loop:
imul edi, 1103515245
add edi, 12345
ret
 
run_test3:
; 1024 times run random operation.
; Randomly select malloc(random size from 1 to 1023)
; or free(random of previously allocated areas)
mov edi, 0x12345678
xor esi, esi ; 0 areas allocated
mov ebx, 1024
.loop:
imul edi, 1103515245
add edi, 12345
mov eax, edi
shr eax, 16
test ebx, 64
75,13 → 75,17
and eax, 1023
jz .loop
push ebx
push eax
; mov ecx, [saved_state_num]
; mov [saved_state+ecx*8], eax
call malloc_with_test
; mov ecx, [saved_state_num]
; mov [saved_state+ecx*8+4], eax
; inc [saved_state_num]
push eax
; mov ecx, [saved_state_num]
; mov [saved_state+ecx*8], eax
push edi
call malloc_with_test
pop ecx
cmp ecx, edi
jnz edi_destroyed
; mov ecx, [saved_state_num]
; mov [saved_state+ecx*8+4], eax
; inc [saved_state_num]
pop ecx
pop ebx
inc esi
110,13 → 114,17
mov edi, eax
mov al, [edi]
repz scasb
jnz memory_destroyed
pop eax edi
push ebx edx
call free
pop edx ebx
dec esi
pop eax ecx
jnz memory_destroyed
pop eax edi
push ebx edx
push edi
call free
pop ecx
cmp ecx, edi
jnz edi_destroyed
pop edx ebx
dec esi
pop eax ecx
push edi
lea edi, [esp+4]
@@:
147,15 → 155,21
jz generic_malloc_fail
call check_mutex
call check_range
ret
 
; Stubs for kernel procedures used by heap code
wait_mutex:
inc dword [ebx]
ret
 
kernel_alloc:
cmp dword [esp+4], bufsize
ret
 
; Stubs for kernel procedures used by heap code
mutex_init:
and dword [ecx], 0
ret
mutex_lock:
inc dword [ecx]
ret
mutex_unlock:
dec dword [ecx]
ret
 
kernel_alloc:
cmp dword [esp+4], bufsize
jnz error1
mov eax, buffer
ret 4
171,13 → 185,13
 
generic_malloc_fail:
mov eax, 2
jmp error_with_code
 
check_mutex:
cmp [mst.mutex], 0
jnz @f
ret
@@:
jmp error_with_code
 
check_mutex:
cmp dword [mst.mutex], 0
jnz @f
ret
@@:
mov eax, 3
jmp error_with_code
 
192,12 → 206,16
jmp error_with_code
 
memory_destroyed:
mov eax, 5
jmp error_with_code
 
error_with_code:
mov edx, saved_state_num
; eax = error code
mov eax, 5
jmp error_with_code
 
edi_destroyed:
mov eax, 6
jmp error_with_code
 
error_with_code:
mov edx, saved_state_num
; eax = error code
; 1 signals error in testing code (wrong bufsize)
; 2 = malloc() returned NULL
; 3 = mutex not released
205,12 → 223,13
; 5 = memory destroyed by malloc() or free()
int3 ; simplest way to report error
jmp $-1 ; just in case
 
; Include main heap code
include '../proc32.inc'
include '../const.inc'
include 'malloc.inc'
 
 
; Include main heap code
include '../proc32.inc'
include '../struct.inc'
include '../const.inc'
include 'malloc.inc'
 
i_end:
 
align 4
/kernel/branches/net/data32.inc
46,17 → 46,29
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
 
 
 
if lang eq ru
boot_fonts db '˜à¨äâë § £à㦥­ë',0
boot_memdetect db 'Š®«¨ç¥á⢮ ®¯¥à â¨¢­®© ¯ ¬ïâ¨',' ',' Œ¡',0
boot_tss db '“áâ ­®¢ª  TSSs',0
boot_cpuid db '—⥭¨¥ CPUIDs',0
boot_devices db '®¨áª ãáâனáâ¢',0
boot_timer db '“áâ ­®¢ª  â ©¬¥à ',0
boot_irqs db '¥à¥®¯à¥¤¥«¥­¨¥ IRQ',0
boot_setmouse db '“áâ ­®¢ª  ¬ëè¨',0
 
 
if lang eq ru
boot_initirq db 'ˆ­¨æ¨ «¨§ æ¨ï IRQ',0
boot_picinit db 'ˆ­¨æ¨ «¨§ æ¨ï PIC',0
boot_v86machine db 'ˆ­¨æ¨ «¨§ æ¨ï á¨á⥬ë V86 ¬ è¨­ë',0
boot_inittimer db 'ˆ­¨æ¨ «¨§ æ¨ï á¨á⥬­®£® â ©¬¥à  (IRQ0)',0
boot_initapic db '®¯ë⪠ ¨­¨æ¨ «¨§ æ¨¨ APIC',0
boot_enableirq db '‚ª«îç¨âì ¯à¥à뢠­¨ï 2, 6, 13, 14, 15',0
boot_enablint_ide db ' §à¥è¥­¨¥ ¯à¥à뢠­¨© ¢ ª®­â஫«¥à¥ IDE',0
boot_detectfloppy db '®¨áª floppy ¤¨áª®¢®¤®¢',0
boot_detecthdcd db '®¨áª ¦¥áâª¨å ¤¨áª®¢ ¨ ATAPI ¯à¨¢®¤®¢',0
boot_getcache db '®«ã祭¨¥ ¯ ¬ï⨠¤«ï ªíè ',0
boot_detectpart db '®¨áª à §¤¥«®¢ ­  ¤¨áª®¢ëå ãáâனá⢠å',0
boot_init_sys db 'ˆ­¨æ¨ «¨§ æ¨ï á¨á⥬­®£® ª â «®£  /sys',0
boot_loadlibs db '‡ £à㧪  ¡¨¡«¨®â¥ª (.obj)',0
boot_memdetect db 'Š®«¨ç¥á⢮ ®¯¥à â¨¢­®© ¯ ¬ïâ¨',' ',' Œ¡',0
boot_tss db '“áâ ­®¢ª  TSSs',0
boot_cpuid db '—⥭¨¥ CPUIDs',0
; boot_devices db '®¨áª ãáâனáâ¢',0
boot_timer db '“áâ ­®¢ª  â ©¬¥à ',0
boot_irqs db '¥à¥®¯à¥¤¥«¥­¨¥ IRQ',0
boot_setmouse db '“áâ ­®¢ª  ¬ëè¨',0
boot_windefs db '“áâ ­®¢ª  ­ áâ஥ª ®ª®­ ¯® 㬮«ç ­¨î',0
boot_bgr db '“áâ ­®¢ª  ä®­ ',0
boot_resirqports db '¥§¥à¢¨à®¢ ­¨¥ IRQ ¨ ¯®à⮢',0
66,21 → 78,36
boot_tsc db '—⥭¨¥ TSC',0
boot_cpufreq db '— áâ®â  ¯à®æ¥áá®à  ',' ',' Œƒæ',0
boot_pal_ega db '“áâ ­®¢ª  EGA/CGA 320x200 ¯ «¨âàë',0
boot_pal_vga db '“áâ ­®¢ª  VGA 640x480 ¯ «¨âàë',0
boot_failed db '‡ £à㧪  ¯¥à¢®£® ¯à¨«®¦¥­¨ï ­¥ 㤠« áì',0
boot_mtrr db '“áâ ­®¢ª  MTRR',0
if preboot_blogesc
boot_tasking db '‚ᥠ£®â®¢® ¤«ï § ¯ã᪠, ­ ¦¬¨âॠESC ¤«ï áâ àâ ',0
end if
else
boot_fonts db 'Fonts loaded',0
boot_memdetect db 'Determining amount of memory',0
boot_tss db 'Setting TSSs',0
boot_cpuid db 'Reading CPUIDs',0
boot_devices db 'Detecting devices',0
boot_setmouse db 'Setting mouse',0
boot_windefs db 'Setting window defaults',0
boot_bgr db 'Calculating background',0
boot_pal_vga db '“áâ ­®¢ª  VGA 640x480 ¯ «¨âàë',0
boot_failed db '‡ £à㧪  ¯¥à¢®£® ¯à¨«®¦¥­¨ï ­¥ 㤠« áì',0
boot_mtrr db '“áâ ­®¢ª  MTRR',0
boot_APIC_found db 'APIC ¢ª«î祭', 0
boot_APIC_nfound db 'APIC ­¥ ­ ©¤¥­', 0
if preboot_blogesc
boot_tasking db '‚ᥠ£®â®¢® ¤«ï § ¯ã᪠, ­ ¦¬¨âॠESC ¤«ï áâ àâ ',0
end if
else
boot_initirq db 'Initialize IRQ',0
boot_picinit db 'Initialize PIC',0
boot_v86machine db 'Initialize system V86 machine',0
boot_inittimer db 'Initialize system timer (IRQ0)',0
boot_initapic db 'Try to initialize APIC',0
boot_enableirq db 'Enable interrupts 2, 6, 13, 14, 15',0
boot_enablint_ide db 'Enable interrupts in IDE controller',0
boot_detectfloppy db 'Search floppy drives',0
boot_detecthdcd db 'Search hard drives and ATAPI drives',0
boot_getcache db 'Get memory for cache',0
boot_detectpart db 'Search partitions on disk devices',0
boot_init_sys db 'Initialize system directory /sys',0
boot_loadlibs db 'Loading librares (.obj)',0
boot_memdetect db 'Determining amount of memory',0
boot_tss db 'Setting TSSs',0
boot_cpuid db 'Reading CPUIDs',0
; boot_devices db 'Detecting devices',0
boot_setmouse db 'Setting mouse',0
boot_windefs db 'Setting window defaults',0
boot_bgr db 'Calculating background',0
boot_resirqports db 'Reserving IRQs & ports',0
boot_setostask db 'Setting OS task',0
boot_allirqs db 'Unmasking IRQs',0
87,36 → 114,33
boot_tsc db 'Reading TSC',0
boot_cpufreq db 'CPU frequency is ',' ',' MHz',0
boot_pal_ega db 'Setting EGA/CGA 320x200 palette',0
boot_pal_vga db 'Setting VGA 640x480 palette',0
boot_failed db 'Failed to start first app',0
boot_mtrr db 'Setting MTRR',0
if preboot_blogesc
boot_tasking db 'All set - press ESC to start',0
end if
end if
boot_pal_vga db 'Setting VGA 640x480 palette',0
boot_failed db 'Failed to start first app',0
boot_mtrr db 'Setting MTRR',0
boot_APIC_found db 'APIC enabled', 0
boot_APIC_nfound db 'APIC not found', 0
if preboot_blogesc
boot_tasking db 'All set - press ESC to start',0
end if
end if
 
;new_process_loading db 'K : New Process - loading',13,10,0
;new_process_running db 'K : New Process - done',13,10,0
start_not_enough_memory db 'K : New Process - not enough memory',13,10,0
 
boot_APIC_found db 'APIC enabled', 0
boot_APIC_nfound db 'APIC not found', 0
 
;new_process_loading db 'K : New Process - loading',13,10,0
;new_process_running db 'K : New Process - done',13,10,0
start_not_enough_memory db 'K : New Process - not enough memory',13,10,0
 
msg_unresolved db 'unresolved ',0
msg_module db 'in module ',0
msg_version db 'incompatible driver version',13,10,0
msg_www db 'please visit www.kolibrios.org',13,10,0
msg_CR db 13,10,0
aHDA db 'INTEL_HDA',0
 
intel_str db "GenuineIntel",0
AMD_str db "AuthenticAMD",0
 
;szSound db 'SOUND',0
;szInfinity db 'INFINITY',0
szHwMouse db 'ATI2D',0
szPS2MDriver db 'PS2MOUSE',0
;szCOM_MDriver db 'COM_MOUSE',0
msg_version db 'incompatible driver version',13,10,0
msg_www db 'please visit www.kolibrios.org',13,10,0
msg_CR db 13,10,0
 
intel_str db "GenuineIntel",0
AMD_str db "AuthenticAMD",0
 
szHwMouse db 'ATI2D',0
szPS2MDriver db 'PS2MOUSE',0
;szCOM_MDriver db 'COM_MOUSE',0
szUSB db 'USB',0
szAtiHW db '/rd/1/drivers/ati2d.drv',0
 
132,15 → 156,12
if lang eq ru
ud_user_message db 'Žè¨¡ª : ­¥¯®¤¤¥à¦¨¢ ¥¬ ï ¨­áâàãªæ¨ï ¯à®æ¥áá®à ',0
else
ud_user_message db 'Error: unsupported processor instruction',0
end if
 
char db '/sys/FONTS/CHAR.MT',0
char2 db '/sys/FONTS/CHAR2.MT',0
 
bootpath db '/KOLIBRI '
bootpath2 db 0
vmode db '/sys/drivers/VMODE.MDR',0
ud_user_message db 'Error: unsupported processor instruction',0
end if
 
bootpath db '/KOLIBRI '
bootpath2 db 0
vmode db '/sys/drivers/VMODE.MDR',0
;vrr_m db 'VRR_M',0
kernel_file db 'KERNEL MNT'
 
/kernel/branches/net/detect/sear_par.inc
130,12 → 130,16
end_search_partitions_bd:
pop ecx
inc [hdpos]
loop start_search_partitions_bd
jmp end_search_partitions
 
partition_data_transfer:
mov edi, [transfer_adress]
mov esi, PARTITION_START ;start of file_system_data
loop start_search_partitions_bd
jmp end_search_partitions
 
problem_partition db 0 ; used for partitions search
 
include '../fs/part_set.inc'
 
partition_data_transfer:
mov edi, [transfer_adress]
mov esi, PARTITION_START ;start of file_system_data
mov ecx, (file_system_data_size+3)/4
rep movsd
ret
/kernel/branches/net/fs/ext2.inc
9,54 → 9,42
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision: 2381 $
 
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
 
;type inode
EXT2_S_IFREG = 0x8000
EXT2_S_IFDIR = 0x4000
;user inode right's
EXT2_S_IRUSR = 0x0100
EXT2_S_IWUSR = 0x0080
EXT2_S_IXUSR = 0x0040
;group inode right's
EXT2_S_IRGRP = 0x0020
EXT2_S_IWGRP = 0x0010
EXT2_S_IXGRP = 0x0008
;other inode right's
EXT2_S_IROTH = 0x0004
EXT2_S_IWOTH = 0x0002
EXT2_S_IXOTH = 0x0001
EXT2_777_MODE = EXT2_S_IROTH or EXT2_S_IWOTH or EXT2_S_IXOTH or \
EXT2_S_IRGRP or EXT2_S_IWGRP or EXT2_S_IXGRP or \
EXT2_S_IRUSR or EXT2_S_IWUSR or EXT2_S_IXUSR
 
EXT2_FT_REG_FILE = 1 ;это файл, запись в родительском каталоге
EXT2_FT_DIR = 2 ;это папка
 
FS_FT_HIDDEN = 2
FS_FT_DIR = 0x10 ;это папка
FS_FT_ASCII = 0 ;имя в ascii
FS_FT_UNICODE = 1 ;имя в unicode
 
EXT2_FEATURE_INCOMPAT_FILETYPE = 0x0002
 
uglobal
EXT2_files_in_folder dd ? ;всего файлов в папке
EXT2_read_in_folder dd ? ;сколько файлов "считали"
EXT2_end_block dd ? ;конец очередного блока папки
EXT2_counter_blocks dd ?
EXT2_filename rb 256
EXT2_parent_name rb 256
EXT2_name_len dd ?
endg
 
struct EXT2_INODE_STRUC
 
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
 
;флаги, указываемый в inode файла
EXT2_S_IFREG = 0x8000
EXT2_S_IFDIR = 0x4000
EXT2_S_IFMT = 0xF000 ;маска для типа файла
 
;флаги, указываемые в linked list родительской папки
EXT2_FT_REG_FILE = 1 ;это файл, запись в родительском каталоге
EXT2_FT_DIR = 2 ;это папка
 
;флаги используемые KolibriOS
FS_FT_HIDDEN = 2
FS_FT_DIR = 0x10 ;это папка
FS_FT_ASCII = 0 ;имя в ascii
FS_FT_UNICODE = 1 ;имя в unicode
 
EXT2_FEATURE_INCOMPAT_FILETYPE = 0x0002 ;тип файла должен указываться в директории
EXT4_FEATURE_INCOMPAT_EXTENTS = 0x0040 ;экстенты
EXT4_FEATURE_INCOMPAT_FLEX_BG = 0x0200 ;гибкие группы блоков
;реализованные ext[234] features
EXT4_FEATURE_INCOMPAT_SUPP = EXT2_FEATURE_INCOMPAT_FILETYPE \
or EXT4_FEATURE_INCOMPAT_EXTENTS \
or EXT4_FEATURE_INCOMPAT_FLEX_BG
 
 
;флаги, указываемые для inode в i_flags
EXT2_EXTENTS_FL = 0x00080000
 
struct EXT2_INODE_STRUC
i_mode dw ?
i_uid dw ?
i_size dd ?
83,18 → 71,20
name_len db ?
file_type db ?
name db ? ; 0..255
ends
 
struct EXT2_BLOCK_GROUP_DESC
block_bitmap dd ?
inode_bitmap dd ?
inode_table dd ?
free_blocks_count dw ?
free_inodes_count dw ?
used_dirs_count dw ?
ends
 
struct EXT2_SB_STRUC
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
129,42 → 119,80
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
dw ? ;+206 alignment
journal_uuid rb 16 ;+208
journal_inum dd ? ;+224
journal_dev dd ? ;+228
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
ends
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 ;заголовок блока экстентов/индексов
eh_magic dw ? ;в текущей реализации ext4 должно быть 0xF30A
eh_entries dw ? ;количество экстентов/индексов в блоке
eh_max dw ? ;max количество (используется при записи)
eh_depth dw ? ;глубина дерева (0, если это блок экстентов)
eh_generation dd ? ;???
ends
 
struct EXT4_EXTENT ;экстент
ee_block dd ? ;номер ext4 блока
ee_len dw ? ;длина экстента
ee_start_hi dw ? ;старшие 16 бит 48-битного адреса (пока не используются в KOS)
ee_start_lo dd ? ;младшие 32 бита 48-битного адреса
ends
 
struct EXT4_EXTENT_IDX ;индес - указатель на блок с экстентами/индексами
ei_block dd ? ;номер ext4 блока
ei_leaf_lo dd ? ;младшие 32 бит 48-битного адреса
ei_leaf_hi dw ? ;старшие 16 бит 48-битного адреса (пока не используются в KOS)
ei_unused dw ? ;зарезервировано
ends
 
ext2_test_superblock:
cmp [fs_type], 0x83
jne .no
 
ext2_test_superblock:
cmp [fs_type], 0x83
jne .no
 
mov eax, [PARTITION_START]
add eax, 2 ;superblock start at 1024b
call hd_read
 
cmp dword [ebx+24], 3 ;s_block_size 0,1,2,3
ja .no
cmp word [ebx+56], 0xEF53 ;s_magic
jne .no
cmp word [ebx+58], 1 ;s_state (EXT_VALID_FS=1)
jne .no
mov eax, [ebx+96]
test eax, EXT2_FEATURE_INCOMPAT_FILETYPE
jz .no
test eax, not EXT2_FEATURE_INCOMPAT_FILETYPE
jnz .no
 
; OK, this is correct EXT2 superblock
add eax, 2 ;superblock start at 1024b
call hd_read
 
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
jnz .no
 
; OK, this is correct EXT2 superblock
clc
ret
.no:
189,13 → 217,13
dec eax
xor edx, edx
div [ebx + EXT2_SB_STRUC.blocks_per_group]
inc eax
mov [ext2_data.groups_count], eax
 
mov ecx, [ebx+24]
inc ecx
mov [ext2_data.log_block_size], ecx ; 1, 2, 3, 4 equ 1kb, 2kb, 4kb, 8kb
 
inc eax
mov [ext2_data.groups_count], eax
 
mov ecx, [ebx + EXT2_SB_STRUC.log_block_size]
inc ecx
mov [ext2_data.log_block_size], ecx ; 1, 2, 3, 4 equ 1kb, 2kb, 4kb, 8kb
 
mov eax, 1
shl eax, cl
mov [ext2_data.count_block_in_block], eax
215,19 → 243,17
 
call kernel_alloc
mov [ext2_data.ext2_save_block], eax ; and for temp block
call kernel_alloc
mov [ext2_data.ext2_temp_block], eax ; and for get_inode proc
 
movzx ebp, word [ebx+88]
mov ecx, [ebx+32]
mov edx, [ebx+40]
 
mov [ext2_data.inode_size], ebp
mov [ext2_data.blocks_per_group], ecx
mov [ext2_data.inodes_per_group], edx
 
push ebp ebp ebp ;3 kernel_alloc
call kernel_alloc
call kernel_alloc
mov [ext2_data.ext2_temp_block], eax ; and for get_inode proc
 
movzx ebp, word [ebx + EXT2_SB_STRUC.inode_size]
mov ecx, [ebx + EXT2_SB_STRUC.blocks_per_group]
 
mov [ext2_data.inode_size], ebp
mov [ext2_data.blocks_per_group], ecx
 
push ebp ebp ebp ;3 kernel_alloc
call kernel_alloc
mov [ext2_data.ext2_save_inode], eax
call kernel_alloc
mov [ext2_data.ext2_temp_inode], eax
238,129 → 264,243
mov eax, EXT2_ROOT_INO
call ext2_get_inode ; read root inode
 
jmp return_from_part_set
 
;==================================================================
;in: eax = i_block
; ebx = pointer to return memory
ext2_get_block:
push eax ebx ecx
mov ecx, [ext2_data.log_block_size]
shl eax, cl
add eax, [PARTITION_START]
mov ecx, [ext2_data.count_block_in_block]
@@:
call hd_read
inc eax
add ebx, 512
loop @B
pop ecx ebx eax
ret
;===================================================================
; in: ecx = номер блока в inode (0..)
; ebp = адрес inode
; out: ecx = адрес очередного блока
ext2_get_inode_block:
cmp ecx, 12 ; 0..11 - direct block address
jb .get_direct_block
 
sub ecx, 12
cmp ecx, [ext2_data.count_pointer_in_block] ; 12.. - indirect block
jb .get_indirect_block
 
sub ecx, [ext2_data.count_pointer_in_block]
jmp return_from_part_set
 
;==================================================================
;read ext2 block form FS to memory
;in: eax = i_block (address of block in ext2 terms)
; ebx = pointer to return memory
;out: eax - error code (0 = no_error)
ext2_get_block:
push ebx ecx
mov ecx, [ext2_data.log_block_size]
shl eax, cl
add eax, [PARTITION_START]
mov ecx, [ext2_data.count_block_in_block]
@@:
call hd_read
cmp [hd_error], 0
jnz .fail
inc eax
add ebx, 512
loop @B
xor eax, eax
@@:
pop ecx ebx
ret
.fail:
mov eax, ERROR_DEVICE
jmp @B
 
;===================================================================
;получает номер блока из extent inode
;in: ecx = номер блока по порядку
; ebp = адрес extent header`а
;out: ecx - адрес очередного блока в случае успеха
; eax - номер ошибки (если равно 0, то ошибки нет)
ext4_block_recursive_search:
cmp word [ebp + EXT4_EXTENT_HEADER.eh_magic], 0xF30A ;EXT4_EXT_MAGIC
jne .fail
movzx ebx, [ebp + EXT4_EXTENT_HEADER.eh_entries]
add ebp, sizeof.EXT4_EXTENT_HEADER
cmp word [ebp - 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, [ebp + EXT4_EXTENT_IDX.ei_block]
jb .fail
cmp ecx, [ebp + sizeof.EXT4_EXTENT_IDX + EXT4_EXTENT_IDX.ei_block] ;блок слeдующего индекса
jb .end_search_index ;следующий дальше - значит текущий, то что нам нужен
add ebp, sizeof.EXT4_EXTENT_IDX
dec ebx
jmp @B
.end_search_index:
;ebp указывает на нужный extent_idx, считываем следующий блок
mov ebx, [ext2_data.ext2_temp_block]
mov eax, [ebp + EXT4_EXTENT_IDX.ei_leaf_lo]
call ext2_get_block
test eax, eax
jnz .fail
mov ebp, ebx
jmp ext4_block_recursive_search ;рекурсивно прыгаем в начало
.leaf_block: ;листовой блок ebp - ext4_extent
;цикл по экстентам
@@:
test ebx, ebx
jz .fail ;ни один узел не подошел - ошибка
 
mov edx, [ebp + EXT4_EXTENT.ee_block]
cmp ecx, edx
jb .fail ;если меньше, значит он был в предыдущих блоках -> ошибка
 
movzx edi, [ebp + EXT4_EXTENT.ee_len]
add edx, edi
cmp ecx, edx
jb .end_search_extent ;нашли нужный блок
add ebp, sizeof.EXT4_EXTENT
dec ebx
jmp @B
.end_search_extent:
mov edx, [ebp + EXT4_EXTENT.ee_start_lo]
sub ecx, [ebp + EXT4_EXTENT.ee_block] ;разница в ext4 блоках
add ecx, edx
xor eax, eax
ret
 
.fail:
mov eax, ERROR_FS_FAIL
ret
 
;===================================================================
;получает адрес ext2 блока из inode с определнным номером
;in: ecx = номер блока в inode (0..)
; ebp = адрес inode
;out: ecx = адрес очередного блока
; eax - error code
ext2_get_inode_block:
test [ebp + EXT2_INODE_STRUC.i_flags], EXT2_EXTENTS_FL
jz @F
 
pushad
add ebp, EXT2_INODE_STRUC.i_block ;ebp - 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, [ext2_data.count_pointer_in_block] ; 12.. - indirect blocks
jb .get_indirect_block
 
sub ecx, [ext2_data.count_pointer_in_block]
cmp ecx, [ext2_data.count_pointer_in_block_square]
jb .get_double_indirect_block
 
sub ecx, [ext2_data.count_pointer_in_block_square]
;.get_triple_indirect_block:
push eax edx ebx
 
mov eax, [ebx + EXT2_INODE_STRUC.i_block + 14*4]
mov ebx, [ext2_data.ext2_temp_block]
call ext2_get_block
 
xor edx, edx
mov eax, ecx
jb .get_double_indirect_block
 
sub ecx, [ext2_data.count_pointer_in_block_square]
;triple indirect block
push edx ebx
 
mov eax, [ebx + EXT2_INODE_STRUC.i_block + 14*4]
mov ebx, [ext2_data.ext2_temp_block]
call ext2_get_block
test eax, eax
jnz .fail
 
xor edx, edx
mov eax, ecx
div [ext2_data.count_pointer_in_block_square]
 
;eax - номер в полученном блоке edx - номер дальше
mov eax, [ebx + eax*4]
call ext2_get_block
 
mov eax, edx
jmp @F
 
.get_double_indirect_block:
push eax edx ebx
 
mov eax, [ebp + EXT2_INODE_STRUC.i_block + 13*4]
mov ebx, [ext2_data.ext2_temp_block]
call ext2_get_block
 
mov eax, ecx
@@:
xor edx, edx
div [ext2_data.count_pointer_in_block]
 
mov eax, [ebx + eax*4]
call ext2_get_block
mov ecx, [ebx + edx*4]
 
pop ebx edx eax
ret
 
.get_indirect_block:
push eax ebx
mov eax, [ebp + EXT2_INODE_STRUC.i_block + 12*4]
mov ebx, [ext2_data.ext2_temp_block]
call ext2_get_block
 
mov ecx, [ebx + ecx*4]
pop ebx eax
ret
 
.get_direct_block:
mov ecx, dword [ebp + EXT2_INODE_STRUC.i_block + ecx*4]
ret
 
;===================================================================
;get content inode by num
;in: eax = inode_num
; ebx = address of inode content
ext2_get_inode:
 
pushad
mov edi, ebx ;сохраним адрес inode
dec eax
xor edx, edx
div [ext2_data.inodes_per_group]
 
push edx ;locale num in group
 
;eax - номер в полученном блоке edx - номер дальше
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, [ebp + EXT2_INODE_STRUC.i_block + 13*4]
mov ebx, [ext2_data.ext2_temp_block]
call ext2_get_block
test eax, eax
jnz .fail
 
mov eax, ecx
@@:
xor edx, edx
div [ext2_data.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, [ebp + EXT2_INODE_STRUC.i_block + 12*4]
mov ebx, [ext2_data.ext2_temp_block]
call ext2_get_block
test eax, eax
jz @F ;если не было ошибки
 
mov ecx, [ebx + ecx*4] ;заносим результат
@@:
pop ebx
ret
 
.get_direct_block:
mov ecx, [ebp + 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
;out: eax - error code
ext2_get_inode:
pushad
mov edi, ebx ;сохраним адрес inode
dec eax
xor edx, edx
mov ecx, [ext2_data.sb]
div [ecx + EXT2_SB_STRUC.inodes_per_group]
 
push edx ;locale num in group
 
mov edx, 32
mul edx ; address block_group in global_desc_table
 
; в eax - смещение группы с inode-ом относительно начала глобальной дескрипторной таблицы
; найдем блок в котором он находится
div [ext2_data.block_size]
add eax, [ecx + EXT2_SB_STRUC.first_data_block]
inc eax
mov ebx, [ext2_data.ext2_temp_block]
call ext2_get_block
test eax, eax
jnz .fail
 
add ebx, edx ; локальный номер в блоке
mov eax, [ebx + EXT2_BLOCK_GROUP_DESC.inode_table]; номер блока - в терминах ext2
 
mov ecx, [ext2_data.log_block_size]
shl eax, cl
add eax, [PARTITION_START] ; а старт раздела - в терминах hdd (512)
 
;eax - указывает на таблицу inode-ов на hdd
mov esi, eax ;сохраним его пока в esi
 
; в eax - смещение группы с inode-ом относительно начала глобальной дескрипторной таблицы
; найдем блок в котором он находится
 
div [ext2_data.block_size]
mov ecx, [ext2_data.sb]
add eax, [ecx + EXT2_SB_STRUC.first_data_block]
inc eax
mov ebx, [ext2_data.ext2_temp_block]
call ext2_get_block
 
add ebx, edx ; локальный номер в блоке
mov eax, [ebx+8] ; номер блока - в терминах ext2
 
mov ecx, [ext2_data.log_block_size]
shl eax, cl
add eax, [PARTITION_START] ; а старт раздела - в терминах hdd (512)
 
;eax - указывает на таблицу inode-ов на hdd
mov esi, eax ;сохраним его пока в esi
 
; прибавим локальный адрес inode-а
pop eax ; index
mov ecx, [ext2_data.inode_size]
368,81 → 508,25
mov ebp, 512
div ebp ;поделим на размер блока
 
add eax, esi ;нашли адрес блока для чтения
mov ebx, [ext2_data.ext2_temp_block]
call hd_read
 
mov esi, edx ;добавим "остаток"
add esi, ebx ;к адресу
; mov ecx, [ext2_data.inode_size]
rep movsb ;копируем inode
popad
ret
 
;----------------------------------------------------------------
; in: esi -> children
; ebx -> pointer to dir block
; out: esi -> name without parent or not_changed
; ebx -> dir_rec of inode children or trash
ext2_test_block_by_name:
push eax ecx edx edi
 
mov edx, ebx
add edx, [ext2_data.block_size] ;запомним конец блока
 
.start_rec:
cmp [ebx + EXT2_DIR_STRUC.inode], 0
jz .next_rec
 
push esi
movzx ecx, [ebx + EXT2_DIR_STRUC.name_len]
mov edi, EXT2_filename
lea esi, [ebx + EXT2_DIR_STRUC.name]
 
call utf8toansi_str
mov ecx, edi
sub ecx, EXT2_filename ;кол-во байт в получившейся строке
 
mov edi, EXT2_filename
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
@@: ;не подошло
pop esi
.next_rec:
movzx eax, [ebx + EXT2_DIR_STRUC.rec_len]
add ebx, eax ;к след. записи
cmp ebx, edx ;проверим конец ли
jb .start_rec
jmp .ret
 
.test_find:
cmp byte [esi], 0
je .find ;нашли конец
cmp byte [esi], '/'
jne @B
inc esi
.find:
pop eax ;удаляем из стека сохраненое значение
.ret:
pop edi edx ecx eax
ret
 
;----------------------------------------------------------------
;
; ext2_HdReadFolder - read disk folder
;
add eax, esi ;нашли адрес блока для чтения
mov ebx, [ext2_data.ext2_temp_block]
call hd_read
cmp [hd_error], 0
jnz .fail
 
mov esi, edx ;добавим "остаток"
add esi, ebx ;к адресу
rep movsb ;копируем inode
xor eax, eax
.fail:
mov PUSHAD_EAX, eax
popad
ret
 
;----------------------------------------------------------------
;
; ext2_HdReadFolder - read disk folder
;
; esi points to filename
; ebx pointer to structure 32-bit number = first wanted block, 0+
; & flags (bitfields)
453,130 → 537,147
; ret ebx = blocks read or 0xffffffff folder not found
; eax = 0 ok read or other = errormsg
;
;--------------------------------------------------------------
ext2_HdReadFolder:
cmp byte [esi], 0
jz .doit
 
push ecx ebx
call ext2_find_lfn
jnc .doit2
pop ebx
.not_found:
pop ecx
or ebx, -1
mov eax, ERROR_FILE_NOT_FOUND
ret
 
.doit:
mov ebp, [ext2_data.root_inode]
push ecx
jmp @F
.doit2:
pop ebx
test [ebp + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR
jz .not_found
@@:
xor eax, eax
mov edi, edx
mov ecx, 32/4
rep stosd ; fill header zero
pop edi ; edi = число блоков для чтения
push edx ebx
 
;--------------------------------------------- final step
and [EXT2_read_in_folder], 0
and [EXT2_files_in_folder], 0
 
mov eax, [ebp + EXT2_INODE_STRUC.i_blocks]
mov [EXT2_counter_blocks], eax
 
add edx, 32 ; (header pointer in stack) edx = current mem for return
xor esi, esi ; esi = номер блока по порядку
 
.new_block_folder: ;reserved label
mov ecx, esi ; получим номер блока
call ext2_get_inode_block
 
mov eax, ecx
mov ebx, [ext2_data.ext2_save_block]
call ext2_get_block ; и считываем блок с hdd
 
mov eax, ebx ; eax = current dir record
add ebx, [ext2_data.block_size]
mov [EXT2_end_block], ebx ; запомним конец очередного блока
 
pop ecx
mov ecx, [ecx] ; ecx = first wanted (flags ommited)
 
.find_wanted_start:
jecxz .find_wanted_end
.find_wanted_cycle:
cmp [eax + EXT2_DIR_STRUC.inode], 0 ; if (inode = 0) => not used
jz @F
inc [EXT2_files_in_folder]
dec ecx
@@:
movzx ebx, [eax+EXT2_DIR_STRUC.rec_len]
 
cmp ebx, 12 ; минимальная длина записи
jb .end_error
test ebx, 0x3 ; длина записи должна делиться на 4
jnz .end_error
 
add eax, ebx ; к следующей записи
cmp eax, [EXT2_end_block] ; проверяем "конец"
jb .find_wanted_start
 
push .find_wanted_start
.end_block: ;вылетили из цикла
mov ebx, [ext2_data.count_block_in_block]
sub [EXT2_counter_blocks], ebx
jbe .end_dir
 
inc esi ;получаем новый блок
push ecx
mov ecx, esi
call ext2_get_inode_block
mov eax, ecx
mov ebx, [ext2_data.ext2_save_block]
call ext2_get_block
pop ecx
mov eax, ebx
add ebx, [ext2_data.block_size]
mov [EXT2_end_block], ebx
ret ; опять в цикл
 
.wanted_end:
loop .find_wanted_cycle ; ecx = -1
 
.find_wanted_end:
mov ecx, edi
.wanted_start: ; ищем first_wanted+count
jecxz .wanted_end
cmp [eax + EXT2_DIR_STRUC.inode], 0 ; if (inode = 0) => not used
jz .empty_rec
inc [EXT2_files_in_folder]
inc [EXT2_read_in_folder]
 
mov edi, edx
push eax ecx
xor eax, eax
mov ecx, 40 / 4
rep stosd
pop ecx eax
 
push eax esi edx ;получим inode
mov eax, [eax + EXT2_DIR_STRUC.inode]
mov ebx, [ext2_data.ext2_temp_inode]
call ext2_get_inode
 
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
;--------------------------------------------------------------
ext2_HdReadFolder:
cmp byte [esi], 0
jz .root_folder
 
push ebx ecx edx
call ext2_find_lfn ;вернет в ebp адрес inode
pop edx ecx ebx
test eax, eax
jnz .error_ret
test [ebp + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR
jz .error_not_found
jmp @F
 
.root_folder:
mov ebp, [ext2_data.root_inode]
test [ebp + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR
jz .error_root
;придется копировать inode
push ecx
mov esi, ebp
mov edi, [ext2_data.ext2_save_inode]
mov ecx, [ext2_data.inode_size]
shr ecx, 2
mov ebp, edi
rep movsd
pop ecx
@@:
cmp [ebp + EXT2_INODE_STRUC.i_blocks], 0 ;папка пуста
je .error_empty_dir
push edx ;адрес результата [edi + 28]
push 0 ;конец очередного блока папки [edi + 24]
push ecx ;сколько файлов нужно прочитать [edi + 20]
push dword [ebx] ;первый "нужный" файл [edi + 16]
push dword [ebx + 4];флаги [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, [ext2_data.ext2_save_block]
call ext2_get_block ; и считываем блок с hdd
test eax, eax
jnz .error_get_block
 
mov esi, ebx ; esi = current dir record
add ebx, [ext2_data.block_size]
mov [edi + 24], ebx ; запомним конец очередного блока
 
mov ecx, [edi + 16] ; ecx = first wanted (flags ommited)
 
.find_wanted_start:
jecxz .find_wanted_end
.find_wanted_cycle:
cmp [esi + EXT2_DIR_STRUC.inode], 0 ; if (inode = 0) => not used
jz @F
inc dword [edi + 4] ; EXT2_files_in_folder
dec ecx
@@:
movzx ebx, [esi + EXT2_DIR_STRUC.rec_len]
 
cmp ebx, 12 ; минимальная длина записи
jb .error_bad_len
test ebx, 0x3 ; длина записи должна делиться на 4
jnz .error_bad_len
 
add esi, ebx ; к следующей записи
cmp esi, [edi + 24] ; сравниваем с концом блока
jb .find_wanted_start
 
push .find_wanted_start
.end_block: ;вылетели из цикла
mov ebx, [ext2_data.count_block_in_block]
sub [ebp + EXT2_INODE_STRUC.i_blocks], ebx ;вычитаем напрямую из структуры inode
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, [ext2_data.ext2_save_block]
call ext2_get_block
test eax, eax
jnz .error_get_block
 
pop ecx
mov esi, ebx
add ebx, [ext2_data.block_size]
mov [edi + 24], ebx ;запомним конец блока
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 [esi + 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 esi edi edx
mov eax, [esi + EXT2_DIR_STRUC.inode] ;получим дочерний inode
mov ebx, [ext2_data.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]
589,75 → 690,94
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
@@:
xor dword [edx], FS_FT_DIR
pop esi eax
 
or dword [edx+4], FS_FT_ASCII ; symbol type in name
 
;теперь скопируем имя, сконвертировав из UTF-8 в CP866
push eax ecx esi
movzx ecx, [eax + EXT2_DIR_STRUC.name_len]
lea edi, [edx + 40]
lea esi, [eax + EXT2_DIR_STRUC.name]
call utf8toansi_str
pop esi ecx eax
and byte [edi], 0
 
cmp byte [edx + 40], '.'
jne @F
or dword [edx], FS_FT_HIDDEN
@@:
 
add edx, 40 + 264 ; go to next record
dec ecx ; если запись пустая ecx не надо уменьшать
.empty_rec:
movzx ebx, [eax + EXT2_DIR_STRUC.rec_len]
cmp ebx, 12 ; минимальная длина записи
jb .end_error
test ebx, 0x3 ; длина записи должна делиться на 4
jnz .end_error
 
add eax, ebx
cmp eax, [EXT2_end_block]
jb .wanted_start
 
push .wanted_start ; дошли до конца очередного блока
jmp .end_block
 
.end_dir:
pop eax ; мусор (адрес возврата в цикл)
.end_error:
pop edx
mov ebx, [EXT2_read_in_folder]
mov ecx, [EXT2_files_in_folder]
mov dword [edx], 1 ;version
xor eax, eax
mov [edx+4], ebx
mov [edx+8], ecx
lea edi, [edx + 12]
mov ecx, 20 / 4
rep stosd
ret
;====================== end ext2_HdReadFolder
utf8toansi_str:
; convert UTF-8 string to ASCII-string (codepage 866)
; in: ecx=length source, esi->source, edi->buffer
; destroys: eax,esi,edi
jecxz .ret
.start:
lodsw
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 ;edi и esi уже сохранены в стеке
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 ecx edi esi
 
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 ebx, [esi + EXT2_DIR_STRUC.rec_len]
cmp ebx, 12 ; минимальная длина записи
jb .error_bad_len
test ebx, 0x3 ; длина записи должна делиться на 4
jnz .error_bad_len
 
add esi, ebx
cmp esi, [edi + 24] ;дошли ли до конца блока?
jb .wanted_start
 
push .wanted_start ; дошли
jmp .end_block
 
.end_dir: ;конец папки, когда еще не дошли до нужного файла
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 ;зарезервировано: нули в текущей реализации
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
ret
.error_empty_dir: ;inode папки без блоков
.error_root: ;root - не папка
mov eax, ERROR_FS_FAIL
jmp .error_ret
 
.error_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
 
709,93 → 829,111
; may be ebx=0 - start from first byte
; ecx number of bytes to read, 0+
; edx mem location to return data
;
; ret ebx = bytes read or 0xffffffff file not found
; eax = 0 ok read or other = errormsg
;
;--------------------------------------------------------------
ext2_HdRead:
cmp byte [esi], 0
;
; ret ebx = bytes read or 0xffffffff file not found
; eax = 0 ok read or other = errormsg
 
;--------------------------------------------------------------
ext2_HdRead:
cmp byte [esi], 0
jnz @F
 
.this_is_nofile:
or ebx, -1
mov eax, ERROR_ACCESS_DENIED
ret
ret
 
@@:
push ecx ebx edx
call ext2_find_lfn
pop edx ebx ecx
test eax, eax
jz @F
 
or ebx, -1
mov eax, ERROR_FILE_NOT_FOUND
ret
 
@@:
mov ax, [ebp + EXT2_INODE_STRUC.i_mode]
and ax, EXT2_S_IFMT ;оставляем только тип inode в ax
cmp ax, EXT2_S_IFREG
jne .this_is_nofile
 
mov edi, edx ; edi = pointer to return mem
 
test ebx, ebx
jz @F
mov esi, ebx ; esi = pointer to first_wanted
mov ebx, [esi+4]
mov eax, [esi] ; ebx : eax - стартовый номер байта
 
;///// сравним хватит ли нам файла или нет
cmp [ebp + EXT2_INODE_STRUC.i_dir_acl], ebx
ja .size_great
jb .size_less
 
@@:
push ecx ebx
call ext2_find_lfn
pop ebx ecx
jnc .doit
;.not_found:
or ebx, -1
mov eax, ERROR_FILE_NOT_FOUND
ret
 
.doit:
test [ebp + EXT2_INODE_STRUC.i_mode], EXT2_S_IFREG
jz .this_is_nofile
 
;-----------------------------------------------------------------------------final step
mov edi, edx ; edi = pointer to return mem
mov esi, ebx ; esi = pointer to first_wanted
 
;///// сравним хватит ли нам файла или нет
mov ebx, [esi+4]
mov eax, [esi] ; ebx : eax - стартовый номер байта
 
cmp [ebp + EXT2_INODE_STRUC.i_dir_acl], ebx
ja .size_great
jb .size_less
 
cmp [ebp + EXT2_INODE_STRUC.i_size], eax
ja .size_great
 
.size_less:
xor ebx, ebx
mov eax, ERROR_END_OF_FILE
ret
.size_great:
add eax, ecx ;add to first_wanted кол-во байт для чтения
adc ebx, 0
xor ebx, ebx
mov eax, ERROR_END_OF_FILE
ret
@@:
xor ebx, ebx
xor eax, eax
.size_great:
add eax, ecx ;add to first_wanted кол-во байт для чтения
adc ebx, 0
 
cmp [ebp + EXT2_INODE_STRUC.i_dir_acl], ebx
ja .size_great_great
jb .size_great_less
cmp [ebp + EXT2_INODE_STRUC.i_size], eax
jae .size_great_great ; а если равно, то не важно куда
 
.size_great_less:
or [EXT2_files_in_folder], 1 ;читаем по границе размера
mov ecx, [ebp + EXT2_INODE_STRUC.i_size]
sub ecx, [esi] ;(размер - старт)
jmp @F
 
.size_great_great:
and [EXT2_files_in_folder], 0 ;читаем столько сколько запросили
 
@@:
push ecx ;save for return
test esi, esi
jz .zero_start
 
;пока делаем п..ц криво =)
mov edx, [esi+4]
mov eax, [esi]
div [ext2_data.block_size]
 
mov [EXT2_counter_blocks], eax ;номер блока запоминаем
 
push ecx
mov ecx, eax
call ext2_get_inode_block
mov ebx, [ext2_data.ext2_save_block]
mov eax, ecx
call ext2_get_block
pop ecx
add ebx, edx
 
ja .size_great_great
jb .size_great_less
cmp [ebp + EXT2_INODE_STRUC.i_size], eax
jae .size_great_great
 
.size_great_less:
push 1
; or [EXT2_files_in_folder], 1 ;читаем по границе размера
mov ecx, [ebp + EXT2_INODE_STRUC.i_size]
sub ecx, [esi] ;(размер - старт) = сколько читать
jmp @F
 
.size_great_great:
push 0
; and [EXT2_files_in_folder], 0 ;читаем столько сколько запросили
 
@@:
;здесь мы точно знаем сколько байт читать - ecx
;edi - return memory
;esi -> first wanted
 
push ecx ;количество считанных байт
test esi, esi
jz .zero_start
 
;получим кусок из первого блока
mov edx, [esi+4]
mov eax, [esi]
div [ext2_data.block_size]
 
push eax ;номер блока запоминаем
push ecx
mov ecx, eax
call ext2_get_inode_block
test eax, eax
jnz .error_at_first_block
mov ebx, [ext2_data.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, [ext2_data.block_size] ;block_size - стартовый байт = сколько байт 1-го блока
cmp ecx, edx
804,143 → 942,255
mov eax, ecx
sub eax, edx
mov ecx, edx
 
mov esi, ebx
rep movsb ;кусок 1-го блока
jmp @F
 
.zero_start:
mov eax, ecx
;теперь в eax кол-во оставшихся байт для чтения
@@:
mov ebx, edi ;чтение блока прям в ->ebx
xor edx, edx
div [ext2_data.block_size] ;кол-во байт в последнем блоке (остаток) в edx
mov edi, eax ;кол-во целых блоков в edi
@@:
test edi, edi
jz .finish_block
inc [EXT2_counter_blocks]
mov ecx, [EXT2_counter_blocks]
call ext2_get_inode_block
 
mov eax, ecx ;а ebx уже забит нужным значением
call ext2_get_block
add ebx, [ext2_data.block_size]
 
dec edi
 
mov esi, ebx
rep movsb ;кусок 1-го блока
jmp .calc_blocks_count
 
.zero_start:
mov eax, ecx
push 0 ;счетчик блоков
;теперь в eax кол-во оставшихся байт для чтения
.calc_blocks_count:
mov ebx, edi ;чтение блока прям в ->ebx
xor edx, edx
div [ext2_data.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, [ext2_data.block_size]
 
dec edi
jmp @B
 
.finish_block: ;в edx - кол-во байт в последнем блоке
test edx, edx
jz .end_read
 
mov ecx, [EXT2_counter_blocks]
inc ecx
call ext2_get_inode_block
 
mov edi, ebx
mov eax, ecx
mov ebx, [ext2_data.ext2_save_block]
call ext2_get_block
 
mov ecx, edx
 
.only_one_block:
mov esi, ebx
rep movsb ;кусок last блока
.end_read:
pop ebx
cmp [EXT2_files_in_folder], 0
jz @F
 
mov eax, ERROR_END_OF_FILE
test edx, edx
jz .end_read
 
pop ecx ;счетчик блоков -> ecx
inc ecx
call ext2_get_inode_block
test eax, eax
jz .error_at_finish_block
 
mov edi, ebx
mov eax, ecx
mov ebx, [ext2_data.ext2_save_block]
call ext2_get_block
test eax, eax
jnz .error_at_finish_block
 
mov ecx, edx
mov esi, ebx
rep movsb ;кусок last блока
.end_read:
pop ebx
pop eax
test eax, eax
jz @F
 
mov eax, ERROR_END_OF_FILE
ret
@@:
xor eax, eax
ret
;========================
;in : esi -> name not save: eax ebx ecx
;out: ebp -> inode cf=0
; ebp -> trash cf=1
ext2_find_lfn:
mov ebp, [ext2_data.root_inode]
.next_folder:
or [EXT2_counter_blocks], -1 ;счетчик блоков папки cur block of inode
mov eax, [ebp + EXT2_INODE_STRUC.i_blocks] ;убывающий счетчик блоков
add eax, [ext2_data.count_block_in_block]
mov [EXT2_end_block], eax
.next_block_folder:
mov eax, [ext2_data.count_block_in_block]
sub [EXT2_end_block], eax
jz .not_found
inc [EXT2_counter_blocks]
mov ecx, [EXT2_counter_blocks]
call ext2_get_inode_block
 
mov eax, ecx
mov ebx, [ext2_data.ext2_save_block] ;ebx = cur dir record
call ext2_get_block
 
mov eax, esi
call ext2_test_block_by_name
cmp eax, esi ;нашли имя?
jz .next_block_folder
 
cmp byte [esi], 0
jz .get_inode_ret
 
cmp [ebx + EXT2_DIR_STRUC.file_type], EXT2_FT_DIR
jne .not_found ;нашли, но это не папка
mov eax, [ebx + EXT2_DIR_STRUC.inode]
mov ebx, [ext2_data.ext2_save_inode] ;все же папка.
call ext2_get_inode
mov ebp, ebx
jmp .next_folder
 
.not_found:
stc
ret
.get_inode_ret:
mov [EXT2_end_block], ebx ; сохраняем указатеть на dir_rec
mov eax, [ebx + EXT2_DIR_STRUC.inode]
mov ebx, [ext2_data.ext2_save_inode]
call ext2_get_inode
mov ebp, ebx
clc
ret
 
 
;========================
 
ext2_HdGetFileInfo:
cmp byte [esi], 0
jz .doit
 
call ext2_find_lfn
jnc .doit2
;.not_found:
mov eax, ERROR_FILE_NOT_FOUND
ret
 
.doit:
mov ebp, [ext2_data.root_inode]
mov ebx, .doit ;неважно что лишь бы этому адресу не '.'
jmp @F
.doit2:
mov ebx, [EXT2_end_block]
add ebx, EXT2_DIR_STRUC.name
@@:
xor eax, eax
mov edi, edx
mov ecx, 40/4
rep stosd ; fill zero
 
cmp byte [ebx], '.'
jnz @F
or dword [edx], FS_FT_HIDDEN
@@:
 
@@:
xor eax, eax
ret
.only_one_block:
mov esi, ebx
rep movsb ;кусок last блока
pop eax
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
ret
 
;----------------------------------------------------------------
; in: esi = file path
; ebx = pointer to dir block
; 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, [ext2_data.block_size] ;запомним конец блока
 
.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 ;кол-во байт в получившейся строке
 
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
@@: ;не подошло
pop esi
.next_rec:
movzx eax, [ebx + EXT2_DIR_STRUC.rec_len]
add ebx, eax ;к след. записи
cmp ebx, edx ;проверим конец ли
jb .start_rec
add esp, 256
ret
 
.test_find:
cmp byte [esi], 0
je .ret ;нашли конец
cmp byte [esi], '/'
jne @B
inc esi
.ret:
add esp, 256 + 4
ret
 
;========================
;Ищет inode по строке пути
;in: esi = name
;out: eax - error code
; ebp = inode
; dl - первый байт из имени файла/папки
ext2_find_lfn:
mov ebp, [ext2_data.root_inode]
cmp [ebp + EXT2_INODE_STRUC.i_blocks], 0
je .error_empty_root
.next_path_part:
push [ebp + EXT2_INODE_STRUC.i_blocks]
xor ecx, ecx
.folder_block_cycle:
call ext2_get_inode_block
test eax, eax
jnz .error_get_inode_block
mov eax, ecx
mov ebx, [ext2_data.ext2_save_block] ;ebx = cur dir record
call ext2_get_block
test eax, eax
jnz .error_get_block
push esi
call ext2_test_block_by_name
pop edi
 
cmp edi, esi ;нашли имя?
je .next_folder_block ;не нашли -> к след. блоку
cmp byte [esi], 0 ;дошли до "конца" пути -> возваращаемся
jz .get_inode_ret
 
cmp [ebx + EXT2_DIR_STRUC.file_type], EXT2_FT_DIR ;нашли, но это не папка
jne .not_found
 
mov eax, [ebx + EXT2_DIR_STRUC.inode]
mov ebx, [ext2_data.ext2_save_inode] ;все же папка.
call ext2_get_inode
test eax, eax
jnz .error_get_inode
pop ecx ;в стеке лежит кол-во блоков
mov ebp, ebx
jmp .next_path_part
.next_folder_block:
;к следующему блоку в текущей папке
pop eax ;счетчик блоков
sub eax, [ext2_data.count_block_in_block]
jle .not_found
inc ecx
jmp .folder_block_cycle
 
.not_found:
pop ebx
mov eax, ERROR_FILE_NOT_FOUND
ret
 
.get_inode_ret:
pop ecx ;в стеке лежит кол-во блоков
mov dl, [ebx + EXT2_DIR_STRUC.name] ;в dl - первый символ ()
mov eax, [ebx + EXT2_DIR_STRUC.inode]
mov ebx, [ext2_data.ext2_save_inode]
call ext2_get_inode
mov ebp, ebx
xor eax, eax
ret
 
.error_get_inode_block:
.error_get_block:
.error_get_inode:
pop ebx
.error_empty_root:
mov eax, ERROR_FS_FAIL
ret
 
;----------------------------------------------------------------
;ext2_HdGetFileInfo - read file info from block device
;
;in: esi points to filename
; edx mem location to return data
;--------------------------------------------------------------
ext2_HdGetFileInfo:
xchg bx, bx
cmp byte [esi], 0
jz .is_root
 
push edx
call ext2_find_lfn
mov ebx, edx
pop edx
test eax, eax
jz @F
ret
 
.is_root:
xor ebx, ebx ;root не может быть скрытым
mov ebp, [ext2_data.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 [ebp + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR
jnz @F
mov eax, [ebp + EXT2_INODE_STRUC.i_size] ;low size
949,27 → 1199,27
mov dword [edx+36], ebx
xor dword [edx], FS_FT_DIR
@@:
xor dword [edx], FS_FT_DIR
 
lea edi, [edx + 8]
mov eax, [ebx + EXT2_INODE_STRUC.i_ctime]
xor edx, edx
add eax, 3054539008
adc edx, 2
xor dword [edx], FS_FT_DIR
 
lea edi, [edx + 8]
mov eax, [ebp + EXT2_INODE_STRUC.i_ctime]
xor edx, edx
add eax, 3054539008
adc edx, 2
call ntfs_datetime_to_bdfe.sec
 
mov eax, [ebp + EXT2_INODE_STRUC.i_atime]
xor edx, edx
add eax, 3054539008
adc edx, 2
call ntfs_datetime_to_bdfe.sec
 
mov eax, [ebp + EXT2_INODE_STRUC.i_mtime]
xor edx, edx
add eax, 3054539008
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
 
xor eax, eax
ret
 
979,340 → 1229,6
ext2_HdSetFileInfo:
ext2_HdDelete:
ext2_HdCreateFolder:
xor ebx, ebx
mov eax, ERROR_UNSUPPORTED_FS
ret
;----------------------------------------------------------------
;
; ext2_HdCreateFolder - create new folder
;
; esi points to filename
;
; ret eax = 0 ok read or other = errormsg
;
;--------------------------------------------------------------
cmp byte [esi], 0
jz .not_found
cmp byte [esi], '/'
jz .not_found
 
mov ebx, esi ; save source pointer
xor edi, edi ; slah pointer
@@:
lodsb
cmp al, 0
jz .zero
cmp al, '/'
jz .slash
jmp @B
 
.slash:
lodsb
cmp al, 0
jz .zero ; уберем слеш из имени
cmp al, '/'
jz .not_found
mov edi, esi ; edi -> next symbol after '/'
dec edi
jmp @B
 
.zero:
dec esi
test edi, edi
jz .doit
 
;слеш был
mov eax, esi
sub eax, edi
mov [EXT2_name_len], eax
 
mov ecx, edi
sub ecx, ebx
dec ecx ;выкинули '/' из имени ролителя
mov esi, ebx
mov edi, EXT2_parent_name
rep movsb
; esi - pointer to last slash
 
mov edx, esi
mov esi, EXT2_parent_name
call ext2_find_lfn
jnc .doit2
.not_found:
or ebx, -1
mov eax, ERROR_FILE_NOT_FOUND
ret
 
.doit:
mov ebp, [ext2_data.root_inode]
mov edx, ebx ; имя создаваемой папки
sub esi, ebx
mov [EXT2_name_len], esi
.doit2:
;ebp -> parent_inode ebx->name_new_folder [EXT2_name_len]=length of name
; стратегия выбора группы для нового inode: (так делает линукс)
; 1) Ищем группу в которой меньше всего папок и в есть свободное место
; 2) Если такая группа не нашлась, то берем группу в которой больше свободного места
 
 
 
 
call ext2_balloc
jmp ext2_HdDelete
 
push ebx
push ebp
 
mov ecx, [ext2_data.sb]
cmp [ecx + EXT2_SB_STRUC.free_inodes_count], 0 ; есть ли место для inode
jz .no_space
mov eax, [ecx + EXT2_SB_STRUC.free_block_count]
sub eax, [ecx + EXT2_SB_STRUC.r_block_count]
cmp eax, 2 ; и как минимум на 2 блока
jb .no_space
 
mov ecx, [ext2_data.groups_count]
mov esi, [ext2_data.global_desc_table]
mov edi, -1 ;указатель на лучшую группу
mov edx, 0
.find_group_dir:
jecxz .end_find_group_dir
movzx eax, [esi + EXT2_BLOCK_GROUP_DESC.free_inodes_count]
cmp eax, edx
jbe @F
cmp [esi + EXT2_BLOCK_GROUP_DESC.free_blocks_count], 0
jz @F
mov edi, esi
movzx edx, [esi + EXT2_BLOCK_GROUP_DESC.free_inodes_count]
@@:
dec ecx
add esi, 32 ;размер структуры
jmp .find_group_dir
.end_find_group_dir:
cmp edx, 0
jz .no_space
 
;нашли группу, получим битовую карту inode-ов (найдем locale number)
mov eax, [edi + EXT2_BLOCK_GROUP_DESC.inode_bitmap]
mov ebx, [ext2_data.ext2_save_block]
call ext2_get_block
 
;теперь цикл по всем битам
mov esi, ebx
mov ecx, [ext2_data.inodes_per_group]
shr ecx, 5 ;делим на 32
mov ebp, ecx ; всего сохраним в ebp
or eax, -1 ; ищем первый свободный inode (!= -1)
repne scasd
jnz .test_last_dword ;нашли или нет
mov eax, [esi-4]
 
sub ebp, ecx
dec ebp
shl ebp, 5 ; глобальный номер локального номера
 
mov ecx, 32
@@:
test eax, 1
jz @F
shr eax, 1
loop @B
@@:
mov eax, 32
sub eax, ecx
 
add ebp, eax ; locale num of inode
 
mov eax, [esi-4]
;устанавливаем в eax крайний справа нулевой бит в 1
mov ecx, eax
inc ecx
or eax, ecx ; x | (x+1)
mov [esi-4], eax
mov ebx, [ext2_data.ext2_save_block]
mov eax, [edi + EXT2_BLOCK_GROUP_DESC.inode_bitmap]
call ext2_set_block
;считаем таблицу inode
sub edi, [ext2_data.global_desc_table]
shr edi, 5
 
mov eax, edi
mul [ext2_data.inodes_per_group]
add eax, ebp
inc eax ; теперь в eax (ebp) номер inode-а
mov ebp, eax
;call ext2_get_inode_address
 
mov ebx, [ext2_data.ext2_save_block]
call hd_read
add edx, ebx ; в edx адрес нужного inode
 
;забьем 0 для начала
mov edi, edx
mov ecx, [ext2_data.inode_size]
shr ecx, 2
xor eax, eax
rep stosd
 
mov edi, edx
mov eax, EXT2_S_IFDIR or EXT2_777_MODE
stosd ; i_mode
xor eax, eax
stosd ; i_uid
mov eax, [ext2_data.block_size]
stosd ; i_size
xor eax, eax
stosd ; i_atime
stosd ; i_ctime
stosd ; i_mtime
stosd ; i_dtime
stosd ; i_gid
inc eax
stosd ; i_links_count
mov eax, [ext2_data.count_block_in_block]
stosd ; i_blocks
 
 
 
 
.test_last_dword:
 
xor ebx, ebx
mov eax, ERROR_UNSUPPORTED_FS
ret
 
 
 
.no_space:
or ebx, -1
mov eax, ERROR_DISK_FULL
ret
 
;выделяет новый блок, если это можно
;иначе возвращает eax=0
ext2_balloc:
mov ecx, [ext2_data.sb]
mov eax, [ecx + EXT2_SB_STRUC.free_block_count]
sub eax, [ecx + EXT2_SB_STRUC.r_block_count]
jbe .no_space
 
mov ecx, [ext2_data.groups_count]
mov edi, [ext2_data.global_desc_table]
;mov esi, -1 ;указатель на лучшую группу
mov edx, 0
.find_group:
jecxz .end_find_group
movzx eax, [edi + EXT2_BLOCK_GROUP_DESC.free_blocks_count]
cmp eax, edx
jbe @F
mov esi, edi
mov edx, eax
@@:
dec ecx
add edi, 32 ;размер структуры
jmp .find_group
.end_find_group:
cmp edx, 0
jz .no_space
 
;нашли группу, получим битовую карту block-ов
mov eax, [esi + EXT2_BLOCK_GROUP_DESC.block_bitmap]
mov ebx, [ext2_data.ext2_save_block]
call ext2_get_block
 
;теперь цикл по всем битам
mov edi, ebx
mov ecx, [ext2_data.blocks_per_group]
shr ecx, 5 ;делим на 32
mov ebp, ecx ;всего сохраним в ebp
or eax, -1 ;ищем первый свободный inode (!= -1)
repe scasd
jz .test_last_dword ;нашли или нет
 
mov eax, [edi-4]
sub ebp, ecx
dec ebp
shl ebp, 5 ; ebp = 32*(номер div 32). Теперь найдем (номер mod 32)
 
mov ecx, 32
@@:
test eax, 1
jz @F
shr eax, 1
loop @B
@@:
mov eax, 32
sub eax, ecx
 
add ebp, eax ; ebp = номер блока в группе
 
mov eax, [edi-4]
mov ecx, eax
inc ecx
or eax, ecx ; x | (x+1) - устанавливает в 1 крайний справа нулевой бит (block used)
mov [edi-4], eax
 
mov ebx, [ext2_data.ext2_save_block]
mov eax, [esi + EXT2_BLOCK_GROUP_DESC.inode_bitmap]
; call ext2_set_block ; и пишем на hdd новую битовую маску
 
;============== тут получаем номер блока
mov eax, [ext2_data.blocks_per_group]
sub esi, [ext2_data.global_desc_table]
shr esi, 5 ;esi - номер группы
mul esi
add ebp, eax ;(номер_группы) * (blocks_per_group) + локальный номер в группе
mov eax, [ext2_data.sb]
add ebp, [eax + EXT2_SB_STRUC.first_data_block]
 
;теперь поправим глобальную дескрипторную таблицу и суперблок
mov ebx, [ext2_data.sb]
dec [ebx + EXT2_SB_STRUC.free_block_count]
mov eax, 2
add eax, [PARTITION_START]
call hd_write
mov eax, [ebx + EXT2_SB_STRUC.first_data_block]
inc eax
dec [esi + EXT2_BLOCK_GROUP_DESC.free_blocks_count];edi все еще указывает на группу в которой мы выделил блок
call ext2_set_block
 
mov eax, ebx
ret
 
.test_last_dword:
lodsd
mov ecx, [ext2_data.blocks_per_group]
and ecx, not (32-1) ;обнуляем все кроме последних 5 бит
mov edx, ecx
mov ebx, 1
@@:
jecxz .no_space
mov edx, ebx
or edx, eax ; тестируем очередной бит
shl ebx, 1
jmp @B
@@:
sub edx, ecx
dec edx ;номер в последнем блоке
 
 
.no_space:
xor eax, eax
ret
 
;in: eax = i_block
; ebx = pointer to memory
ext2_set_block:
push eax ebx ecx
mov ecx, [ext2_data.log_block_size]
shl eax, cl
add eax, [PARTITION_START]
mov ecx, [ext2_data.count_block_in_block]
@@:
call hd_write
inc eax
add ebx, 512
loop @B
pop ecx ebx eax
ret
 
xor ebx, ebx
mov eax, ERROR_UNSUPPORTED_FS
ret
/kernel/branches/net/fs/fat12.inc
631,39 → 631,42
; \begin{diamond}
fat_find_lfn:
; in: esi->name
; [esp+4] = next
; [esp+8] = first
; [esp+C]... - possibly parameters for first and next
; out: CF=1 - file not found
; else CF=0, esi->next name component, edi->direntry
pusha
; [esp+4] = next
; [esp+8] = first
; [esp+C]... - possibly parameters for first and next
; out: CF=1 - file not found, eax=error code
; else CF=0, esi->next name component, edi->direntry
pusha
lea eax, [esp+0Ch+20h]
call dword [eax-4]
jc .reterr
sub esp, 262*2 ; reserve place for LFN
push 0 ; for fat_get_name: read ASCII name
.l1:
lea ebp, [esp+4]
call fat_get_name
jc .l2
call fat_compare_name
jz .found
.l2:
mov ebp, [esp+8+262*2+4]
lea eax, [esp+0Ch+20h+262*2+4]
call dword [eax-8]
jnc .l1
add esp, 262*2+4
.reterr:
mov [esp+28], eax
stc
popa
ret
.found:
add esp, 262*2+4
mov ebp, [esp+8]
; if this is LFN entry, advance to true entry
cmp byte [edi+11], 0xF
jnz @f
lea eax, [esp+0Ch+20h]
call dword [eax-4]
jc .reterr
sub esp, 262*2 ; reserve place for LFN
mov ebp, esp
push 0 ; for fat_get_name: read ASCII name
.l1:
call fat_get_name
jc .l2
call fat_compare_name
jz .found
.l2:
lea eax, [esp+0Ch+20h+262*2+4]
call dword [eax-8]
jnc .l1
add esp, 262*2+4
.reterr:
stc
popa
ret
.found:
add esp, 262*2+4
; if this is LFN entry, advance to true entry
cmp byte [edi+11], 0xF
jnz @f
lea eax, [esp+0Ch+20h]
call dword [eax-8]
jc .reterr
@@:
add esp, 8 ; CF=0
/kernel/branches/net/fs/fat32.inc
46,547 → 46,444
 
$Revision $
 
 
cache_max equ 1919 ; max. is 1919*512+0x610000=0x6ffe00
 
ERROR_SUCCESS = 0
ERROR_DISK_BASE = 1
ERROR_UNSUPPORTED_FS = 2
ERROR_UNKNOWN_FS = 3
ERROR_PARTITION = 4
ERROR_FILE_NOT_FOUND = 5
ERROR_END_OF_FILE = 6
ERROR_MEMORY_POINTER = 7
ERROR_DISK_FULL = 8
ERROR_FAT_TABLE = 9
ERROR_ACCESS_DENIED = 10
ERROR_DEVICE = 11
 
PUSHAD_EAX equ [esp+28]
PUSHAD_ECX equ [esp+24]
PUSHAD_EDX equ [esp+20]
 
cache_max equ 1919 ; max. is 1919*512+0x610000=0x6ffe00
 
PUSHAD_EAX equ [esp+28]
PUSHAD_ECX equ [esp+24]
PUSHAD_EDX equ [esp+20]
PUSHAD_EBX equ [esp+16]
PUSHAD_EBP equ [esp+8]
PUSHAD_ESI equ [esp+4]
PUSHAD_EDI equ [esp+0]
 
uglobal
align 4
partition_count dd 0 ; partitions found by set_FAT32_variables
longname_sec1 dd 0 ; used by analyze_directory to save 2 previous
longname_sec2 dd 0 ; directory sectors for delete long filename
 
hd_error dd 0 ; set by wait_for_sector_buffer
hd_setup dd 0
hd_wait_timeout dd 0
 
cluster_tmp dd 0 ; used by analyze_directory
; and analyze_directory_to_write
 
file_size dd 0 ; used by file_read
 
cache_search_start dd 0 ; used by find_empty_slot
endg
 
iglobal
fat_in_cache dd -1
endg
 
uglobal
align 4
fat_cache:
times 512 db 0
Sector512: ; label for dev_hdcd.inc
buffer:
times 512 db 0
fsinfo_buffer:
times 512 db 0
endg
 
uglobal
fat16_root db 0 ; flag for fat16 rootdir
fat_change db 0 ; 1=fat has changed
endg
 
reserve_hd1:
 
cli
cmp [hd1_status], 0
je reserve_ok1
 
sti
call change_task
jmp reserve_hd1
 
reserve_ok1:
 
push eax
mov eax, [CURRENT_TASK]
shl eax, 5
mov eax, [eax+CURRENT_TASK+TASKDATA.pid]
mov [hd1_status], eax
pop eax
sti
ret
;********************************************
 
uglobal
hd_in_cache db ?
endg
 
reserve_hd_channel:
; BIOS disk accesses are protected with common mutex hd1_status
; This must be modified when hd1_status will not be valid!
cmp [hdpos], 0x80
jae .ret
cmp [hdbase], 0x1F0
jne .IDE_Channel_2
.IDE_Channel_1:
cli
cmp [IDE_Channel_1], 0
je .reserve_ok_1
sti
call change_task
jmp .IDE_Channel_1
.IDE_Channel_2:
cli
cmp [IDE_Channel_2], 0
je .reserve_ok_2
sti
call change_task
jmp .IDE_Channel_2
.reserve_ok_1:
mov [IDE_Channel_1], 1
push eax
mov al, 1
jmp @f
.reserve_ok_2:
mov [IDE_Channel_2], 1
push eax
mov al, 3
@@:
cmp [hdid], 1
sbb al, -1
cmp al, [hd_in_cache]
jz @f
mov [hd_in_cache], al
call clear_hd_cache
@@:
pop eax
sti
.ret:
ret
 
free_hd_channel:
; see comment at reserve_hd_channel
cmp [hdpos], 0x80
jae .ret
cmp [hdbase], 0x1F0
jne .IDE_Channel_2
.IDE_Channel_1:
mov [IDE_Channel_1], 0
.ret:
ret
.IDE_Channel_2:
mov [IDE_Channel_2], 0
ret
;********************************************
problem_partition db 0 ; used for partitions search
 
include 'part_set.inc'
 
set_FAT:
;--------------------------------
; input : EAX = cluster
; EDX = value to save
; output : EDX = old value
;--------------------------------
push eax ebx esi
 
cmp eax, 2
jb sfc_error
cmp eax, [LAST_CLUSTER]
ja sfc_error
cmp [fs_type], 16
je sfc_1
PUSHAD_ESI equ [esp+4]
PUSHAD_EDI equ [esp+0]
 
; Internal data for every FAT partition.
struct FAT
p PARTITION ; must be the first item
fs_type db ?
fat16_root db 0 ; flag for fat16 rootdir
fat_change db 0 ; 1=fat has changed
db ? ; alignment
Lock MUTEX ? ; currently operations with one partition
; can not be executed in parallel since the
; legacy code is not ready; this mutex guards
; all operations
SECTORS_PER_FAT dd 0x1f3a
NUMBER_OF_FATS dd 0x2
SECTORS_PER_CLUSTER dd 0x8
BYTES_PER_SECTOR dd 0x200 ; Note: if BPS <> 512 need lots of changes
ROOT_CLUSTER dd 2 ; first rootdir cluster
FAT_START dd 0 ; start of fat table
ROOT_START dd 0 ; start of rootdir (only fat16)
ROOT_SECTORS dd 0 ; count of rootdir sectors (only fat16)
DATA_START dd 0 ; start of data area (=first cluster 2)
LAST_CLUSTER dd 0 ; last availabe cluster
ADR_FSINFO dd 0 ; used only by fat32
 
fatRESERVED dd 0x0FFFFFF6
fatBAD dd 0x0FFFFFF7
fatEND dd 0x0FFFFFF8
fatMASK dd 0x0FFFFFFF
 
fatStartScan dd 2
 
cluster_tmp dd 0 ; used by analyze_directory
; and analyze_directory_to_write
 
longname_sec1 dd 0 ; used by analyze_directory to save 2 previous
longname_sec2 dd 0 ; directory sectors for delete long filename
 
fat_in_cache dd -1
 
fat_cache rb 512
buffer rb 512
fsinfo_buffer rb 512
ends
 
uglobal
align 4
partition_count dd 0 ; partitions found by set_FAT32_variables
 
hd_error dd 0 ; set by wait_for_sector_buffer
hd_setup dd 0
hd_wait_timeout dd 0
 
cache_search_start dd 0 ; used by find_empty_slot
endg
 
uglobal
align 4
Sector512: ; label for dev_hdcd.inc
buffer:
times 512 db 0
endg
 
iglobal
align 4
fat_user_functions:
dd (fat_user_functions_end - fat_user_functions - 4) / 4
dd fat_Read
dd fat_ReadFolder
dd fat_Rewrite
dd fat_Write
dd fat_SetFileEnd
dd fat_GetFileInfo
dd fat_SetFileInfo
dd 0
dd fat_Delete
dd fat_CreateFolder
fat_user_functions_end:
endg
 
; these labels are located before the main function to make
; most of jumps to these be short
fat_create_partition.free_return0:
push ebx
mov eax, ebp
call free
pop ebx
pop ebp
fat_create_partition.return0:
xor eax, eax
ret
fat_create_partition:
; bootsector must have been successfully read
cmp dword [esp+4], 1
jnz .return0
; bootsector signature must be correct
cmp word [ebx+0x1fe], 0xaa55
jnz .return0
; sectors per cluster must be nonzero
cmp byte [ebx+0xd], 0
jz .return0
; bytes per sector must be 0x200
cmp word [ebx+0xb], 0x200
jnz .return0
; number of fats must be nonzero
cmp byte [ebx+0x10], 0
jz .return0
; The only reason to be invalid partition now is FAT12. Since the test for
; FAT size requires knowledge of some calculated values, which are also used
; in the normal operation, let's hope for the best and allocate data now; if
; it will prove wrong, just deallocate it.
push ebx
push sizeof.FAT
pop eax
call malloc
pop ebx
test eax, eax
jz .return0
mov ecx, [ebp+8]
mov dword [eax+FAT.p.FirstSector], ecx
mov ecx, [ebp+12]
mov dword [eax+FAT.p.FirstSector+4], ecx
mov ecx, [ebp+16]
mov dword [eax+FAT.p.Length], ecx
mov ecx, [ebp+20]
mov dword [eax+FAT.p.Length+4], ecx
mov [eax+FAT.p.Disk], esi
mov [eax+FAT.p.FSUserFunctions], fat_user_functions
or [eax+FAT.fat_in_cache], -1
mov [eax+FAT.fat_change], 0
push ebp
mov ebp, eax
 
lea ecx, [ebp+FAT.Lock]
call mutex_init
 
movzx eax, word [ebx+0xe] ; sectors reserved
mov [ebp+FAT.FAT_START], eax
 
movzx eax, byte [ebx+0xd] ; sectors per cluster
mov [ebp+FAT.SECTORS_PER_CLUSTER], eax
 
movzx ecx, word [ebx+0xb] ; bytes per sector
mov [ebp+FAT.BYTES_PER_SECTOR], ecx
 
movzx eax, word [ebx+0x11] ; count of rootdir entries (=0 fat32)
shl eax, 5 ; mul 32
dec ecx
add eax, ecx ; round up if not equal count
inc ecx ; bytes per sector
xor edx, edx
div ecx
mov [ebp+FAT.ROOT_SECTORS], eax ; count of rootdir sectors
 
movzx eax, word [ebx+0x16] ; sectors per fat <65536
test eax, eax
jnz @f
mov eax, [ebx+0x24] ; sectors per fat
@@:
mov [ebp+FAT.SECTORS_PER_FAT], eax
 
movzx eax, byte [ebx+0x10] ; number of fats
mov [ebp+FAT.NUMBER_OF_FATS], eax
imul eax, [ebp+FAT.SECTORS_PER_FAT]
add eax, [ebp+FAT.FAT_START]
mov [ebp+FAT.ROOT_START], eax ; rootdir = fat_start + fat_size * fat_count
add eax, [ebp+FAT.ROOT_SECTORS] ; rootdir sectors should be 0 on fat32
mov [ebp+FAT.DATA_START], eax ; data area = rootdir + rootdir_size
 
movzx eax, word [ebx+0x13] ; total sector count <65536
test eax, eax
jnz @f
mov eax, [ebx+0x20] ; total sector count
@@:
mov dword [ebp+FAT.p.Length], eax
and dword [ebp+FAT.p.Length+4], 0
sub eax, [ebp+FAT.DATA_START] ; eax = count of data sectors
xor edx, edx
div [ebp+FAT.SECTORS_PER_CLUSTER]
inc eax
mov [ebp+FAT.LAST_CLUSTER], eax
dec eax ; cluster count
mov [ebp+FAT.fatStartScan], 2
 
; limits by Microsoft Hardware White Paper v1.03
cmp eax, 4085 ; 0xff5
jb .free_return0 ; fat12 not supported
cmp eax, 65525 ; 0xfff5
jb .fat16
.fat32:
mov eax, [ebx+0x2c] ; rootdir cluster
mov [ebp+FAT.ROOT_CLUSTER], eax
movzx eax, word [ebx+0x30]
mov [ebp+FAT.ADR_FSINFO], eax
push ebx
add ebx, 512
call fs_read32_sys
test eax, eax
jnz @f
mov eax, [ebx+0x1ec]
cmp eax, -1
jz @f
mov [ebp+FAT.fatStartScan], eax
@@:
pop ebx
mov [ebp+FAT.fatRESERVED], 0x0FFFFFF6
mov [ebp+FAT.fatBAD], 0x0FFFFFF7
mov [ebp+FAT.fatEND], 0x0FFFFFF8
mov [ebp+FAT.fatMASK], 0x0FFFFFFF
mov al, 32
mov [fs_type], al
mov [ebp+FAT.fs_type], al
mov eax, ebp
pop ebp
ret
.fat16:
and [ebp+FAT.ROOT_CLUSTER], 0
mov [ebp+FAT.fatRESERVED], 0x0000FFF6
mov [ebp+FAT.fatBAD], 0x0000FFF7
mov [ebp+FAT.fatEND], 0x0000FFF8
mov [ebp+FAT.fatMASK], 0x0000FFFF
mov al, 16
mov [fs_type], al
mov [ebp+FAT.fs_type], al
mov eax, ebp
pop ebp
ret
 
set_FAT:
;--------------------------------
; input : EAX = cluster
; EDX = value to save
; EBP = pointer to FAT structure
; output : EDX = old value
;--------------------------------
; out: CF set <=> error
push eax ebx esi
 
cmp eax, 2
jb sfc_error
cmp eax, [ebp+FAT.LAST_CLUSTER]
ja sfc_error
cmp [ebp+FAT.fs_type], 16
je sfc_1
add eax, eax
sfc_1:
add eax, eax
sfc_1:
add eax, eax
mov esi, 511
and esi, eax ; esi = position in fat sector
shr eax, 9 ; eax = fat sector
add eax, [FAT_START]
mov ebx, fat_cache
 
cmp eax, [fat_in_cache]; is fat sector already in memory?
je sfc_in_cache ; yes
 
cmp [fat_change], 0 ; is fat changed?
je sfc_no_change ; no
call write_fat_sector; yes. write it into disk
cmp [hd_error], 0
jne sfc_error
 
sfc_no_change:
mov [fat_in_cache], eax; save fat sector
call hd_read
cmp [hd_error], 0
jne sfc_error
 
 
sfc_in_cache:
cmp [fs_type], 16
jne sfc_test32
 
sfc_set16:
mov esi, 511
and esi, eax ; esi = position in fat sector
shr eax, 9 ; eax = fat sector
add eax, [ebp+FAT.FAT_START]
lea ebx, [ebp+FAT.fat_cache]
 
cmp eax, [ebp+FAT.fat_in_cache]; is fat sector already in memory?
je sfc_in_cache ; yes
 
cmp [ebp+FAT.fat_change], 0; is fat changed?
je sfc_no_change ; no
call write_fat_sector; yes. write it into disk
jc sfc_error
 
sfc_no_change:
mov [ebp+FAT.fat_in_cache], eax; save fat sector
call fs_read32_sys
test eax, eax
jne sfc_error
 
 
sfc_in_cache:
cmp [ebp+FAT.fs_type], 16
jne sfc_test32
 
sfc_set16:
xchg [ebx+esi], dx ; save new value and get old value
jmp sfc_write
 
sfc_test32:
mov eax, [fatMASK]
 
sfc_set32:
and edx, eax
jmp sfc_write
 
sfc_test32:
mov eax, [ebp+FAT.fatMASK]
 
sfc_set32:
and edx, eax
xor eax, -1 ; mask for high bits
and eax, [ebx+esi] ; get high 4 bits
or eax, edx
mov edx, [ebx+esi] ; get old value
mov [ebx+esi], eax ; save new value
 
sfc_write:
mov [fat_change], 1 ; fat has changed
 
sfc_nonzero:
and edx, [fatMASK]
 
sfc_error:
pop esi ebx eax
ret
 
 
get_FAT:
;--------------------------------
; input : EAX = cluster
; output : EAX = next cluster
;--------------------------------
push ebx esi
 
cmp [fs_type], 16
je gfc_1
mov [ebx+esi], eax ; save new value
 
sfc_write:
mov [ebp+FAT.fat_change], 1; fat has changed
 
sfc_nonzero:
and edx, [ebp+FAT.fatMASK]
 
sfc_return:
pop esi ebx eax
ret
sfc_error:
stc
jmp sfc_return
 
 
get_FAT:
;--------------------------------
; input : EAX = cluster
; EBP = pointer to FAT structure
; output : EAX = next cluster
;--------------------------------
; out: CF set <=> error
push ebx esi
 
cmp [ebp+FAT.fs_type], 16
je gfc_1
add eax, eax
gfc_1:
add eax, eax
gfc_1:
add eax, eax
mov esi, 511
and esi, eax ; esi = position in fat sector
shr eax, 9 ; eax = fat sector
add eax, [FAT_START]
mov ebx, fat_cache
 
cmp eax, [fat_in_cache]; is fat sector already in memory?
je gfc_in_cache
 
cmp [fat_change], 0 ; is fat changed?
je gfc_no_change ; no
call write_fat_sector; yes. write it into disk
cmp [hd_error], 0
jne hd_error_01
 
gfc_no_change:
mov [fat_in_cache], eax
call hd_read
cmp [hd_error], 0
jne hd_error_01
 
gfc_in_cache:
mov eax, [ebx+esi]
and eax, [fatMASK]
hd_error_01:
pop esi ebx
ret
 
 
get_free_FAT:
mov esi, 511
and esi, eax ; esi = position in fat sector
shr eax, 9 ; eax = fat sector
add eax, [ebp+FAT.FAT_START]
lea ebx, [ebp+FAT.fat_cache]
 
cmp eax, [ebp+FAT.fat_in_cache]; is fat sector already in memory?
je gfc_in_cache
 
cmp [ebp+FAT.fat_change], 0; is fat changed?
je gfc_no_change ; no
call write_fat_sector; yes. write it into disk
jc hd_error_01
 
gfc_no_change:
mov [ebp+FAT.fat_in_cache], eax
call fs_read32_sys
test eax, eax
jne hd_error_01
 
gfc_in_cache:
mov eax, [ebx+esi]
and eax, [ebp+FAT.fatMASK]
gfc_return:
pop esi ebx
ret
hd_error_01:
stc
jmp gfc_return
 
 
get_free_FAT:
;-----------------------------------------------------------
; output : if CARRY=0 EAX = # first cluster found free
; if CARRY=1 disk full
; Note : for more speed need to use fat_cache directly
;-----------------------------------------------------------
push ecx
mov ecx, [LAST_CLUSTER]; counter for full disk
sub ecx, 2
mov eax, [fatStartScan]
cmp eax, 2
jb gff_reset
; Note : for more speed need to use fat_cache directly
;-----------------------------------------------------------
push ecx
mov ecx, [ebp+FAT.LAST_CLUSTER]; counter for full disk
sub ecx, 2
mov eax, [ebp+FAT.fatStartScan]
cmp eax, 2
jb gff_reset
 
gff_test:
cmp eax, [ebp+FAT.LAST_CLUSTER]; if above last cluster start at cluster 2
jbe gff_in_range
gff_reset:
mov eax, 2
 
gff_test:
cmp eax, [LAST_CLUSTER]; if above last cluster start at cluster 2
jbe gff_in_range
gff_reset:
mov eax, 2
 
gff_in_range:
push eax
call get_FAT ; get cluster state
cmp [hd_error], 0
jne gff_not_found_1
 
test eax, eax ; is it free?
pop eax
gff_in_range:
push eax
call get_FAT ; get cluster state
jc gff_not_found_1
 
test eax, eax ; is it free?
pop eax
je gff_found ; yes
inc eax ; next cluster
dec ecx ; is all checked?
jns gff_test ; no
dec ecx ; is all checked?
jns gff_test ; no
 
gff_not_found:
pop ecx ; yes. disk is full
stc
ret
 
gff_not_found_1:
pop eax
jmp gff_not_found
 
gff_found:
lea ecx, [eax+1]
mov [ebp+FAT.fatStartScan], ecx
pop ecx
clc
ret
 
gff_not_found_1:
add esp, 4
gff_not_found:
pop ecx ; yes. disk is full
stc
ret
 
gff_found:
lea ecx, [eax+1]
mov [fatStartScan], ecx
pop ecx
clc
ret
 
 
write_fat_sector:
;-----------------------------------------------------------
; write changed fat to disk
;-----------------------------------------------------------
push eax ebx ecx
 
mov [fat_change], 0
mov eax, [fat_in_cache]
cmp eax, -1
jz write_fat_not_used
mov ebx, fat_cache
mov ecx, [NUMBER_OF_FATS]
 
write_next_fat:
call hd_write
cmp [hd_error], 0
jne write_fat_not_used
 
add eax, [SECTORS_PER_FAT]
dec ecx
jnz write_next_fat
 
;-----------------------------------------------------------
push eax ebx ecx
 
mov [ebp+FAT.fat_change], 0
mov eax, [ebp+FAT.fat_in_cache]
cmp eax, -1
jz write_fat_not_used
lea ebx, [ebp+FAT.fat_cache]
mov ecx, [ebp+FAT.NUMBER_OF_FATS]
 
write_next_fat:
push eax
call fs_write32_sys
test eax, eax
pop eax
jnz write_fat_not_used
 
add eax, [ebp+FAT.SECTORS_PER_FAT]
dec ecx
jnz write_next_fat
 
write_fat_not_used:
pop ecx ebx eax
ret
 
 
analyze_directory:
;-----------------------------------------------------------
; input : EAX = first cluster of the directory
; EBX = pointer to filename
; output : IF CARRY=0 EAX = sector where th file is found
; EBX = pointer in buffer
; [buffer .. buffer+511]
; ECX,EDX,ESI,EDI not changed
; IF CARRY=1 filename not found
; Note : if cluster=0 it's changed to read rootdir
; save 2 previous directory sectors in longname_sec
;-----------------------------------------------------------
push ecx edx esi edi ebx; ebx = [esp+0]
mov [longname_sec1], 0
mov [longname_sec2], 0
 
adr_new_cluster:
mov [cluster_tmp], eax
mov [fat16_root], 0
cmp eax, [LAST_CLUSTER]
ja adr_not_found ; too big cluster number, something is wrong
cmp eax, 2
jnb adr_data_cluster
 
mov eax, [ROOT_CLUSTER]; if cluster < 2 then read rootdir
cmp [fs_type], 16
jne adr_data_cluster
mov eax, [ROOT_START]
mov edx, [ROOT_SECTORS]
mov [fat16_root], 1 ; flag for fat16 rootdir
jmp adr_new_sector
 
adr_data_cluster:
sub eax, 2
mov edx, [SECTORS_PER_CLUSTER]
imul eax, edx
add eax, [DATA_START]
 
adr_new_sector:
mov ebx, buffer
call hd_read
cmp [hd_error], 0
jne adr_not_found
 
mov ecx, 512/32 ; count of dir entrys per sector = 16
 
adr_analyze:
mov edi, [ebx+11] ; file attribute
and edi, 0xf
cmp edi, 0xf
je adr_long_filename
test edi, 0x8 ; skip over volume label
jne adr_long_filename; Note: label can be same name as file/dir
 
mov esi, [esp+0] ; filename need to be uppercase
mov edi, ebx
push ecx
mov ecx, 11
cld
rep cmpsb ; compare 8+3 filename
pop ecx
je adr_found
 
adr_long_filename:
add ebx, 32 ; position of next dir entry
dec ecx
jnz adr_analyze
 
mov ecx, [longname_sec1]; save 2 previous directory sectors
mov [longname_sec1], eax; for delete long filename
mov [longname_sec2], ecx
inc eax ; next sector
dec edx
jne adr_new_sector
cmp [fat16_root], 1 ; end of fat16 rootdir
je adr_not_found
 
adr_next_cluster:
mov eax, [cluster_tmp]
call get_FAT ; get next cluster
cmp [hd_error], 0
jne adr_not_found
 
cmp eax, 2 ; incorrect fat chain?
jb adr_not_found ; yes
cmp eax, [fatRESERVED]; is it end of directory?
jb adr_new_cluster ; no. analyse it
 
adr_not_found:
pop edi edi esi edx ecx; first edi will remove ebx
stc ; file not found
ret
 
adr_found:
pop edi edi esi edx ecx; first edi will remove ebx
clc ; file found
ret
 
 
get_data_cluster:
;-----------------------------------------------------------
; input : EAX = cluster
; EBX = pointer to buffer
; EDX = # blocks to read in buffer
; ESI = # blocks to skip over
; output : if CARRY=0 ok EBX/EDX/ESI updated
; if CARRY=1 cluster out of range
; Note : if cluster=0 it's changed to read rootdir
;-----------------------------------------------------------
push eax ecx
 
mov [fat16_root], 0
cmp eax, [LAST_CLUSTER]
ja gdc_error ; too big cluster number, something is wrong
cmp eax, 2
jnb gdc_cluster
 
mov eax, [ROOT_CLUSTER]; if cluster < 2 then read rootdir
cmp [fs_type], 16
jne gdc_cluster
mov eax, [ROOT_START]
mov ecx, [ROOT_SECTORS]; Note: not cluster size
mov [fat16_root], 1 ; flag for fat16 rootdir
jmp gdc_read
 
gdc_cluster:
sub eax, 2
mov ecx, [SECTORS_PER_CLUSTER]
imul eax, ecx
add eax, [DATA_START]
 
gdc_read:
test esi, esi ; first wanted block
je gdcl1 ; yes, skip count is 0
dec esi
jmp gdcl2
 
gdcl1:
call hd_read
cmp [hd_error], 0
jne gdc_error
 
add ebx, 512 ; update pointer
dec edx
 
gdcl2:
test edx, edx ; is all read?
je out_of_read
 
inc eax ; next sector
dec ecx
jnz gdc_read
 
out_of_read:
pop ecx eax
clc
ret
 
gdc_error:
pop ecx eax
stc
ret
 
 
get_cluster_of_a_path:
;---------------------------------------------------------
; input : EBX = pointer to a path string
; (example: the path "/files/data/document" become
; "files......data.......document...0"
; '.' = space char
; '0' = char(0) (ASCII=0) !!! )
; output : if (CARRY=1) -> ERROR in the PATH
; if (CARRY=0) -> EAX=cluster
;---------------------------------------------------------
push ebx edx
 
mov eax, [ROOT_CLUSTER]
mov edx, ebx
 
search_end_of_path:
cmp byte [edx], 0
je found_end_of_path
 
inc edx; '/'
mov ebx, edx
call analyze_directory
jc directory_not_found
 
mov eax, [ebx+20-2] ; read the HIGH 16bit cluster field
mov ax, [ebx+26] ; read the LOW 16bit cluster field
and eax, [fatMASK]
add edx, 11 ; 8+3 (name+extension)
jmp search_end_of_path
 
found_end_of_path:
pop edx ebx
clc ; no errors
ret
 
directory_not_found:
pop edx ebx
stc ; errors occour
ret
 
 
bcd2bin:
;----------------------------------
; input : AL=BCD number (eg. 0x11)
ret
 
 
 
 
 
bcd2bin:
;----------------------------------
; input : AL=BCD number (eg. 0x11)
; output : AH=0
; AL=decimal number (eg. 11)
;----------------------------------
673,251 → 570,84
; input : ecx = cluster count
; Note : negative = remove clusters from free space
; positive = add clusters to free space
;-----------------------------------------------------
test ecx, ecx ; no change
je add_dfs_no
cmp [fs_type], 32 ; free disk space only used by fat32
jne add_dfs_no
;-----------------------------------------------------
test ecx, ecx ; no change
je add_dfs_no
cmp [ebp+FAT.fs_type], 32 ; free disk space only used by fat32
jne add_dfs_no
 
push eax ebx
mov eax, [ebp+FAT.ADR_FSINFO]
lea ebx, [ebp+FAT.fsinfo_buffer]
call fs_read32_sys
test eax, eax
jnz add_not_fs
 
cmp dword [ebx+0x1fc], 0xaa550000; check sector id
jne add_not_fs
 
add [ebx+0x1e8], ecx
push [ebp+FAT.fatStartScan]
pop dword [ebx+0x1ec]
mov eax, [ebp+FAT.ADR_FSINFO]
call fs_write32_sys
; jc add_not_fs
 
add_not_fs:
pop ebx eax
 
push eax ebx
mov eax, [ADR_FSINFO]
mov ebx, fsinfo_buffer
call hd_read
cmp [hd_error], 0
jne add_not_fs
 
cmp dword [ebx+0x1fc], 0xaa550000; check sector id
jne add_not_fs
 
add [ebx+0x1e8], ecx
push [fatStartScan]
pop dword [ebx+0x1ec]
call hd_write
; cmp [hd_error],0
; jne add_not_fs
 
add_not_fs:
pop ebx eax
 
add_dfs_no:
ret
 
 
file_read:
;--------------------------------------------------------------------------
; INPUT : user-register register-in-this meaning symbol-in-this
;
; EAX EDI system call to write /
; EBX EAX (PAR0) pointer to file-name PAR0
; EDX ECX (PAR1) pointer to buffer PAR1
; ECX EBX (PAR2) vt file blocks to read PAR2
; ESI EDX (PAR3) pointer to path PAR3
; EDI ESI vt first 512 block to read
; EDI if 0 - read root
;
; output : eax = 0 - ok
; 3 - unknown FS
; 5 - file not found
; 6 - end of file
; 9 - fat table corrupted
; 10 - access denied
; ebx = size of file/directory
;--------------------------------------------------------------------------
cmp [fs_type], 16
jz fat_ok_for_reading
cmp [fs_type], 32
jz fat_ok_for_reading
xor ebx, ebx
mov eax, ERROR_UNKNOWN_FS
mov [hd1_status], ebx
ret
 
fat_ok_for_reading:
; call reserve_hd1
 
pushad
 
mov ebx, edx
call get_cluster_of_a_path
jc file_to_read_not_found
 
test edi, edi ; read rootdir
jne no_read_root
 
xor eax, eax
call get_dir_size ; return rootdir size
cmp [hd_error], 0
jne file_access_denied
 
mov [file_size], eax
mov eax, [ROOT_CLUSTER]
jmp file_read_start
 
no_read_root:
mov ebx, PUSHAD_EAX ; file name
call analyze_directory
jc file_to_read_not_found
 
mov eax, [ebx+28] ; file size
test byte [ebx+11], 0x10; is it directory?
jz read_set_size ; no
 
mov eax, [ebx+20-2] ; FAT entry
mov ax, [ebx+26]
and eax, [fatMASK]
call get_dir_size
cmp [hd_error], 0
jne file_access_denied
 
read_set_size:
mov [file_size], eax
 
mov eax, [ebx+20-2] ; FAT entry
mov ax, [ebx+26]
and eax, [fatMASK]
 
file_read_start:
mov ebx, PUSHAD_ECX ; pointer to buffer
mov edx, PUSHAD_EBX ; file blocks to read
mov esi, PUSHAD_ESI ; first 512 block to read
 
file_read_new_cluster:
call get_data_cluster
jc file_read_eof ; end of file or cluster out of range
 
test edx, edx ; is all read?
je file_read_OK ; yes
 
call get_FAT ; get next cluster
cmp [hd_error], 0
jne file_access_denied
 
cmp eax, [fatRESERVED]; end of file
jnb file_read_eof
cmp eax, 2 ; incorrect fat chain
jnb file_read_new_cluster
 
popad
mov [hd1_status], 0
mov ebx, [file_size]
mov eax, ERROR_FAT_TABLE
ret
 
file_read_eof:
cmp [hd_error], 0
jne file_access_denied
popad
mov [hd1_status], 0
mov ebx, [file_size]
mov eax, ERROR_END_OF_FILE
ret
 
file_read_OK:
popad
mov [hd1_status], 0
mov ebx, [file_size]
xor eax, eax
ret
 
file_to_read_not_found:
cmp [hd_error], 0
jne file_access_denied
popad
mov [hd1_status], 0
xor ebx, ebx
mov eax, ERROR_FILE_NOT_FOUND
ret
 
file_access_denied:
popad
mov [hd1_status], 0
xor ebx, ebx
mov eax, ERROR_ACCESS_DENIED
ret
 
get_dir_size:
ret
 
 
 
clear_cluster_chain:
;-----------------------------------------------------
; input : eax = first cluster
;-----------------------------------------------------
; input : eax = first cluster (0=rootdir)
; output : eax = directory size in bytes
;-----------------------------------------------------
push edx
xor edx, edx ; count of directory clusters
test eax, eax
jnz dir_size_next
 
mov eax, [ROOT_SECTORS]
shl eax, 9 ; fat16 rootdir size in bytes
cmp [fs_type], 16
je dir_size_ret
mov eax, [ROOT_CLUSTER]
 
dir_size_next:
cmp eax, 2 ; incorrect fat chain
jb dir_size_end
cmp eax, [fatRESERVED]; end of directory
ja dir_size_end
call get_FAT ; get next cluster
cmp [hd_error], 0
jne dir_size_ret
 
inc edx
jmp dir_size_next
 
dir_size_end:
imul eax, [SECTORS_PER_CLUSTER], 512; cluster size in bytes
imul eax, edx
 
dir_size_ret:
pop edx
ret
 
 
clear_cluster_chain:
;-----------------------------------------------------
; input : eax = first cluster
;-----------------------------------------------------
push eax ecx edx
xor ecx, ecx ; cluster count
 
clean_new_chain:
cmp eax, [LAST_CLUSTER]; end of file
ja delete_OK
cmp eax, 2 ; unfinished fat chain or zero length file
jb delete_OK
cmp eax, [ROOT_CLUSTER]; don't remove root cluster
jz delete_OK
 
xor edx, edx
call set_FAT ; clear fat entry
cmp [hd_error], 0
jne access_denied_01
 
inc ecx ; update cluster count
mov eax, edx ; old cluster
xor ecx, ecx ; cluster count
 
clean_new_chain:
cmp eax, [ebp+FAT.LAST_CLUSTER]; end of file
ja delete_OK
cmp eax, 2 ; unfinished fat chain or zero length file
jb delete_OK
cmp eax, [ebp+FAT.ROOT_CLUSTER]; don't remove root cluster
jz delete_OK
 
xor edx, edx
call set_FAT ; clear fat entry
jc access_denied_01
 
inc ecx ; update cluster count
mov eax, edx ; old cluster
jmp clean_new_chain
 
delete_OK:
call add_disk_free_space; add clusters to free disk space
access_denied_01:
pop edx ecx eax
ret
 
 
get_hd_info:
;-----------------------------------------------------------
; output : eax = 0 - ok
 
delete_OK:
call add_disk_free_space; add clusters to free disk space
clc
access_denied_01:
pop edx ecx eax
ret
 
 
if 0
get_hd_info:
;-----------------------------------------------------------
; output : eax = 0 - ok
; 3 - unknown FS
; 10 - access denied
; edx = cluster size in bytes
; ebx = total clusters on disk
; ecx = free clusters on disk
;-----------------------------------------------------------
cmp [fs_type], 16
jz info_fat_ok
cmp [fs_type], 32
jz info_fat_ok
xor edx, edx
xor ebx, ebx
; ebx = total clusters on disk
; ecx = free clusters on disk
;-----------------------------------------------------------
cmp [ebp+FAT.fs_type], 16
jz info_fat_ok
cmp [ebp+FAT.fs_type], 32
jz info_fat_ok
xor edx, edx
xor ebx, ebx
xor ecx, ecx
mov eax, ERROR_UNKNOWN_FS
ret
924,19 → 654,18
 
info_fat_ok:
; call reserve_hd1
 
xor ecx, ecx ; count of free clusters
mov eax, 2
mov ebx, [LAST_CLUSTER]
 
info_cluster:
push eax
call get_FAT ; get cluster info
cmp [hd_error], 0
jne info_access_denied
 
test eax, eax ; is it free?
jnz info_used ; no
 
xor ecx, ecx ; count of free clusters
mov eax, 2
mov ebx, [ebp+FAT.LAST_CLUSTER]
 
info_cluster:
push eax
call get_FAT ; get cluster info
jc info_access_denied
 
test eax, eax ; is it free?
jnz info_used ; no
inc ecx
 
info_used:
943,56 → 672,65
pop eax
inc eax
cmp eax, ebx ; is above last cluster?
jbe info_cluster ; no. test next cluster
 
dec ebx ; cluster count
imul edx, [SECTORS_PER_CLUSTER], 512; cluster size in bytes
mov [hd1_status], 0
xor eax, eax
ret
 
jbe info_cluster ; no. test next cluster
 
dec ebx ; cluster count
imul edx, [ebp+FAT.SECTORS_PER_CLUSTER], 512; cluster size in bytes
xor eax, eax
ret
 
info_access_denied:
add esp, 4
xor edx, edx
xor ebx, ebx
xor ecx, ecx
mov eax, ERROR_ACCESS_DENIED
ret
 
update_disk:
;-----------------------------------------------------------
; write changed fat and cache to disk
;-----------------------------------------------------------
cmp [fat_change], 0 ; is fat changed?
je upd_no_change
 
call write_fat_sector
cmp [hd_error], 0
jne update_disk_acces_denied
 
upd_no_change:
 
call write_cache
update_disk_acces_denied:
ret
 
 
; \begin{diamond}
hd_find_lfn:
; in: esi+ebp -> name
; out: CF=1 - file not found
; else CF=0 and edi->direntry, eax=sector
; destroys eax
push esi edi
xor ecx, ecx
mov eax, ERROR_ACCESS_DENIED
ret
end if
 
update_disk:
;-----------------------------------------------------------
; write changed fat and cache to disk
;-----------------------------------------------------------
cmp [ebp+FAT.fat_change], 0 ; is fat changed?
je upd_no_change
 
call write_fat_sector
jc update_disk_acces_denied
 
upd_no_change:
 
push esi
mov esi, [ebp+PARTITION.Disk]
call disk_sync
pop esi
update_disk_acces_denied:
ret
 
fat_lock:
lea ecx, [ebp+FAT.Lock]
jmp mutex_lock
fat_unlock:
lea ecx, [ebp+FAT.Lock]
jmp mutex_unlock
 
; \begin{diamond}
hd_find_lfn:
; in: ebp -> FAT structure
; in: esi+[esp+4] -> name
; out: CF=1 - file not found, eax=error code
; else CF=0 and edi->direntry, eax=sector
; destroys eax
push esi edi
push 0
push 0
push fat16_root_first
push fat16_root_next
mov eax, [ROOT_CLUSTER]
cmp [fs_type], 32
jz .fat32
.loop:
call fat_find_lfn
push 0
push fat16_root_first
push fat16_root_next
mov eax, [ebp+FAT.ROOT_CLUSTER]
cmp [ebp+FAT.fs_type], 32
jz .fat32
.loop:
call fat_find_lfn
jc .notfound
cmp byte [esi], 0
jz .found
1008,37 → 746,40
mov dword [esp], fat_notroot_next
jmp .loop
.notfound:
add esp, 16
pop edi esi
stc
ret
.found:
test ebp, ebp
jz @f
mov esi, ebp
xor ebp, ebp
jmp .continue
@@:
lea eax, [esp+8]
add esp, 16
pop edi esi
stc
ret 4
.found:
lea eax, [esp+4+24]
cmp dword [eax], 0
jz @f
mov esi, [eax]
and dword [eax], 0
jmp .continue
@@:
lea eax, [esp+8]
cmp dword [eax], 0
jz .root
call fat_get_sector
jmp .cmn
.root:
mov eax, [eax+4]
add eax, [ROOT_START]
.cmn:
add esp, 20 ; CF=0
pop esi
ret
 
;----------------------------------------------------------------
;
; fs_HdRead - LFN variant for reading hard disk
;
; esi points to filename
; ebx pointer to 64-bit number = first wanted byte, 0+
; may be ebx=0 - start from first byte
jmp .cmn
.root:
mov eax, [eax+4]
add eax, [ebp+FAT.ROOT_START]
.cmn:
add esp, 20 ; CF=0
pop esi
ret 4
 
;----------------------------------------------------------------
;
; fs_HdRead - LFN variant for reading hard disk
;
; Obsolete, will be replaced with filesystem-specific functions.
;
; esi points to filename
; ebx pointer to 64-bit number = first wanted byte, 0+
; may be ebx=0 - start from first byte
; ecx number of bytes to read, 0+
; edx mem location to return data
;
1056,48 → 797,65
cmp [fs_type], 2
jz ext2_HdRead
or ebx, -1
mov eax, ERROR_UNKNOWN_FS
ret
@@:
push edi
cmp byte [esi], 0
jnz @f
.noaccess:
pop edi
.noaccess_2:
or ebx, -1
mov eax, ERROR_ACCESS_DENIED
ret
 
@@:
call hd_find_lfn
jnc .found
pop edi
cmp [hd_error], 0
jne .noaccess_2
or ebx, -1
mov eax, ERROR_FILE_NOT_FOUND
ret
 
.found:
test byte [edi+11], 0x10; do not allow read directories
jnz .noaccess
test ebx, ebx
jz .l1
cmp dword [ebx+4], 0
jz @f
xor ebx, ebx
.reteof:
mov eax, 6
pop edi
ret
@@:
mov ebx, [ebx]
.l1:
push ecx edx
push 0
mov eax, [edi+28]
sub eax, ebx
mov eax, ERROR_UNKNOWN_FS
ret
@@:
sub ebx, 4
push ebp
mov ebp, [fs_dependent_data_start.partition]
call fat_Read
pop ebp
ret
 
;----------------------------------------------------------------
; fat_Read - FAT16/32 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
;----------------------------------------------------------------
fat_Read:
call fat_lock
push edi
cmp byte [esi], 0
jnz @f
.noaccess:
pop edi
.noaccess_2:
call fat_unlock
or ebx, -1
mov eax, ERROR_ACCESS_DENIED
ret
 
@@:
stdcall hd_find_lfn, [esp+4+4]
jnc .found
pop edi
push eax
call fat_unlock
pop eax
or ebx, -1
ret
 
.found:
test byte [edi+11], 0x10; do not allow read directories
jnz .noaccess
cmp dword [ebx+8], 0
jz @f
xor ebx, ebx
.reteof:
call fat_unlock
mov eax, ERROR_END_OF_FILE
pop edi
ret
@@:
mov ecx, [ebx+12] ; size
mov edx, [ebx+16] ; pointer
mov ebx, [ebx+4] ; file offset
push edx
push 0
mov eax, [edi+28]
sub eax, ebx
jb .eof
cmp eax, ecx
jae @f
1106,49 → 864,49
@@:
mov eax, [edi+20-2]
mov ax, [edi+26]
; now eax=cluster, ebx=position, ecx=count, edx=buffer for data
.new_cluster:
jecxz .new_sector
test eax, eax
jz .eof
cmp eax, [fatRESERVED]
jae .eof
mov [cluster_tmp], eax
dec eax
dec eax
mov edi, [SECTORS_PER_CLUSTER]
imul eax, edi
add eax, [DATA_START]
.new_sector:
test ecx, ecx
jz .done
; now eax=cluster, ebx=position, ecx=count, edx=buffer for data
.new_cluster:
jecxz .new_sector
cmp eax, 2
jb .eof
cmp eax, [ebp+FAT.fatRESERVED]
jae .eof
mov [ebp+FAT.cluster_tmp], eax
dec eax
dec eax
mov edi, [ebp+FAT.SECTORS_PER_CLUSTER]
imul eax, edi
add eax, [ebp+FAT.DATA_START]
.new_sector:
test ecx, ecx
jz .done
sub ebx, 512
jae .skip
add ebx, 512
jnz .force_buf
cmp ecx, 512
jb .force_buf
; we may read directly to given buffer
push ebx
mov ebx, edx
call hd_read
pop ebx
cmp [hd_error], 0
jne .noaccess_1
add edx, 512
sub ecx, 512
cmp ecx, 512
jb .force_buf
; we may read directly to given buffer
push eax ebx
mov ebx, edx
call fs_read32_app
test eax, eax
pop ebx eax
jne .noaccess_1
add edx, 512
sub ecx, 512
jmp .skip
.force_buf:
; we must read sector to temporary buffer and then copy it to destination
push eax ebx
mov ebx, buffer
call hd_read
mov eax, ebx
pop ebx
cmp [hd_error], 0
jne .noaccess_3
add eax, ebx
push ecx
.force_buf:
; we must read sector to temporary buffer and then copy it to destination
push eax ebx
lea ebx, [ebp+FAT.buffer]
call fs_read32_app
test eax, eax
mov eax, ebx
pop ebx
jne .noaccess_3
add eax, ebx
push ecx
add ecx, ebx
cmp ecx, 512
jbe @f
1163,38 → 921,40
pop eax
xor ebx, ebx
.skip:
inc eax
dec edi
jnz .new_sector
mov eax, [cluster_tmp]
call get_FAT
cmp [hd_error], 0
jne .noaccess_1
 
jmp .new_cluster
.noaccess_3:
pop eax
.noaccess_1:
pop eax
push 11
.done:
mov ebx, edx
pop eax edx ecx edi
sub ebx, edx
ret
.eof:
mov ebx, edx
pop eax edx ecx
sub ebx, edx
jmp .reteof
 
inc eax
dec edi
jnz .new_sector
mov eax, [ebp+FAT.cluster_tmp]
call get_FAT
jc .noaccess_1
 
jmp .new_cluster
.noaccess_3:
pop eax
.noaccess_1:
pop eax
push ERROR_DEVICE
.done:
mov ebx, edx
call fat_unlock
pop eax edx edi
sub ebx, edx
ret
.eof:
mov ebx, edx
pop eax edx
sub ebx, edx
jmp .reteof
 
;----------------------------------------------------------------
;
; fs_HdReadFolder - LFN variant for reading hard disk folder
;
; esi points to filename
; ebx pointer to structure 32-bit number = first wanted block, 0+
; & flags (bitfields)
;
; fs_HdReadFolder - LFN variant for reading hard disk folder
;
; Obsolete, will be replaced with filesystem-specific functions.
;
; esi points to filename
; ebx pointer to structure 32-bit number = first wanted block, 0+
; & flags (bitfields)
; flags: bit 0: 0=ANSI names, 1=UNICODE names
; ecx number of blocks to read, 0+
; edx mem location to return data
1201,299 → 961,354
;
; ret ebx = blocks read or 0xffffffff folder not found
; eax = 0 ok read or other = errormsg
;
;--------------------------------------------------------------
fs_HdReadFolder:
cmp [fs_type], 1
jz ntfs_HdReadFolder
cmp [fs_type], 2
jz ext2_HdReadFolder
cmp [fs_type], 16
jz @f
cmp [fs_type], 32
jz @f
push ERROR_UNSUPPORTED_FS
pop eax
or ebx, -1
ret
@@:
mov eax, [ROOT_CLUSTER]
push edi
cmp byte [esi], 0
jz .doit
call hd_find_lfn
jnc .found
pop edi
or ebx, -1
mov eax, ERROR_FILE_NOT_FOUND
ret
.found:
test byte [edi+11], 0x10 ; do not allow read files
jnz .found_dir
pop edi
or ebx, -1
mov eax, ERROR_ACCESS_DENIED
ret
;
;--------------------------------------------------------------
fs_HdReadFolder:
cmp [fs_type], 16
jz @f
cmp [fs_type], 32
jz @f
cmp [fs_type], 1
jz ntfs_HdReadFolder
cmp [fs_type], 2
jz ext2_HdReadFolder
push ERROR_UNSUPPORTED_FS
pop eax
or ebx, -1
ret
@@:
sub ebx, 4
push ebp
mov ebp, [fs_dependent_data_start.partition]
call fat_ReadFolder
pop ebp
ret
 
;----------------------------------------------------------------
; fat_ReadFolder - FAT16/32 implementation of reading a folder
; 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
;----------------------------------------------------------------
fat_ReadFolder:
call fat_lock
mov eax, [ebp+FAT.ROOT_CLUSTER]
push edi
cmp byte [esi], 0
jz .doit
stdcall hd_find_lfn, [esp+4+4]
jnc .found
pop edi
push eax
call fat_unlock
pop eax
or ebx, -1
ret
.found:
test byte [edi+11], 0x10 ; do not allow read files
jnz .found_dir
pop edi
call fat_unlock
or ebx, -1
mov eax, ERROR_ACCESS_DENIED
ret
.found_dir:
mov eax, [edi+20-2]
mov ax, [edi+26] ; eax=cluster
.doit:
push esi ecx
push ebp
sub esp, 262*2 ; reserve space for LFN
mov ebp, esp
push dword [ebx+4] ; for fat_get_name: read ANSI/UNICODE name
mov ebx, [ebx]
; init header
push eax ecx
mov edi, edx
mov ecx, 32/4
xor eax, eax
rep stosd
pop ecx eax
mov byte [edx], 1 ; version
mov esi, edi ; esi points to BDFE
.new_cluster:
mov [cluster_tmp], eax
test eax, eax
jnz @f
cmp [fs_type], 32
jz .notfound
mov eax, [ROOT_START]
push [ROOT_SECTORS]
push ebx
jmp .new_sector
@@:
dec eax
dec eax
imul eax, [SECTORS_PER_CLUSTER]
push [SECTORS_PER_CLUSTER]
add eax, [DATA_START]
push ebx
.new_sector:
mov ebx, buffer
mov edi, ebx
call hd_read
cmp [hd_error], 0
jnz .notfound2
add ebx, 512
push eax
.l1:
call fat_get_name
jc .l2
cmp byte [edi+11], 0xF
jnz .do_bdfe
mov eax, [edi+20-2]
mov ax, [edi+26] ; eax=cluster
.doit:
push esi
sub esp, 262*2 ; reserve space for LFN
push dword [ebx+8] ; for fat_get_name: read ANSI/UNICODE name
mov edx, [ebx+16] ; pointer to buffer
; init header
push eax
mov edi, edx
mov ecx, 32/4
xor eax, eax
rep stosd
pop eax
mov byte [edx], 1 ; version
mov esi, edi ; esi points to BDFE
mov ecx, [ebx+12] ; number of blocks to read
mov ebx, [ebx+4] ; index of the first block
.new_cluster:
mov [ebp+FAT.cluster_tmp], eax
test eax, eax
jnz @f
cmp [ebp+FAT.fs_type], 32
jz .notfound
mov eax, [ebp+FAT.ROOT_START]
push [ebp+FAT.ROOT_SECTORS]
push ebx
jmp .new_sector
@@:
dec eax
dec eax
imul eax, [ebp+FAT.SECTORS_PER_CLUSTER]
push [ebp+FAT.SECTORS_PER_CLUSTER]
add eax, [ebp+FAT.DATA_START]
push ebx
.new_sector:
lea ebx, [ebp+FAT.buffer]
mov edi, ebx
push eax
call fs_read32_sys
test eax, eax
pop eax
jnz .notfound2
add ebx, 512
push eax
.l1:
push ebp
lea ebp, [esp+20]
call fat_get_name
pop ebp
jc .l2
cmp byte [edi+11], 0xF
jnz .do_bdfe
add edi, 0x20
cmp edi, ebx
jb .do_bdfe
pop eax
inc eax
dec dword [esp+4]
jnz @f
mov eax, [cluster_tmp]
test eax, eax
jz .done
call get_FAT
cmp [hd_error], 0
jnz .notfound2
cmp eax, 2
jb .done
cmp eax, [fatRESERVED]
jae .done
push eax
mov eax, [SECTORS_PER_CLUSTER]
mov [esp+8], eax
pop eax
mov [cluster_tmp], eax
dec eax
dec eax
imul eax, [SECTORS_PER_CLUSTER]
add eax, [DATA_START]
@@:
mov ebx, buffer
mov edi, ebx
call hd_read
cmp [hd_error], 0
jnz .notfound2
add ebx, 512
push eax
inc eax
dec dword [esp+4]
jnz @f
mov eax, [ebp+FAT.cluster_tmp]
test eax, eax
jz .done
call get_FAT
jc .notfound2
cmp eax, 2
jb .done
cmp eax, [ebp+FAT.fatRESERVED]
jae .done
push eax
mov eax, [ebp+FAT.SECTORS_PER_CLUSTER]
mov [esp+8], eax
pop eax
mov [ebp+FAT.cluster_tmp], eax
dec eax
dec eax
imul eax, [ebp+FAT.SECTORS_PER_CLUSTER]
add eax, [ebp+FAT.DATA_START]
@@:
lea ebx, [ebp+FAT.buffer]
mov edi, ebx
push eax
call fs_read32_sys
test eax, eax
pop eax
jnz .notfound2
add ebx, 512
push eax
.do_bdfe:
inc dword [edx+8] ; new file found
dec dword [esp+4]
jns .l2
dec ecx
js .l2
inc dword [edx+4] ; new file block copied
call fat_entry_to_bdfe
.l2:
add edi, 0x20
cmp edi, ebx
dec ecx
js .l2
inc dword [edx+4] ; new file block copied
push ebp
lea ebp, [esp+20]
call fat_entry_to_bdfe
pop ebp
.l2:
add edi, 0x20
cmp edi, ebx
jb .l1
pop eax
inc eax
dec dword [esp+4]
jnz .new_sector
mov eax, [cluster_tmp]
test eax, eax
jz .done
call get_FAT
cmp [hd_error], 0
jnz .notfound2
cmp eax, 2
jb .done
cmp eax, [fatRESERVED]
jae .done
push eax
mov eax, [SECTORS_PER_CLUSTER]
mov [esp+8], eax
pop eax
pop ebx
inc eax
dec dword [esp+4]
jnz .new_sector
mov eax, [ebp+FAT.cluster_tmp]
test eax, eax
jz .done
call get_FAT
jc .notfound2
cmp eax, 2
jb .done
cmp eax, [ebp+FAT.fatRESERVED]
jae .done
push eax
mov eax, [ebp+FAT.SECTORS_PER_CLUSTER]
mov [esp+8], eax
pop eax
pop ebx
add esp, 4
jmp .new_cluster
.notfound2:
add esp, 8
.notfound:
add esp, 262*2+4
pop ebp ecx esi edi
mov eax, ERROR_FILE_NOT_FOUND
or ebx, -1
ret
.done:
add esp, 262*2+4+8
pop ebp
mov ebx, [edx+4]
xor eax, eax
dec ecx
js @f
mov al, ERROR_END_OF_FILE
@@:
pop ecx esi edi
ret
 
fat16_root_next:
cmp edi, buffer+0x200-0x20
jae fat16_root_next_sector
add edi, 0x20
ret ; CF=0
fat16_root_next_sector:
; read next sector
push [longname_sec2]
pop [longname_sec1]
push ecx
mov ecx, [eax+4]
push ecx
add ecx, [ROOT_START]
mov [longname_sec2], ecx
pop ecx
inc ecx
mov [eax+4], ecx
cmp ecx, [ROOT_SECTORS]
pop ecx
jae fat16_root_first.readerr
fat16_root_first:
mov eax, [eax+4]
add eax, [ROOT_START]
push ebx
mov edi, buffer
mov ebx, edi
call hd_read
pop ebx
cmp [hd_error], 0
jnz .readerr
ret ; CF=0
.readerr:
stc
ret
fat16_root_begin_write:
push edi eax
call fat16_root_first
add esp, 8
.notfound:
add esp, 262*2+4
pop esi edi
mov ebx, [edx+4]
call fat_unlock
mov eax, ERROR_DEVICE
ret
.done:
add esp, 262*2+4+8
mov ebx, [edx+4]
xor eax, eax
dec ecx
js @f
mov al, ERROR_END_OF_FILE
@@:
push eax
call fat_unlock
pop eax
pop esi edi
ret
 
fat16_root_next:
push ecx
lea ecx, [ebp+FAT.buffer+0x200-0x20]
cmp edi, ecx
jae fat16_root_next_sector
pop ecx
add edi, 0x20
ret ; CF=0
fat16_root_next_sector:
; read next sector
push [ebp+FAT.longname_sec2]
pop [ebp+FAT.longname_sec1]
mov ecx, [eax+4]
push ecx
add ecx, [ebp+FAT.ROOT_START]
mov [ebp+FAT.longname_sec2], ecx
pop ecx
inc ecx
mov [eax+4], ecx
cmp ecx, [ebp+FAT.ROOT_SECTORS]
pop ecx
jb fat16_root_first
mov eax, ERROR_FILE_NOT_FOUND
stc
ret
fat16_root_first:
mov eax, [eax+4]
add eax, [ebp+FAT.ROOT_START]
push ebx
lea edi, [ebp+FAT.buffer]
mov ebx, edi
call fs_read32_sys
pop ebx
test eax, eax
jnz .readerr
ret ; CF=0
.readerr:
mov eax, ERROR_DEVICE
stc
ret
.notfound:
mov eax, ERROR_FILE_NOT_FOUND
stc
ret
fat16_root_begin_write:
push edi eax
call fat16_root_first
pop eax edi
ret
fat16_root_end_write:
pusha
mov eax, [eax+4]
add eax, [ROOT_START]
mov ebx, buffer
call hd_write
popa
ret
fat16_root_next_write:
cmp edi, buffer+0x200
jae @f
ret
@@:
call fat16_root_end_write
fat16_root_end_write:
pusha
mov eax, [eax+4]
add eax, [ebp+FAT.ROOT_START]
lea ebx, [ebp+FAT.buffer]
call fs_write32_sys
popa
ret
fat16_root_next_write:
push ecx
lea ecx, [ebp+FAT.buffer+0x200]
cmp edi, ecx
jae @f
pop ecx
ret
@@:
call fat16_root_end_write
jmp fat16_root_next_sector
fat16_root_extend_dir:
stc
ret
 
fat_notroot_next:
cmp edi, buffer+0x200-0x20
jae fat_notroot_next_sector
add edi, 0x20
ret ; CF=0
fat_notroot_next_sector:
push [longname_sec2]
pop [longname_sec1]
push eax
call fat_get_sector
mov [longname_sec2], eax
pop eax
push ecx
mov ecx, [eax+4]
inc ecx
cmp ecx, [SECTORS_PER_CLUSTER]
jae fat_notroot_next_cluster
mov [eax+4], ecx
jmp @f
ret
 
fat_notroot_next:
push ecx
lea ecx, [ebp+FAT.buffer+0x200-0x20]
cmp edi, ecx
jae fat_notroot_next_sector
pop ecx
add edi, 0x20
ret ; CF=0
fat_notroot_next_sector:
push [ebp+FAT.longname_sec2]
pop [ebp+FAT.longname_sec1]
push eax
call fat_get_sector
mov [ebp+FAT.longname_sec2], eax
pop eax
mov ecx, [eax+4]
inc ecx
cmp ecx, [ebp+FAT.SECTORS_PER_CLUSTER]
jae fat_notroot_next_cluster
mov [eax+4], ecx
jmp @f
fat_notroot_next_cluster:
push eax
mov eax, [eax]
call get_FAT
mov ecx, eax
pop eax
cmp [hd_error], 0
jnz fat_notroot_next_err
cmp ecx, [fatRESERVED]
jae fat_notroot_next_err
mov [eax], ecx
and dword [eax+4], 0
call get_FAT
mov ecx, eax
pop eax
jc fat_notroot_first.deverr
cmp ecx, 2
jb fat_notroot_next_err
cmp ecx, [ebp+FAT.fatRESERVED]
jae fat_notroot_next_err
mov [eax], ecx
and dword [eax+4], 0
@@:
pop ecx
fat_notroot_first:
call fat_get_sector
push ebx
mov edi, buffer
mov ebx, edi
call hd_read
pop ebx
cmp [hd_error], 0
jnz @f
ret ; CF=0
fat_notroot_next_err:
pop ecx
@@:
stc
ret
fat_notroot_begin_write:
fat_notroot_first:
call fat_get_sector
push ebx
lea edi, [ebp+FAT.buffer]
mov ebx, edi
call fs_read32_sys
pop ebx
test eax, eax
jz .ret ; CF=0
push ecx
.deverr:
pop ecx
mov eax, ERROR_DEVICE
stc
.ret:
ret
fat_notroot_next_err:
pop ecx
mov eax, ERROR_FILE_NOT_FOUND
stc
ret
fat_notroot_begin_write:
push eax edi
call fat_notroot_first
pop edi eax
ret
fat_notroot_end_write:
call fat_get_sector
push ebx
mov ebx, buffer
call hd_write
pop ebx
ret
fat_notroot_next_write:
cmp edi, buffer+0x200
jae @f
ret
@@:
push eax
fat_notroot_end_write:
call fat_get_sector
push ebx
lea ebx, [ebp+FAT.buffer]
call fs_write32_sys
pop ebx
ret
fat_notroot_next_write:
push ecx
lea ecx, [ebp+FAT.buffer+0x200]
cmp edi, ecx
jae @f
pop ecx
ret
@@:
push eax
call fat_notroot_end_write
pop eax
jmp fat_notroot_next_sector
1502,33 → 1317,34
call get_free_FAT
jnc .found
pop eax
ret ; CF=1
.found:
push edx
mov edx, [fatEND]
call set_FAT
mov edx, eax
mov eax, [esp+4]
mov eax, [eax]
push edx
call set_FAT
pop edx
cmp [hd_error], 0
jz @f
pop edx
pop eax
stc
ret ; CF=1
.found:
push edx
mov edx, [ebp+FAT.fatEND]
call set_FAT
jc .writeerr
mov edx, eax
mov eax, [esp+4]
mov eax, [eax]
push edx
call set_FAT
pop edx
jnc @f
.writeerr:
pop edx
pop eax
stc
ret
@@:
push ecx
or ecx, -1
call add_disk_free_space
; zero new cluster
mov ecx, 512/4
mov edi, buffer
push edi
xor eax, eax
rep stosd
call add_disk_free_space
; zero new cluster
mov ecx, 512/4
lea edi, [ebp+FAT.buffer]
push edi
xor eax, eax
rep stosd
pop edi
pop ecx
mov eax, [esp+4]
1536,180 → 1352,225
and dword [eax+4], 0
pop edx
mov eax, [eax]
dec eax
dec eax
push ebx ecx
mov ecx, [SECTORS_PER_CLUSTER]
imul eax, ecx
add eax, [DATA_START]
mov ebx, edi
@@:
call hd_write
inc eax
loop @b
pop ecx ebx eax
dec eax
dec eax
push ebx ecx
mov ecx, [ebp+FAT.SECTORS_PER_CLUSTER]
imul eax, ecx
add eax, [ebp+FAT.DATA_START]
mov ebx, edi
@@:
push eax
call fs_write32_sys
pop eax
inc eax
loop @b
pop ecx ebx eax
clc
ret
 
fat_get_sector:
push ecx
mov ecx, [eax]
dec ecx
dec ecx
imul ecx, [SECTORS_PER_CLUSTER]
add ecx, [DATA_START]
add ecx, [eax+4]
mov eax, ecx
pop ecx
mov ecx, [eax]
dec ecx
dec ecx
imul ecx, [ebp+FAT.SECTORS_PER_CLUSTER]
add ecx, [ebp+FAT.DATA_START]
add ecx, [eax+4]
mov eax, ecx
pop ecx
ret
 
;----------------------------------------------------------------
;
; fs_HdRewrite - LFN variant for writing hard disk
;
; esi points to filename
; ebx ignored (reserved)
; ecx number of bytes to write, 0+
;
; fs_HdRewrite - LFN variant for writing hard disk
;
; Obsolete, will be replaced with filesystem-specific functions.
;
; esi points to filename
; ebx ignored (reserved)
; ecx number of bytes to write, 0+
; edx mem location to data
;
; ret ebx = number of written bytes
; eax = 0 ok read or other = errormsg
;
;--------------------------------------------------------------
fshrad:
mov eax, ERROR_ACCESS_DENIED
xor ebx, ebx
ret
fshrfs:
mov eax, ERROR_UNKNOWN_FS
xor ebx, ebx
ret
; eax = 0 ok read or other = errormsg
;
;--------------------------------------------------------------
fs_HdCreateFolder:
mov al, 1
jmp fs_HdRewrite.common
 
fs_HdCreateFolder:
mov al, 1
jmp fs_HdRewrite.common
 
fs_HdRewrite:
xor eax, eax
.common:
cmp [fs_type], 1
jz ntfs_HdRewrite
cmp [fs_type], 2
jz ext2_HdRewrite
cmp [fs_type], 16
fs_HdRewrite:
xor eax, eax
.common:
cmp [fs_type], 16
jz @f
cmp [fs_type], 32
jz @f
cmp [fs_type], 1
jz ntfs_HdRewrite
cmp [fs_type], 2
jz ext2_HdRewrite
mov eax, ERROR_UNKNOWN_FS
xor ebx, ebx
ret
@@:
sub ebx, 4
push ebp
mov ebp, [fs_dependent_data_start.partition]
test eax, eax
mov eax, fat_CreateFolder
jnz @f
mov eax, fat_Rewrite
@@:
call eax
pop ebp
ret
 
fshrad:
call fat_unlock
mov eax, ERROR_ACCESS_DENIED
xor ebx, ebx
ret
 
;----------------------------------------------------------------
; fat_CreateFolder - FAT16/32 implementation of creating a folder
; 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
;----------------------------------------------------------------
fat_CreateFolder:
push 1
jmp fat_Rewrite.common
 
;----------------------------------------------------------------
; fat_HdRewrite - FAT16/32 implementation of creating a new 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
;----------------------------------------------------------------
fat_Rewrite:
push 0
.common:
call fat_lock
pop eax
cmp byte [esi], 0
jz fshrad
mov ecx, [ebx+12]
mov edx, [ebx+16]
pushad
xor edi, edi
mov edx, [esp+4+20h]
push esi
test edx, edx
jz @f
mov esi, edx
@@:
lodsb
test al, al
jz @f
cmp [fs_type], 32
jnz fshrfs
@@:
cmp byte [esi], 0
jz fshrad
pushad
xor edi, edi
push esi
test ebp, ebp
jz @f
mov esi, ebp
@@:
lodsb
test al, al
jz @f
cmp al, '/'
jnz @b
lea edi, [esi-1]
jmp @b
@@:
pop esi
test edi, edi
jnz .noroot
test ebp, ebp
jnz .hasebp
mov ebp, [ROOT_CLUSTER]
cmp [fs_type], 32
jz .pushnotroot
push fat16_root_extend_dir
push fat16_root_end_write
push fat16_root_next_write
push fat16_root_begin_write
xor ebp, ebp
push ebp
push ebp
push fat16_root_first
push fat16_root_next
jmp .common1
.hasebp:
mov eax, ERROR_ACCESS_DENIED
cmp byte [ebp], 0
jz .ret1
push ebp
xor ebp, ebp
call hd_find_lfn
pop esi
jc .notfound0
jmp .common0
.noroot:
mov eax, ERROR_ACCESS_DENIED
pop esi
test edi, edi
jnz .noroot
test edx, edx
jnz .hasebp
mov edx, [ebp+FAT.ROOT_CLUSTER]
cmp [ebp+FAT.fs_type], 32
jz .pushnotroot
xor edx, edx
push edx
push fat16_root_extend_dir
push fat16_root_end_write
push fat16_root_next_write
push fat16_root_begin_write
push edx
push edx
push fat16_root_first
push fat16_root_next
jmp .common1
.hasebp:
mov eax, ERROR_ACCESS_DENIED
cmp byte [edx], 0
jz .ret1
stdcall hd_find_lfn, 0
mov esi, [esp+4+20h]
jc .ret1
jmp .common0
.noroot:
mov eax, ERROR_ACCESS_DENIED
cmp byte [edi+1], 0
jz .ret1
; check existence
mov byte [edi], 0
push edi
call hd_find_lfn
pop esi
mov byte [esi], '/'
jnc @f
; check existence
mov byte [edi], 0
push edi
stdcall hd_find_lfn, [esp+4+24h]
pop esi
mov byte [esi], '/'
jnc @f
.notfound0:
mov eax, ERROR_FILE_NOT_FOUND
.ret1:
mov [esp+28], eax
popad
xor ebx, ebx
ret
mov eax, ERROR_FILE_NOT_FOUND
.ret1:
mov [esp+28], eax
call fat_unlock
popad
xor ebx, ebx
ret
@@:
inc esi
.common0:
test byte [edi+11], 0x10 ; must be directory
mov eax, ERROR_ACCESS_DENIED
jz .ret1
mov ebp, [edi+20-2]
mov bp, [edi+26] ; ebp=cluster
mov eax, ERROR_FAT_TABLE
cmp ebp, 2
jb .ret1
.pushnotroot:
push fat_notroot_extend_dir
push fat_notroot_end_write
push fat_notroot_next_write
push fat_notroot_begin_write
push 0
push ebp
push fat_notroot_first
push fat_notroot_next
.common1:
test byte [edi+11], 0x10 ; must be directory
mov eax, ERROR_ACCESS_DENIED
jz .ret1
mov edx, [edi+20-2]
mov dx, [edi+26] ; ebp=cluster
mov eax, ERROR_FAT_TABLE
cmp edx, 2
jb .ret1
.pushnotroot:
push edx
push fat_notroot_extend_dir
push fat_notroot_end_write
push fat_notroot_next_write
push fat_notroot_begin_write
push 0
push edx
push fat_notroot_first
push fat_notroot_next
.common1:
call fat_find_lfn
jc .notfound
; found
test byte [edi+11], 10h
jz .exists_file
; found directory; if we are creating directory, return OK,
; if we are creating file, say "access denied"
add esp, 32
popad
test al, al
mov eax, ERROR_ACCESS_DENIED
jz .exists_file
; found directory; if we are creating directory, return OK,
; if we are creating file, say "access denied"
add esp, 36
call fat_unlock
popad
test al, al
mov eax, ERROR_ACCESS_DENIED
jz @f
mov al, 0
@@:
xor ebx, ebx
ret
.exists_file:
; found file; if we are creating directory, return "access denied",
; if we are creating file, delete existing file and continue
cmp byte [esp+32+28], 0
jz @f
add esp, 32
popad
mov eax, ERROR_ACCESS_DENIED
xor ebx, ebx
.exists_file:
; found file; if we are creating directory, return "access denied",
; if we are creating file, delete existing file and continue
cmp byte [esp+36+28], 0
jz @f
add esp, 36
call fat_unlock
popad
mov eax, ERROR_ACCESS_DENIED
xor ebx, ebx
ret
@@:
; delete FAT chain
1721,19 → 1582,20
mov ax, [edi+26]
mov word [edi+20], cx
mov word [edi+26], cx
test eax, eax
jz .done1
@@:
cmp eax, [fatRESERVED]
jae .done1
push edx
xor edx, edx
call set_FAT
mov eax, edx
pop edx
inc ecx
jmp @b
.done1:
test eax, eax
jz .done1
@@:
cmp eax, [ebp+FAT.fatRESERVED]
jae .done1
push edx
xor edx, edx
call set_FAT
mov eax, edx
pop edx
jc .done1
inc ecx
jmp @b
.done1:
pop edi
call get_time_for_file
mov [edi+22], ax
1743,13 → 1605,14
or byte [edi+11], 20h ; set 'archive' attribute
jmp .doit
.notfound:
; file is not found; generate short name
call fat_name_is_legal
jc @f
add esp, 32
popad
mov eax, ERROR_FILE_NOT_FOUND
xor ebx, ebx
; file is not found; generate short name
call fat_name_is_legal
jc @f
add esp, 36
call fat_unlock
popad
mov eax, ERROR_FILE_NOT_FOUND
xor ebx, ebx
ret
@@:
sub esp, 12
1756,13 → 1619,14
mov edi, esp
call fat_gen_short_name
.test_short_name_loop:
push esi edi ecx
mov esi, edi
lea eax, [esp+12+12+8]
mov [eax], ebp
and dword [eax+4], 0
call dword [eax-4]
jc .found
push esi edi ecx
mov esi, edi
lea eax, [esp+12+12+8]
mov edx, [eax+24]
mov [eax], edx
and dword [eax+4], 0
call dword [eax-4]
jc .found
.test_short_name_entry:
cmp byte [edi+11], 0xF
jz .test_short_name_cont
1778,13 → 1642,14
jmp .found
.short_name_found:
pop ecx edi esi
call fat_next_short_name
jnc .test_short_name_loop
.disk_full:
add esp, 12+32
popa
mov eax, ERROR_DISK_FULL
xor ebx, ebx
call fat_next_short_name
jnc .test_short_name_loop
.disk_full:
add esp, 12+36
call fat_unlock
popa
mov eax, ERROR_DISK_FULL
xor ebx, ebx
ret
.found:
pop ecx edi esi
1818,21 → 1683,23
push -1
push -1
; find <eax> successive entries in directory
xor ecx, ecx
push eax
lea eax, [esp+16+8+12+8]
mov [eax], ebp
and dword [eax+4], 0
call dword [eax-4]
pop eax
jnc .scan_dir
.fsfrfe3:
add esp, 12+8+12+32
popad
mov eax, 11
xor ebx, ebx
ret
.scan_dir:
xor ecx, ecx
push eax
lea eax, [esp+16+8+12+8]
mov edx, [eax+24]
mov [eax], edx
and dword [eax+4], 0
call dword [eax-4]
pop eax
jnc .scan_dir
.fsfrfe3:
add esp, 12+8+12+36
call fat_unlock
popad
mov eax, ERROR_DEVICE
xor ebx, ebx
ret
.scan_dir:
cmp byte [edi], 0
jz .free
cmp byte [edi], 0xE5
1839,22 → 1706,24
jz .free
xor ecx, ecx
.scan_cont:
push eax
lea eax, [esp+16+8+12+8]
call dword [eax-8]
pop eax
jnc .scan_dir
cmp [hd_error], 0
jnz .fsfrfe3
push eax
lea eax, [esp+16+8+12+8]
call dword [eax+20] ; extend directory
pop eax
jnc .scan_dir
add esp, 12+8+12+32
popad
mov eax, ERROR_DISK_FULL
xor ebx, ebx
push eax
lea eax, [esp+16+8+12+8]
call dword [eax-8]
mov edx, eax
pop eax
jnc .scan_dir
cmp edx, ERROR_DEVICE
jz .fsfrfe3
push eax
lea eax, [esp+16+8+12+8]
call dword [eax+20] ; extend directory
pop eax
jnc .scan_dir
add esp, 12+8+12+36
call fat_unlock
popad
mov eax, ERROR_DISK_FULL
xor ebx, ebx
ret
.free:
test ecx, ecx
1867,14 → 1736,29
xor ecx, ecx
@@:
inc ecx
cmp ecx, eax
jb .scan_cont
; found!
; calculate name checksum
push esi ecx
mov esi, [esp+8+12]
mov ecx, 11
xor eax, eax
cmp ecx, eax
jb .scan_cont
; found!
push esi ecx
; If creating a directory, allocate one data cluster now and fail immediately
; if this is impossible. This prevents from creating an invalid directory entry
; on a full disk.
; yup, the argument is quite non-intuitive... but what should I do if
; the entire function uses such arguments? BTW, it refers to al from pushad,
; which in turn is filled with 0 in fat_Rewrite and 1 in fat_CreateFolder.
cmp byte [esp+8+12+8+12+36+28], 0
jz .no.preallocate.folder.data
call get_free_FAT
jnc @f
add esp, 8+12+8
jmp .disk_full
@@:
mov [esp+8+12+8+12+36+20], eax ; store the cluster somewhere
.no.preallocate.folder.data:
; calculate name checksum
mov esi, [esp+8+12]
mov ecx, 11
xor eax, eax
@@:
ror al, 1
add al, [esi]
1938,147 → 1822,154
mov [edi+24], ax ; last write date
mov [edi+18], ax ; last access date
xor ecx, ecx
mov word [edi+20], cx ; high word of cluster
mov word [edi+26], cx ; low word of cluster - to be filled
mov dword [edi+28], ecx ; file size - to be filled
cmp byte [esp+32+28], cl
jz .doit
; create directory
mov byte [edi+11], 10h ; attributes: folder
mov edx, edi
lea eax, [esp+8]
call dword [eax+16] ; flush directory
push ecx
mov ecx, [SECTORS_PER_CLUSTER]
shl ecx, 9
jmp .doit2
.doit:
lea eax, [esp+8]
call dword [eax+16] ; flush directory
push ecx
mov ecx, [esp+4+32+24]
.doit2:
push ecx
push edi
mov esi, edx
test ecx, ecx
jz .done
call get_free_FAT
jc .diskfull
push eax
mov [edi+26], ax
shr eax, 16
mov word [edi+20], cx ; high word of cluster
mov word [edi+26], cx ; low word of cluster - to be filled
mov dword [edi+28], ecx ; file size - to be filled
cmp byte [esp+36+28], cl
jz .doit
; create directory
mov byte [edi+11], 10h ; attributes: folder
mov esi, edi
lea eax, [esp+8]
call dword [eax+16] ; flush directory
mov eax, [esp+36+20] ; extract saved cluster
mov [esp+36+20], edi ; this is needed for calculating arg of add_disk_free_space!
push ecx
mov ecx, [ebp+FAT.SECTORS_PER_CLUSTER]
shl ecx, 9
push ecx
push edi
jmp .doit2
.doit:
mov esi, [esp+36+20]
lea eax, [esp+8]
call dword [eax+16] ; flush directory
push ecx
mov ecx, [esp+4+36+24]
push ecx
push edi
test ecx, ecx
jz .done
call get_free_FAT
jc .diskfull
.doit2:
push eax
mov [edi+26], ax
shr eax, 16
mov [edi+20], ax
lea eax, [esp+16+8]
call dword [eax+16] ; flush directory
pop eax
push edx
mov edx, [fatEND]
call set_FAT
pop edx
.write_cluster:
push eax
dec eax
dec eax
mov ebp, [SECTORS_PER_CLUSTER]
imul eax, ebp
add eax, [DATA_START]
; write data
.write_sector:
cmp byte [esp+16+32+28], 0
jnz .writedir
mov ecx, 512
cmp dword [esp+8], ecx
jb .writeshort
; we can write directly from given buffer
mov ebx, esi
add esi, ecx
jmp .writecommon
.writeshort:
mov ecx, [esp+8]
push ecx
mov edi, buffer
mov ebx, edi
rep movsb
.writedircont:
mov ecx, buffer+0x200
sub ecx, edi
push eax
xor eax, eax
call dword [eax+16] ; flush directory
pop eax
push edx
mov edx, [ebp+FAT.fatEND]
call set_FAT
pop edx
.write_cluster:
push eax
dec eax
dec eax
imul eax, [ebp+FAT.SECTORS_PER_CLUSTER]
add eax, [ebp+FAT.DATA_START]
push [ebp+FAT.SECTORS_PER_CLUSTER]
; write data
.write_sector:
cmp byte [esp+20+36+28], 0
jnz .writedir
mov ecx, 512
cmp dword [esp+12], ecx
jb .writeshort
; we can write directly from given buffer
mov ebx, esi
add esi, ecx
jmp .writecommon
.writeshort:
mov ecx, [esp+12]
push ecx
lea edi, [ebp+FAT.buffer]
mov ebx, edi
rep movsb
.writedircont:
lea ecx, [ebp+FAT.buffer+0x200]
sub ecx, edi
push eax
xor eax, eax
rep stosb
pop eax
pop ecx
.writecommon:
call hd_write
cmp [hd_error], 0
jnz .writeerr
inc eax
sub dword [esp+8], ecx
jz .writedone
dec ebp
jnz .write_sector
; allocate new cluster
pop eax
mov ecx, eax
call get_free_FAT
jc .diskfull
push edx
mov edx, [fatEND]
pop eax
pop ecx
.writecommon:
push eax
call fs_write32_app
test eax, eax
pop eax
jnz .writeerr
inc eax
sub dword [esp+12], ecx
jz .writedone
dec dword [esp]
jnz .write_sector
pop eax
; allocate new cluster
pop eax
mov ecx, eax
call get_free_FAT
jc .diskfull
push edx
mov edx, [ebp+FAT.fatEND]
call set_FAT
xchg eax, ecx
mov edx, ecx
call set_FAT
xchg eax, ecx
mov edx, ecx
call set_FAT
pop edx
xchg eax, ecx
jmp .write_cluster
.diskfull:
mov eax, ERROR_DISK_FULL
jmp .ret
.writeerr:
pop eax
sub esi, ecx
mov eax, 11
jmp .ret
.writedone:
pop eax
.done:
xor eax, eax
.ret:
pop edi ecx
mov ebx, esi
sub ebx, edx
pop ebp
mov [esp+32+28], eax
lea eax, [esp+8]
call dword [eax+8]
mov [edi+28], ebx
call dword [eax+16]
mov [esp+32+16], ebx
lea eax, [ebx+511]
shr eax, 9
mov ecx, [SECTORS_PER_CLUSTER]
lea eax, [eax+ecx-1]
xor edx, edx
div ecx
mov ecx, ebp
sub ecx, eax
call add_disk_free_space
add esp, 32
call update_disk
popad
ret
.writedir:
push 512
mov edi, buffer
mov ebx, edi
mov ecx, [SECTORS_PER_CLUSTER]
shl ecx, 9
cmp ecx, [esp+12]
jnz .writedircont
dec dword [esp+16]
push esi
mov ecx, 32/4
rep movsd
mov eax, ERROR_DISK_FULL
jmp .ret
.writeerr:
pop eax eax
sub esi, ecx
mov eax, ERROR_DEVICE
jmp .ret
.writedone:
pop eax eax
.done:
xor eax, eax
.ret:
pop edi ecx
sub esi, [esp+4+36+20]
mov [esp+4+36+28], eax
mov [esp+4+36+16], esi
lea eax, [esp+12]
call dword [eax+8]
mov [edi+28], esi
call dword [eax+16]
mov [esp+36+16], ebx
lea eax, [esi+511]
shr eax, 9
mov ecx, [ebp+FAT.SECTORS_PER_CLUSTER]
lea eax, [eax+ecx-1]
xor edx, edx
div ecx
pop ecx
sub ecx, eax
call add_disk_free_space
add esp, 36
call update_disk
call fat_unlock
popad
ret
.writedir:
push 512
lea edi, [ebp+FAT.buffer]
mov ebx, edi
mov ecx, [ebp+FAT.SECTORS_PER_CLUSTER]
shl ecx, 9
cmp ecx, [esp+16]
jnz .writedircont
dec dword [esp+20]
push esi
mov ecx, 32/4
rep movsd
pop esi
mov dword [edi-32], '. '
mov dword [edi-32+4], ' '
2089,14 → 1980,14
rep movsd
pop esi
mov dword [edi-32], '.. '
mov dword [edi-32+4], ' '
mov dword [edi-32+8], ' '
mov byte [edi-32+11], 10h
mov ecx, [esp+20+8]
cmp ecx, [ROOT_CLUSTER]
jnz @f
xor ecx, ecx
@@:
mov dword [edi-32+4], ' '
mov dword [edi-32+8], ' '
mov byte [edi-32+11], 10h
mov ecx, [esp+20+36]
cmp ecx, [ebp+FAT.ROOT_CLUSTER]
jnz @f
xor ecx, ecx
@@:
mov word [edi-32+26], cx
shr ecx, 16
mov [edi-32+20], cx
2103,81 → 1994,92
jmp .writedircont
 
;----------------------------------------------------------------
;
; fs_HdWrite - LFN variant for writing to hard disk
;
; esi points to filename
; ebx pointer to 64-bit number = first wanted byte, 0+
; may be ebx=0 - start from first byte
;
; fs_HdWrite - LFN variant for writing to hard disk
;
; Obsolete, will be replaced with filesystem-specific functions.
;
; esi points to filename
; ebx pointer to 64-bit number = first wanted byte, 0+
; may be ebx=0 - start from first byte
; ecx number of bytes to write, 0+
; edx mem location to data
;
; ret ebx = bytes written (maybe 0)
; eax = 0 ok write or other = errormsg
;
;--------------------------------------------------------------
fs_HdWrite.access_denied:
push ERROR_ACCESS_DENIED
fs_HdWrite.ret0:
pop eax
; eax = 0 ok write or other = errormsg
;
;--------------------------------------------------------------
fat_Write.access_denied:
push ERROR_ACCESS_DENIED
fs_HdWrite.ret0:
pop eax
xor ebx, ebx
ret
 
fs_HdWrite.ret11:
push 11
jmp fs_HdWrite.ret0
 
fs_HdWrite:
cmp [fs_type], 1
jz ntfs_HdWrite
cmp [fs_type], 2
jz ext2_HdWrite
cmp [fs_type], 16
jz @f
cmp [fs_type], 32
jz @f
push ERROR_UNKNOWN_FS
jmp .ret0
@@:
cmp byte [esi], 0
jz .access_denied
pushad
call hd_find_lfn
pushfd
cmp [hd_error], 0
jz @f
popfd
popad
push 11
jmp .ret0
@@:
popfd
jnc .found
popad
push ERROR_FILE_NOT_FOUND
jmp .ret0
.found:
; FAT does not support files larger than 4GB
test ebx, ebx
jz .l1
cmp dword [ebx+4], 0
jz @f
.eof:
popad
push ERROR_END_OF_FILE
jmp .ret0
@@:
mov ebx, [ebx]
.l1:
; now edi points to direntry, ebx=start byte to write,
; ecx=number of bytes to write, edx=data pointer
 
; extend file if needed
add ecx, ebx
jc .eof ; FAT does not support files larger than 4GB
push eax ; save directory sector
push 0 ; return value=0
 
ret
 
fs_HdWrite.ret11:
push ERROR_DEVICE
jmp fs_HdWrite.ret0
 
fs_HdWrite:
cmp [fs_type], 16
jz @f
cmp [fs_type], 32
jz @f
cmp [fs_type], 1
jz ntfs_HdWrite
cmp [fs_type], 2
jz ext2_HdWrite
push ERROR_UNKNOWN_FS
jmp .ret0
@@:
sub ebx, 4
push ebp
mov ebp, [fs_dependent_data_start.partition]
call fat_Write
pop ebp
ret
 
;----------------------------------------------------------------
; fat_Write - FAT16/32 implementation of writing to 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
;----------------------------------------------------------------
fat_Write:
cmp byte [esi], 0
jz .access_denied
call fat_lock
push edi
stdcall hd_find_lfn, [esp+4+4]
jnc .found
pop edi
push eax
call fat_unlock
jmp fs_HdWrite.ret0
.found:
; FAT does not support files larger than 4GB
cmp dword [ebx+8], 0
jz @f
.eof:
pop edi
push ERROR_END_OF_FILE
call fat_unlock
jmp fs_HdWrite.ret0
@@:
mov ecx, [ebx+12]
mov edx, [ebx+16]
mov ebx, [ebx+4]
; now edi points to direntry, ebx=start byte to write,
; ecx=number of bytes to write, edx=data pointer
 
; extend file if needed
add ecx, ebx
jc .eof ; FAT does not support files larger than 4GB
push edx
push eax ; save directory sector
push 0 ; return value=0
 
call get_time_for_file
mov [edi+22], ax ; last write time
call get_date_for_file
2193,63 → 2095,70
jnc .length_ok
mov [esp+4], eax
; hd_extend_file can return three error codes: FAT table error, device error or disk full.
; First two cases are fatal errors, in third case we may write some data
cmp al, ERROR_DISK_FULL
jz .disk_full
pop eax
pop eax
mov [esp+4+28], eax
pop eax
popad
xor ebx, ebx
ret
.disk_full:
; First two cases are fatal errors, in third case we may write some data
cmp al, ERROR_DISK_FULL
jz .disk_full
call fat_unlock
pop eax
pop eax
pop ecx
pop edx
pop edi
xor ebx, ebx
ret
.disk_full:
; correct number of bytes to write
mov ecx, [edi+28]
cmp ecx, ebx
ja .length_ok
.ret:
call update_disk
cmp [hd_error], 0
jz @f
mov byte [esp+4], 11
@@:
pop eax
pop eax
mov [esp+4+28], eax ; eax=return value
pop eax
sub edx, [esp+20]
mov [esp+16], edx ; ebx=number of written bytes
popad
ret
.length_ok:
mov esi, [edi+28]
mov eax, [edi+20-2]
mov ax, [edi+26]
mov edi, eax ; edi=current cluster
xor ebp, ebp ; ebp=current sector in cluster
; save directory
mov eax, [esp+8]
push ebx
mov ebx, buffer
call hd_write
pop ebx
cmp [hd_error], 0
jz @f
.device_err:
mov byte [esp+4], 11
jmp .ret
@@:
 
; now ebx=start pos, ecx=end pos, both lie inside file
mov ecx, [edi+28]
cmp ecx, ebx
ja .length_ok
push 0
.ret:
pop eax
sub edx, [esp+12]
mov ebx, edx ; ebx=number of written bytes
call update_disk
test eax, eax
jz @f
mov byte [esp+4], ERROR_DEVICE
@@:
call fat_unlock
pop eax
pop eax
pop ecx
pop edx
pop edi
ret
.length_ok:
mov esi, [edi+28]
mov eax, [edi+20-2]
mov ax, [edi+26]
mov edi, eax ; edi=current cluster
push 0 ; current sector in cluster
; save directory
mov eax, [esp+12]
push ebx
lea ebx, [ebp+FAT.buffer]
call fs_write32_sys
pop ebx
test eax, eax
jz @f
.device_err:
mov byte [esp+8], ERROR_DEVICE
jmp .ret
.fat_err:
mov byte [esp+8], ERROR_FAT_TABLE
jmp .ret
@@:
 
; now ebx=start pos, ecx=end pos, both lie inside file
sub ecx, ebx
jz .ret
.write_loop:
; skip unmodified sectors
cmp dword [esp], 0x200
jb .modify
sub ebx, 0x200
jae .skip
jz .ret
.write_loop:
; skip unmodified sectors
cmp dword [esp+4], 0x200
jb .modify
sub ebx, 0x200
jae .skip
add ebx, 0x200
.modify:
; get length of data in current sector
2266,145 → 2175,147
mov ecx, ebx
@@:
; get current sector number
mov eax, edi
dec eax
dec eax
imul eax, [SECTORS_PER_CLUSTER]
add eax, [DATA_START]
add eax, ebp
; load sector if needed
cmp dword [esp+4], 0 ; we don't need to read uninitialized data
jz .noread
cmp ecx, 0x200 ; we don't need to read sector if it is fully rewritten
jz .noread
cmp ecx, esi ; (same for the last sector)
jz .noread
push ebx
mov ebx, buffer
call hd_read
pop ebx
cmp [hd_error], 0
jz @f
.device_err2:
pop ecx
mov eax, edi
dec eax
dec eax
imul eax, [ebp+FAT.SECTORS_PER_CLUSTER]
add eax, [ebp+FAT.DATA_START]
add eax, [esp+4]
; load sector if needed
cmp dword [esp+8], 0 ; we don't need to read uninitialized data
jz .noread
cmp ecx, 0x200 ; we don't need to read sector if it is fully rewritten
jz .noread
cmp ecx, esi ; (same for the last sector)
jz .noread
push eax ebx
lea ebx, [ebp+FAT.buffer]
call fs_read32_app
test eax, eax
pop ebx eax
jz @f
.device_err2:
pop ecx
jmp .device_err
@@:
.noread:
; zero uninitialized data if file was extended (because hd_extend_file does not this)
push eax ecx edi
xor eax, eax
mov ecx, 0x200
sub ecx, [esp+4+12]
jbe @f
mov edi, buffer
add edi, [esp+4+12]
rep stosb
@@:
; zero uninitialized data in the last sector
mov ecx, 0x200
sub ecx, esi
jbe @f
mov edi, buffer
add edi, esi
rep stosb
@@:
pop edi ecx
push eax ecx edi
xor eax, eax
mov ecx, 0x200
sub ecx, [esp+8+12]
jbe @f
lea edi, [ebp+FAT.buffer]
add edi, [esp+8+12]
rep stosb
@@:
; zero uninitialized data in the last sector
mov ecx, 0x200
sub ecx, esi
jbe @f
lea edi, [ebp+FAT.buffer+esi]
rep stosb
@@:
pop edi ecx
; copy new data
mov eax, edx
neg ebx
jecxz @f
add ebx, buffer+0x200
call memmove
xor ebx, ebx
@@:
pop eax
; save sector
push ebx
mov ebx, buffer
call hd_write
pop ebx
cmp [hd_error], 0
jnz .device_err2
add edx, ecx
sub [esp], ecx
mov eax, edx
neg ebx
jecxz @f
lea ebx, [ebp+FAT.buffer+0x200+ebx]
call memmove
xor ebx, ebx
@@:
pop eax
; save sector
push ebx
lea ebx, [ebp+FAT.buffer]
call fs_write32_app
pop ebx
test eax, eax
jnz .device_err2
add edx, ecx
sub [esp], ecx
pop ecx
jz .ret
.skip:
; next sector
inc ebp
cmp ebp, [SECTORS_PER_CLUSTER]
jb @f
xor ebp, ebp
mov eax, edi
call get_FAT
mov edi, eax
cmp [hd_error], 0
jnz .device_err
@@:
sub esi, 0x200
jae @f
xor esi, esi
@@:
sub dword [esp], 0x200
jae @f
and dword [esp], 0
@@:
jmp .write_loop
 
jz .ret
.skip:
; next sector
pop eax
inc eax
push eax
cmp eax, [ebp+FAT.SECTORS_PER_CLUSTER]
jb @f
and dword [esp], 0
mov eax, edi
call get_FAT
mov edi, eax
jc .device_err
cmp edi, 2
jb .fat_err
cmp edi, [ebp+FAT.fatRESERVED]
jae .fat_err
@@:
sub esi, 0x200
jae @f
xor esi, esi
@@:
sub dword [esp+4], 0x200
jae @f
and dword [esp+4], 0
@@:
jmp .write_loop
 
hd_extend_file.zero_size:
xor eax, eax
jmp hd_extend_file.start_extend
 
; extends file on hd to given size (new data area is undefined)
; in: edi->direntry, ecx=new size
; out: CF=0 => OK, eax=0
; CF=1 => error, eax=code (ERROR_FAT_TABLE or ERROR_DISK_FULL or 11)
hd_extend_file:
push ebp
mov ebp, [SECTORS_PER_CLUSTER]
imul ebp, [BYTES_PER_SECTOR]
push ecx
; find the last cluster of file
mov eax, [edi+20-2]
; extends file on hd to given size (new data area is undefined)
; in: edi->direntry, ecx=new size
; out: CF=0 => OK, eax=0
; CF=1 => error, eax=code (ERROR_FAT_TABLE or ERROR_DISK_FULL or ERROR_DEVICE)
hd_extend_file:
push esi
mov esi, [ebp+FAT.SECTORS_PER_CLUSTER]
imul esi, [ebp+FAT.BYTES_PER_SECTOR]
push ecx
; find the last cluster of file
mov eax, [edi+20-2]
mov ax, [edi+26]
mov ecx, [edi+28]
jecxz .zero_size
.last_loop:
sub ecx, ebp
jbe .last_found
call get_FAT
cmp [hd_error], 0
jz @f
.device_err:
pop ecx
.device_err2:
pop ebp
push 11
.ret_err:
pop eax
stc
mov ecx, [edi+28]
jecxz .zero_size
.last_loop:
sub ecx, esi
jbe .last_found
call get_FAT
jnc @f
.device_err:
pop ecx
.device_err2:
pop esi
push ERROR_DEVICE
.ret_err:
pop eax
stc
ret
@@:
cmp eax, 2
jb .fat_err
cmp eax, [fatRESERVED]
jb .last_loop
.fat_err:
pop ecx ebp
push ERROR_FAT_TABLE
jmp .ret_err
.last_found:
push eax
call get_FAT
cmp [hd_error], 0
jz @f
pop eax
jmp .device_err
@@:
cmp eax, [fatRESERVED]
pop eax
jb .fat_err
; set length to full number of clusters
@@:
cmp eax, 2
jb .fat_err
cmp eax, [ebp+FAT.fatRESERVED]
jb .last_loop
.fat_err:
pop ecx esi
push ERROR_FAT_TABLE
jmp .ret_err
.last_found:
push eax
call get_FAT
jnc @f
pop eax
jmp .device_err
@@:
cmp eax, [ebp+FAT.fatRESERVED]
pop eax
jb .fat_err
; set length to full number of clusters
sub [edi+28], ecx
.start_extend:
pop ecx
2415,13 → 2326,13
cmp [edi+28], ecx
jae .extend_done
; add new cluster
push eax
call get_free_FAT
jc .disk_full
mov edx, [fatEND]
call set_FAT
mov edx, eax
pop eax
push eax
call get_free_FAT
jc .disk_full
mov edx, [ebp+FAT.fatEND]
call set_FAT
mov edx, eax
pop eax
test eax, eax
jz .first_cluster
push edx
2436,389 → 2347,469
@@:
push ecx
mov ecx, -1
call add_disk_free_space
pop ecx
mov eax, edx
cmp [hd_error], 0
jnz .device_err3
add [edi+28], ebp
jmp .extend_loop
.extend_done:
mov [edi+28], ecx
pop edx ebp
xor eax, eax ; CF=0
ret
.device_err3:
pop edx
jmp .device_err2
.disk_full:
pop eax edx ebp
push ERROR_DISK_FULL
pop eax
cmp [hd_error], 0
jz @f
mov al, 11
@@:
stc
ret
 
call add_disk_free_space
pop ecx
mov eax, edx
add [edi+28], esi
jmp .extend_loop
.extend_done:
mov [edi+28], ecx
pop edx esi
xor eax, eax ; CF=0
ret
.device_err3:
pop edx
jmp .device_err2
.disk_full:
pop eax edx esi
push ERROR_DISK_FULL
pop eax
stc
ret
 
;----------------------------------------------------------------
;
; fs_HdSetFileEnd - set end of file on hard disk
;
; esi points to filename
; ebx points to 64-bit number = new file size
; ecx ignored (reserved)
;
; fs_HdSetFileEnd - set end of file on hard disk
;
; Obsolete, will be replaced with filesystem-specific functions.
;
; esi points to filename
; ebx points to 64-bit number = new file size
; ecx ignored (reserved)
; edx ignored (reserved)
;
; ret eax = 0 ok or other = errormsg
;
;--------------------------------------------------------------
fs_HdSetFileEnd:
cmp [fs_type], 1
jz ntfs_HdSetFileEnd
cmp [fs_type], 2
jz ext2_HdSetFileEnd
cmp [fs_type], 16
jz @f
cmp [fs_type], 32
jz @f
push ERROR_UNKNOWN_FS
.ret:
pop eax
ret
@@:
cmp byte [esi], 0
jnz @f
.access_denied:
push ERROR_ACCESS_DENIED
jmp .ret
@@:
push edi
call hd_find_lfn
pushfd
cmp [hd_error], 0
jz @f
popfd
push 11
jmp .ret
@@:
popfd
jnc @f
pop edi
push ERROR_FILE_NOT_FOUND
jmp .ret
@@:
; must not be directory
test byte [edi+11], 10h
jz @f
pop edi
jmp .access_denied
@@:
; file size must not exceed 4 Gb
cmp dword [ebx+4], 0
jz @f
pop edi
push ERROR_END_OF_FILE
jmp .ret
@@:
push eax ; save directory sector
; set file modification date/time to current
call fat_update_datetime
mov eax, [ebx]
cmp eax, [edi+28]
jb .truncate
ja .expand
pop eax
mov ebx, buffer
call hd_write
pop edi
xor eax, eax
cmp [hd_error], 0
jz @f
mov al, 11
@@:
ret
.expand:
push ebx ebp ecx
push dword [edi+28] ; save old size
;
;--------------------------------------------------------------
fs_HdSetFileEnd:
cmp [fs_type], 16
jz @f
cmp [fs_type], 32
jz @f
cmp [fs_type], 1
jz ntfs_HdSetFileEnd
cmp [fs_type], 2
jz ext2_HdSetFileEnd
push ERROR_UNKNOWN_FS
pop eax
ret
@@:
sub ebx, 4
push ebp
mov ebp, [fs_dependent_data_start.partition]
call fat_SetFileEnd
pop ebp
ret
 
;----------------------------------------------------------------
; fat_SetFileEnd - FAT16/32 implementation of setting end-of-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
;----------------------------------------------------------------
fat_SetFileEnd:
call fat_lock
push edi
cmp byte [esi], 0
jnz @f
.access_denied:
push ERROR_ACCESS_DENIED
.ret:
call fat_unlock
pop eax
pop edi
ret
@@:
stdcall hd_find_lfn, [esp+4+4]
jnc @f
.reteax:
push eax
jmp .ret
@@:
; must not be directory
test byte [edi+11], 10h
jnz .access_denied
; file size must not exceed 4 Gb
cmp dword [ebx+8], 0
jz @f
push ERROR_END_OF_FILE
jmp .ret
@@:
push eax ; save directory sector
; set file modification date/time to current
call fat_update_datetime
mov eax, [ebx+4]
cmp eax, [edi+28]
jb .truncate
ja .expand
pop eax
lea ebx, [ebp+FAT.buffer]
call fs_write32_sys
pop edi
test eax, eax
jz @f
push ERROR_DEVICE
jmp .ret
@@:
push 0
jmp .ret
.expand:
push ebx ebp ecx
push dword [edi+28] ; save old size
mov ecx, eax
call hd_extend_file
push eax ; return code
jnc .expand_ok
cmp al, ERROR_DISK_FULL
jz .disk_full
.pop_ret:
call update_disk
pop eax ecx ebp ebx ecx edi edi
ret
.expand_ok:
.disk_full:
; save directory
mov eax, [edi+28]
xchg eax, [esp+20]
mov ebx, buffer
call hd_write
mov eax, [edi+20-2]
mov ax, [edi+26]
mov edi, eax
cmp [hd_error], 0
jz @f
.pop_ret11:
mov byte [esp], 11
jmp .pop_ret
@@:
; now zero new data
xor ebp, ebp
; edi=current cluster, ebp=sector in cluster
; [esp+20]=new size, [esp+4]=old size, [esp]=return code
.zero_loop:
sub dword [esp+4], 0x200
jae .next_cluster
lea eax, [edi-2]
imul eax, [SECTORS_PER_CLUSTER]
add eax, [DATA_START]
add eax, ebp
cmp dword [esp+4], -0x200
jz .noread
mov ebx, buffer
call hd_read
cmp [hd_error], 0
jnz .err_next
.noread:
mov ecx, [esp+4]
neg ecx
push edi
mov edi, buffer+0x200
add edi, [esp+8]
push eax
xor eax, eax
mov [esp+12], eax
rep stosb
pop eax
pop edi
call hd_write
cmp [hd_error], 0
jz .next_cluster
.err_next:
mov byte [esp], 11
.next_cluster:
sub dword [esp+20], 0x200
jbe .pop_ret
inc ebp
cmp ebp, [SECTORS_PER_CLUSTER]
jb .zero_loop
xor ebp, ebp
mov eax, edi
call get_FAT
mov edi, eax
cmp [hd_error], 0
jnz .pop_ret11
jmp .zero_loop
.truncate:
mov [edi+28], eax
push ecx
jz .disk_full
.pop_ret:
call update_disk
pop eax ecx ecx ebp ebx ecx
jmp .reteax
.expand_ok:
.disk_full:
; save directory
mov eax, [edi+28]
xchg eax, [esp+20]
lea ebx, [ebp+FAT.buffer]
call fs_write32_sys
test eax, eax
mov eax, [edi+20-2]
mov ax, [edi+26]
mov edi, eax
jz @f
.pop_ret11:
mov byte [esp], ERROR_DEVICE
jmp .pop_ret
@@:
test edi, edi
jz .pop_ret
; now zero new data
push 0
; edi=current cluster, [esp]=sector in cluster
; [esp+24]=new size, [esp+8]=old size, [esp+4]=return code
.zero_loop:
cmp edi, 2
jb .error_fat
cmp edi, [ebp+FAT.fatRESERVED]
jae .error_fat
sub dword [esp+8], 0x200
jae .next_cluster
lea eax, [edi-2]
imul eax, [ebp+FAT.SECTORS_PER_CLUSTER]
add eax, [ebp+FAT.DATA_START]
add eax, [esp]
cmp dword [esp+8], -0x200
jz .noread
push eax
lea ebx, [ebp+FAT.buffer]
call fs_read32_app
test eax, eax
pop eax
jnz .err_next
.noread:
mov ecx, [esp+8]
neg ecx
push edi
lea edi, [ebp+FAT.buffer+0x200]
add edi, [esp+12]
push eax
xor eax, eax
mov [esp+16], eax
rep stosb
pop eax
pop edi
call fs_write32_app
test eax, eax
jz .next_cluster
.err_next:
mov byte [esp+4], ERROR_DEVICE
.next_cluster:
pop eax
sub dword [esp+20], 0x200
jbe .pop_ret
inc eax
push eax
cmp eax, [ebp+FAT.SECTORS_PER_CLUSTER]
jb .zero_loop
and dword [esp], 0
mov eax, edi
call get_FAT
mov edi, eax
jnc .zero_loop
pop eax
jmp .pop_ret11
.truncate:
mov [edi+28], eax
push ecx
mov ecx, [edi+20-2]
mov cx, [edi+26]
push eax
test eax, eax
jz .zero_size
; find new last cluster
@@:
mov eax, [SECTORS_PER_CLUSTER]
shl eax, 9
sub [esp], eax
jbe @f
mov eax, ecx
call get_FAT
mov ecx, eax
cmp [hd_error], 0
jz @b
.device_err3:
pop eax ecx eax edi
push 11
pop eax
ret
@@:
jz .zero_size
; find new last cluster
@@:
cmp ecx, 2
jb .error_fat2
cmp ecx, [ebp+FAT.fatRESERVED]
jae .error_fat2
mov eax, [ebp+FAT.SECTORS_PER_CLUSTER]
shl eax, 9
sub [esp], eax
jbe @f
mov eax, ecx
call get_FAT
mov ecx, eax
jnc @b
.device_err3:
pop eax ecx eax edi
call update_disk
call fat_unlock
push ERROR_DEVICE
pop eax
ret
@@:
; we will zero data at the end of last sector - remember it
push ecx
; terminate FAT chain
push edx
mov eax, ecx
mov edx, [fatEND]
call set_FAT
mov eax, edx
pop edx
cmp [hd_error], 0
jz @f
.device_err4:
pop ecx
jmp .device_err3
; terminate FAT chain
push edx
mov eax, ecx
mov edx, [ebp+FAT.fatEND]
call set_FAT
mov eax, edx
pop edx
jnc @f
.device_err4:
pop ecx
jmp .device_err3
.zero_size:
and word [edi+20], 0
and word [edi+26], 0
push 0
mov eax, ecx
@@:
; delete FAT chain
call clear_cluster_chain
cmp [hd_error], 0
jnz .device_err4
; save directory
mov eax, [esp+12]
push ebx
mov ebx, buffer
call hd_write
pop ebx
cmp [hd_error], 0
jnz .device_err4
; zero last sector, ignore errors
pop ecx
@@:
; delete FAT chain
call clear_cluster_chain
jc .device_err4
; save directory
mov eax, [esp+12]
push ebx
lea ebx, [ebp+FAT.buffer]
call fs_write32_sys
pop ebx
test eax, eax
jnz .device_err4
; zero last sector, ignore errors
pop ecx
pop eax
dec ecx
imul ecx, [ebp+FAT.SECTORS_PER_CLUSTER]
add ecx, [ebp+FAT.DATA_START]
push eax
sar eax, 9
add ecx, eax
pop eax
dec ecx
imul ecx, [SECTORS_PER_CLUSTER]
add ecx, [DATA_START]
push eax
sar eax, 9
add ecx, eax
pop eax
and eax, 0x1FF
jz .truncate_done
push ebx eax
mov eax, ecx
mov ebx, buffer
call hd_read
pop eax
lea edi, [buffer+eax]
push ecx
mov ecx, 0x200
sub ecx, eax
xor eax, eax
rep stosb
pop eax
call hd_write
pop ebx
.truncate_done:
pop ecx eax edi
call update_disk
xor eax, eax
cmp [hd_error], 0
jz @f
mov al, 11
@@:
ret
 
fs_HdGetFileInfo:
cmp [fs_type], 1
jz ntfs_HdGetFileInfo
cmp [fs_type], 2
jz ext2_HdGetFileInfo
cmp [fs_type], 16
jz @f
cmp [fs_type], 32
jz @f
mov eax, ERROR_UNKNOWN_FS
ret
@@:
cmp byte [esi], 0
jnz @f
mov eax, 2
ret
@@:
push edi
call hd_find_lfn
pushfd
cmp [hd_error], 0
jz @f
popfd
pop edi
mov eax, 11
ret
@@:
popfd
jmp fs_GetFileInfo_finish
 
fs_HdSetFileInfo:
cmp [fs_type], 1
jz ntfs_HdSetFileInfo
cmp [fs_type], 2
jz ext2_HdSetFileInfo
cmp [fs_type], 16
jz @f
cmp [fs_type], 32
jz @f
mov eax, ERROR_UNKNOWN_FS
ret
@@:
cmp byte [esi], 0
jnz @f
mov eax, 2
ret
@@:
push edi
call hd_find_lfn
pushfd
cmp [hd_error], 0
jz @f
popfd
pop edi
mov eax, 11
ret
@@:
popfd
jnc @f
pop edi
mov eax, ERROR_FILE_NOT_FOUND
ret
@@:
push eax
call bdfe_to_fat_entry
pop eax
mov ebx, buffer
call hd_write
call update_disk
pop edi
xor eax, eax
ret
 
;----------------------------------------------------------------
;
; fs_HdDelete - delete file or empty folder from hard disk
;
; esi points to filename
;
; ret eax = 0 ok or other = errormsg
;
;--------------------------------------------------------------
fs_HdDelete:
cmp [fs_type], 1
jz ntfs_HdDelete
cmp [fs_type], 2
jz ext2_HdDelete
cmp [fs_type], 16
jz @f
cmp [fs_type], 32
jz @f
push ERROR_UNKNOWN_FS
.pop_ret:
pop eax
ret
@@:
cmp byte [esi], 0
jnz @f
; cannot delete root!
.access_denied:
push ERROR_ACCESS_DENIED
jz .truncate_done
push ebx eax
mov eax, ecx
lea ebx, [ebp+FAT.buffer]
call fs_read32_app
pop eax
lea edi, [ebp+FAT.buffer+eax]
push ecx
mov ecx, 0x200
sub ecx, eax
xor eax, eax
rep stosb
pop eax
call fs_write32_app
pop ebx
.truncate_done:
pop ecx eax edi
call update_disk
call fat_unlock
xor eax, eax
ret
.error_fat:
pop eax
mov byte [esp], ERROR_FAT_TABLE
jmp .pop_ret
.error_fat2:
pop eax ecx eax edi
call update_disk
call fat_unlock
push ERROR_FAT_TABLE
pop eax
ret
 
fs_HdGetFileInfo:
cmp [fs_type], 16
jz @f
cmp [fs_type], 32
jz @f
cmp [fs_type], 1
jz ntfs_HdGetFileInfo
cmp [fs_type], 2
jz ext2_HdGetFileInfo
mov eax, ERROR_UNKNOWN_FS
ret
@@:
sub ebx, 4
push ebp
mov ebp, [fs_dependent_data_start.partition]
call fat_GetFileInfo
pop ebp
ret
 
;----------------------------------------------------------------
; fat_GetFileInfo - FAT16/32 implementation of getting file info
; 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
;----------------------------------------------------------------
fat_GetFileInfo:
cmp byte [esi], 0
jnz @f
mov eax, 2
ret
@@:
push edi
call fat_lock
stdcall hd_find_lfn, [esp+4+4]
jc .error
push ebp
xor ebp, ebp
mov esi, [ebx+16]
mov dword [esi+4], ebp
call fat_entry_to_bdfe2
pop ebp
call fat_unlock
xor eax, eax
pop edi
ret
.error:
push eax
call fat_unlock
pop eax
pop edi
ret
 
fs_HdSetFileInfo:
cmp [fs_type], 16
jz @f
cmp [fs_type], 32
jz @f
cmp [fs_type], 1
jz ntfs_HdSetFileInfo
cmp [fs_type], 2
jz ext2_HdSetFileInfo
mov eax, ERROR_UNKNOWN_FS
ret
@@:
sub ebx, 4
push ebp
mov ebp, [fs_dependent_data_start.partition]
call fat_SetFileInfo
pop ebp
ret
 
;----------------------------------------------------------------
; fat_SetFileInfo - FAT16/32 implementation of setting file info
; 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
;----------------------------------------------------------------
fat_SetFileInfo:
cmp byte [esi], 0
jnz @f
mov eax, 2
ret
@@:
push edi
call fat_lock
stdcall hd_find_lfn, [esp+4+4]
jc .error
push eax
mov edx, [ebx+16]
call bdfe_to_fat_entry
pop eax
lea ebx, [ebp+FAT.buffer]
call fs_write32_sys
call update_disk
call fat_unlock
pop edi
xor eax, eax
ret
.error:
push eax
call fat_unlock
pop eax
pop edi
ret
 
;----------------------------------------------------------------
;
; fs_HdDelete - delete file or empty folder from hard disk
;
; Obsolete, will be replaced with filesystem-specific functions.
;
; esi points to filename
;
; ret eax = 0 ok or other = errormsg
;
;--------------------------------------------------------------
fs_HdDelete:
cmp [fs_type], 16
jz @f
cmp [fs_type], 32
jz @f
cmp [fs_type], 1
jz ntfs_HdDelete
cmp [fs_type], 2
jz ext2_HdDelete
push ERROR_UNKNOWN_FS
pop eax
ret
@@:
sub ebx, 4
push ebp
mov ebp, [fs_dependent_data_start.partition]
call fat_Delete
pop ebp
ret
 
;----------------------------------------------------------------
; fat_Delete - FAT16/32 implementation of deleting a file/folder
; 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
;----------------------------------------------------------------
fat_Delete:
call fat_lock
cmp byte [esi], 0
jnz @f
; cannot delete root!
.access_denied:
push ERROR_ACCESS_DENIED
.pop_ret:
call fat_unlock
pop eax
xor ebx, ebx
ret
@@:
and [ebp+FAT.longname_sec1], 0
and [ebp+FAT.longname_sec2], 0
push edi
stdcall hd_find_lfn, [esp+4+4]
jnc .found
pop edi
push ERROR_FILE_NOT_FOUND
jmp .pop_ret
@@:
and [longname_sec1], 0
and [longname_sec2], 0
push edi
call hd_find_lfn
jnc .found
pop edi
push ERROR_FILE_NOT_FOUND
jmp .pop_ret
.found:
cmp dword [edi], '. '
jz .access_denied2
2825,116 → 2816,128
cmp dword [edi], '.. '
jz .access_denied2
test byte [edi+11], 10h
jz .dodel
; we can delete only empty folders!
pushad
mov ebp, [edi+20-2]
mov bp, [edi+26]
xor ecx, ecx
lea eax, [ebp-2]
imul eax, [SECTORS_PER_CLUSTER]
add eax, [DATA_START]
mov ebx, buffer
call hd_read
cmp [hd_error], 0
jnz .err1
add ebx, 2*0x20
.checkempty:
cmp byte [ebx], 0
jz .dodel
; we can delete only empty folders!
pushad
mov esi, [edi+20-2]
mov si, [edi+26]
xor ecx, ecx
lea eax, [esi-2]
imul eax, [ebp+FAT.SECTORS_PER_CLUSTER]
add eax, [ebp+FAT.DATA_START]
lea ebx, [ebp+FAT.buffer]
call fs_read32_sys
test eax, eax
jnz .err1
lea eax, [ebx+0x200]
add ebx, 2*0x20
.checkempty:
cmp byte [ebx], 0
jz .empty
cmp byte [ebx], 0xE5
jnz .notempty
add ebx, 0x20
cmp ebx, buffer+0x200
jb .checkempty
inc ecx
cmp ecx, [SECTORS_PER_CLUSTER]
jb @f
mov eax, ebp
call get_FAT
cmp [hd_error], 0
jnz .err1
mov ebp, eax
xor ecx, ecx
@@:
lea eax, [ebp-2]
imul eax, [SECTORS_PER_CLUSTER]
add eax, [DATA_START]
add eax, ecx
mov ebx, buffer
call hd_read
cmp [hd_error], 0
jz .checkempty
.err1:
popad
.err2:
pop edi
push 11
pop eax
ret
.notempty:
popad
.access_denied2:
pop edi
push ERROR_ACCESS_DENIED
pop eax
ret
.empty:
popad
push ebx
mov ebx, buffer
call hd_read
pop ebx
cmp [hd_error], 0
jnz .err2
.dodel:
push eax
cmp byte [ebx], 0xE5
jnz .notempty
add ebx, 0x20
cmp ebx, eax
jb .checkempty
inc ecx
cmp ecx, [ebp+FAT.SECTORS_PER_CLUSTER]
jb @f
mov eax, esi
call get_FAT
jc .err1
cmp eax, 2
jb .error_fat
cmp eax, [ebp+FAT.fatRESERVED]
jae .empty
mov esi, eax
xor ecx, ecx
@@:
lea eax, [esi-2]
imul eax, [ebp+FAT.SECTORS_PER_CLUSTER]
add eax, [ebp+FAT.DATA_START]
add eax, ecx
lea ebx, [ebp+FAT.buffer]
call fs_read32_sys
test eax, eax
lea eax, [ebx+0x200]
jz .checkempty
.err1:
popad
.err2:
pop edi
call fat_unlock
push ERROR_DEVICE
pop eax
ret
.error_fat:
popad
pop edi
call fat_unlock
push ERROR_FAT_TABLE
pop eax
ret
.notempty:
popad
.access_denied2:
pop edi
call fat_unlock
push ERROR_ACCESS_DENIED
pop eax
ret
.empty:
popad
push eax ebx
lea ebx, [ebp+FAT.buffer]
call fs_read32_sys
test eax, eax
pop ebx eax
jnz .err2
.dodel:
push eax
mov eax, [edi+20-2]
mov ax, [edi+26]
xchg eax, [esp]
; delete folder entry
mov byte [edi], 0xE5
; delete LFN (if present)
.lfndel:
cmp edi, buffer
ja @f
cmp [longname_sec2], 0
mov byte [edi], 0xE5
; delete LFN (if present)
.lfndel:
lea edx, [ebp+FAT.buffer]
cmp edi, edx
ja @f
cmp [ebp+FAT.longname_sec2], 0
jz .lfndone
push [ebp+FAT.longname_sec2]
push [ebp+FAT.longname_sec1]
pop [ebp+FAT.longname_sec2]
and [ebp+FAT.longname_sec1], 0
push ebx
mov ebx, edx
call fs_write32_sys
mov eax, [esp+4]
call fs_read32_sys
pop ebx
pop eax
lea edi, [ebp+FAT.buffer+0x200]
@@:
sub edi, 0x20
cmp byte [edi], 0xE5
jz .lfndone
push [longname_sec2]
push [longname_sec1]
pop [longname_sec2]
and [longname_sec1], 0
push ebx
mov ebx, buffer
call hd_write
mov eax, [esp+4]
call hd_read
pop ebx
pop eax
mov edi, buffer+0x200
@@:
sub edi, 0x20
cmp byte [edi], 0xE5
jz .lfndone
cmp byte [edi+11], 0xF
jnz .lfndone
mov byte [edi], 0xE5
jmp .lfndel
.lfndone:
push ebx
mov ebx, buffer
call hd_write
pop ebx
; delete FAT chain
pop eax
call clear_cluster_chain
call update_disk
pop edi
xor eax, eax
cmp [hd_error], 0
jz @f
mov al, 11
@@:
ret
 
; \end{diamond}
jmp .lfndel
.lfndone:
push ebx
lea ebx, [ebp+FAT.buffer]
call fs_write32_sys
pop ebx
; delete FAT chain
pop eax
call clear_cluster_chain
call update_disk
call fat_unlock
pop edi
xor eax, eax
ret
 
; \end{diamond}
/kernel/branches/net/fs/fs.inc
166,17 → 166,13
and dword [esp+36], 0; ok read
mov dword [esp+24], 32*2; size of root
ret
 
fs_info: ;start of code - Mihasik
push eax
cmp [eax+21], byte 'h'
je fs_info_h
cmp [eax+21], byte 'H'
je fs_info_h
cmp [eax+21], byte 'r'
 
fs_info: ;start of code - Mihasik
push eax
cmp [eax+21], byte 'r'
je fs_info_r
cmp [eax+21], byte 'R'
je fs_info_r
cmp [eax+21], byte 'R'
je fs_info_r
mov eax, 3 ;if unknown disk
xor ebx, ebx
xor ecx, ecx
186,15 → 182,12
call ramdisk_free_space;if ramdisk
mov ecx, edi ;free space in ecx
shr ecx, 9 ;free clusters
mov ebx, 2847 ;total clusters
mov edx, 512 ;cluster size
xor eax, eax ;always 0
jmp fs_info1
fs_info_h: ;if harddisk
call get_hd_info
fs_info1:
pop edi
mov [esp+36], eax
mov ebx, 2847 ;total clusters
mov edx, 512 ;cluster size
xor eax, eax ;always 0
fs_info1:
pop edi
mov [esp+36], eax
mov [esp+24], ebx ; total clusters on disk
mov [esp+32], ecx ; free clusters on disk
mov [edi], edx ; cluster size in bytes
434,41 → 427,15
hd_err_return:
call free_hd_channel
and [hd1_status], 0
jmp file_system_return
@@:
 
cmp dword [esp+20], 0; READ
jne fs_noharddisk_read
 
mov eax, [esp+0] ; /fname
lea edi, [eax+12]
mov byte [eax], 0 ; path to asciiz
inc eax ; filename start
 
mov ebx, [esp+12] ; count to read
mov ecx, [esp+8] ; buffer
mov edx, [esp+4]
add edx, 12*2 ; dir start
sub edi, edx ; path length
mov esi, [esp+16] ; blocks to read
 
call file_read
 
mov edi, [esp+0]
mov byte [edi], '/'
 
call free_hd_channel
and [hd1_status], 0
jmp file_system_return
 
fs_noharddisk_read:
 
call free_hd_channel
and [hd1_status], 0
 
fs_noharddisk:
; \begin{diamond}[18.03.2006]
mov eax, 5 ; file not found
jmp file_system_return
@@:
 
call free_hd_channel
and [hd1_status], 0
 
fs_noharddisk:
; \begin{diamond}[18.03.2006]
mov eax, 5 ; file not found
; à ìîæåò áûòü, âîçâðàùàòü äðóãîé êîä îøèáêè?
mov ebx, [esp+24+24]; do not change ebx in application
; \end{diamond}[18.03.2006]
/kernel/branches/net/fs/fs_lfn.inc
7,6 → 7,19
 
$Revision $
 
ERROR_SUCCESS = 0
ERROR_DISK_BASE = 1
ERROR_UNSUPPORTED_FS = 2
ERROR_UNKNOWN_FS = 3
ERROR_PARTITION = 4
ERROR_FILE_NOT_FOUND = 5
ERROR_END_OF_FILE = 6
ERROR_MEMORY_POINTER = 7
ERROR_DISK_FULL = 8
ERROR_FAT_TABLE = 9 ;deprecated
ERROR_FS_FAIL = 9
ERROR_ACCESS_DENIED = 10
ERROR_DEVICE = 11
 
image_of_eax EQU esp+32
image_of_ebx EQU esp+20
/kernel/branches/net/fs/part_set.inc
30,31 → 30,15
fs_type db 0 ; 1=NTFS, 2=EXT2/3, 16=FAT16, 32=FAT32
align 4
 
fs_dependent_data_start:
; FATxx data
 
SECTORS_PER_FAT dd 0x1f3a
NUMBER_OF_FATS dd 0x2
SECTORS_PER_CLUSTER dd 0x8
BYTES_PER_SECTOR dd 0x200 ; Note: if BPS <> 512 need lots of changes
ROOT_CLUSTER dd 2 ; first rootdir cluster
FAT_START dd 0 ; start of fat table
ROOT_START dd 0 ; start of rootdir (only fat16)
ROOT_SECTORS dd 0 ; count of rootdir sectors (only fat16)
DATA_START dd 0 ; start of data area (=first cluster 2)
LAST_CLUSTER dd 0 ; last availabe cluster
ADR_FSINFO dd 0 ; used only by fat32
 
fatRESERVED dd 0x0FFFFFF6
fatBAD dd 0x0FFFFFF7
fatEND dd 0x0FFFFFF8
fatMASK dd 0x0FFFFFFF
 
fatStartScan dd 2
 
fs_dependent_data_end:
file_system_data_size = $ - PARTITION_START
if file_system_data_size > 96
fs_dependent_data_start:
; FATxx data
 
.partition dd ?
rb 80
 
fs_dependent_data_end:
file_system_data_size = $ - PARTITION_START
if file_system_data_size > 96
ERROR:
sizeof(file system data) too big!
end if
85,13 → 69,12
; EXT2 data
ext2_data:
.log_block_size dd ?
.block_size dd ?
.count_block_in_block dd ?
.blocks_per_group dd ?
.inodes_per_group dd ?
.global_desc_table dd ?
.root_inode dd ? ; pointer to root inode in memory
.inode_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 ? ; ¡«®ª ­  £«®¡ «ì­ãî 1 ¯à®æ¥¤ãàã
424,111 → 407,30
 
mov eax, [PARTITION_START] ;ext2 test changes [buffer]
call hd_read
cmp [hd_error], 0
jnz problem_fat_dec_count
 
cmp word [ebx+0x1fe], 0xaa55; is it valid boot sector?
jnz problem_fat_dec_count
 
movzx eax, word [ebx+0xe]; sectors reserved
add eax, [PARTITION_START]
mov [FAT_START], eax; fat_start = partition_start + reserved
 
movzx eax, byte [ebx+0xd]; sectors per cluster
test eax, eax
jz problem_fat_dec_count
mov [SECTORS_PER_CLUSTER], eax
 
movzx ecx, word [ebx+0xb]; bytes per sector
cmp ecx, 0x200
jnz problem_fat_dec_count
mov [BYTES_PER_SECTOR], ecx
 
movzx eax, word [ebx+0x11]; count of rootdir entries (=0 fat32)
mov edx, 32
mul edx
dec ecx
add eax, ecx ; round up if not equal count
inc ecx ; bytes per sector
div ecx
mov [ROOT_SECTORS], eax; count of rootdir sectors
 
movzx eax, word [ebx+0x16]; sectors per fat <65536
test eax, eax
jnz fat16_fatsize
mov eax, [ebx+0x24] ; sectors per fat
fat16_fatsize:
mov [SECTORS_PER_FAT], eax
 
movzx eax, byte [ebx+0x10]; number of fats
test eax, eax ; if 0 it's not fat partition
jz problem_fat_dec_count
mov [NUMBER_OF_FATS], eax
imul eax, [SECTORS_PER_FAT]
add eax, [FAT_START]
mov [ROOT_START], eax; rootdir = fat_start + fat_size * fat_count
add eax, [ROOT_SECTORS]; rootdir sectors should be 0 on fat32
mov [DATA_START], eax; data area = rootdir + rootdir_size
 
movzx eax, word [ebx+0x13]; total sector count <65536
test eax, eax
jnz fat16_total
mov eax, [ebx+0x20] ; total sector count
fat16_total:
add eax, [PARTITION_START]
dec eax
mov [PARTITION_END], eax
inc eax
sub eax, [DATA_START]; eax = count of data sectors
xor edx, edx
div dword [SECTORS_PER_CLUSTER]
inc eax
mov [LAST_CLUSTER], eax
dec eax ; cluster count
mov [fatStartScan], 2
 
; limits by Microsoft Hardware White Paper v1.03
cmp eax, 4085 ; 0xff5
jb problem_fat_dec_count; fat12 not supported
cmp eax, 65525 ; 0xfff5
jb fat16_partition
 
fat32_partition:
mov eax, [ebx+0x2c] ; rootdir cluster
mov [ROOT_CLUSTER], eax
movzx eax, word [ebx+0x30]; fs info sector
add eax, [PARTITION_START]
mov [ADR_FSINFO], eax
call hd_read
mov eax, [ebx+0x1ec]
cmp eax, -1
jz @f
mov [fatStartScan], eax
@@:
 
popad
 
mov [fatRESERVED], 0x0FFFFFF6
mov [fatBAD], 0x0FFFFFF7
mov [fatEND], 0x0FFFFFF8
mov [fatMASK], 0x0FFFFFFF
mov [fs_type], 32 ; Fat32
call free_hd_channel
mov [hd1_status], 0 ; free
ret
 
fat16_partition:
xor eax, eax
mov [ROOT_CLUSTER], eax
 
popad
 
mov [fatRESERVED], 0x0000FFF6
mov [fatBAD], 0x0000FFF7
mov [fatEND], 0x0000FFF8
mov [fatMASK], 0x0000FFFF
mov [fs_type], 16 ; Fat16
call free_hd_channel
mov [hd1_status], 0 ; free
ret
 
cmp [hd_error], 0
jnz problem_fat_dec_count
 
push 0
mov eax, [PARTITION_END]
sub eax, [PARTITION_START]
inc eax
push eax
push 0
push [PARTITION_START]
push ebp
push ebp
mov ebp, esp
mov esi, 'old' ; special value: there is no DISK structure
push 1 ; bootsector read successfully
call fat_create_partition
add esp, 4*7
test eax, eax
jz problem_fat_dec_count
mov [fs_dependent_data_start.partition], eax
mov al, [eax+FAT.fs_type]
mov [fs_type], al
 
popad
call free_hd_channel
mov [hd1_status], 0 ; free
ret
/kernel/branches/net/gui/char.mt
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/kernel/branches/net/gui/char2.mt
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/kernel/branches/net/gui/font.inc
225,7 → 225,15
add eax, 8
and ecx, 0xffffff
or ecx, 0xff000000 ; not transparent
mov [eax], ecx ; store pixel
popad
ret
mov [eax], ecx ; store pixel
popad
ret
;------------------------------------------------------------------------------
align 4
FONT_I:
file 'char.mt'
;------------------------------------------------------------------------------
align 4
FONT_II:
file 'char2.mt'
;------------------------------------------------------------------------------
/kernel/branches/net/gui/mouse.inc
255,15 → 255,15
@@:
test dl, mouse.WINDOW_RESIZE_E_FLAG
jz .call_window_handler
call .calculate_e_delta
call .calculate_e_delta
 
.call_window_handler:
; mov eax, mouse.active_sys_window.old_box
; call sys_window_start_moving_handler
 
.exit:
ret
 
.call_window_handler:
mov eax, mouse.active_sys_window.old_box
call sys_window_start_moving_handler
 
.exit:
ret
 
.calculate_n_delta:
mov eax, [mouse.state.pos.y]
sub eax, [mouse.active_sys_window.old_box.top]
/kernel/branches/net/gui/window.inc
1023,13 → 1023,62
mov byte[MOUSE_DOWN], 0
inc eax
ret
;------------------------------------------------------------------------------
align 4
;------------------------------------------------------------------------------
minimize_all_window:
push ebx ecx edx esi edi
pushfd
cli
xor edx, edx
mov eax, 2 ; we do not minimize the kernel thread N1
mov ebx, [TASK_COUNT]
;--------------------------------------
align 4
.loop:
movzx edi, word[WIN_POS + eax * 2]
shl edi, 5
; it is a unused slot?
cmp dword [edi+CURRENT_TASK+TASKDATA.state], 9
je @f
; it is a hidden thread?
lea esi, [edi*8+SLOT_BASE+APPDATA.app_name]
cmp [esi], byte '@'
je @f
; is it already minimized?
test [edi + window_data+WDATA.fl_wstate], WSTATE_MINIMIZED
jnz @f
; no it's not, let's do that
or [edi + window_data+WDATA.fl_wstate], WSTATE_MINIMIZED
inc edx
;--------------------------------------
align 4
@@:
inc eax
cmp eax, ebx
jbe .loop
; If nothing has changed
test edx, edx
jz @f
 
push edx
call syscall_display_settings._.calculate_whole_screen
call syscall_display_settings._.redraw_whole_screen
pop edx
;--------------------------------------
align 4
@@:
mov eax, edx
popfd
pop edi esi edx ecx ebx
ret
;------------------------------------------------------------------------------
align 4
;------------------------------------------------------------------------------
minimize_window: ;/////////////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;> eax = window number on screen
;------------------------------------------------------------------------------
align 4
;------------------------------------------------------------------------------
minimize_window: ;/////////////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;> eax = window number on screen
;------------------------------------------------------------------------------
;# corrupts [dl*]
;------------------------------------------------------------------------------
push edi
1044,27 → 1093,43
jnz .exit
 
push eax ebx ecx edx esi
 
; no it's not, let's do that
or [edi + WDATA.fl_wstate], WSTATE_MINIMIZED
mov eax, [edi + WDATA.box.left]
mov [draw_limits.left], eax
mov ecx, eax
 
; no it's not, let's do that
or [edi + WDATA.fl_wstate], WSTATE_MINIMIZED
; If the window width is 0, then the action is not needed.
cmp [edi + WDATA.box.width], dword 0
je @f
; If the window height is 0, then the action is not needed.
cmp [edi + WDATA.box.height], dword 0
je @f
 
mov eax, [edi + WDATA.box.left]
mov [draw_limits.left], eax
mov ecx, eax
add ecx, [edi + WDATA.box.width]
mov [draw_limits.right], ecx
mov ebx, [edi + WDATA.box.top]
mov [draw_limits.top], ebx
mov edx, ebx
add edx, [edi + WDATA.box.height]
mov [draw_limits.bottom], edx
call calculatescreen
xor esi, esi
xor eax, eax
call redrawscreen
 
pop esi edx ecx ebx eax
;--------------------------------------
align 4
mov edx, ebx
add edx, [edi + WDATA.box.height]
mov [draw_limits.bottom], edx
 
; DEBUGF 1, "K : minimize_window\n"
; DEBUGF 1, "K : dl_left %x\n",[draw_limits.left]
; DEBUGF 1, "K : dl_right %x\n",[draw_limits.right]
; DEBUGF 1, "K : dl_top %x\n",[draw_limits.top]
; DEBUGF 1, "K : dl_bottom %x\n",[draw_limits.bottom]
call calculatescreen
; xor esi, esi
; xor eax, eax
mov eax, edi
call redrawscreen
;--------------------------------------
align 4
@@:
pop esi edx ecx ebx eax
;--------------------------------------
align 4
.exit:
popfd
pop edi
1263,35 → 1328,35
call window._.set_window_box
add esp, sizeof.BOX
ret
;------------------------------------------------------------------------------
align 4
;------------------------------------------------------------------------------
sys_window_start_moving_handler: ;/////////////////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
;> eax = old (original) window box
;> esi = process slot
;------------------------------------------------------------------------------
mov edi, eax
call window._.draw_negative_box
ret
;------------------------------------------------------------------------------
align 4
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
align 4
;------------------------------------------------------------------------------
;sys_window_start_moving_handler: ;/////////////////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
;> eax = old (original) window box
;> esi = process slot
;------------------------------------------------------------------------------
; mov edi, eax
; call window._.draw_negative_box
; ret
;------------------------------------------------------------------------------
align 4
;------------------------------------------------------------------------------
sys_window_end_moving_handler: ;///////////////////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
;> eax = old (original) window box
;> ebx = new (final) window box
;> esi = process slot
;------------------------------------------------------------------------------
mov edi, ebx
call window._.end_moving__box
 
mov edi, esi
shl edi, 5
;> ebx = new (final) window box
;> esi = process slot
;------------------------------------------------------------------------------
; mov edi, ebx
; call window._.end_moving__box
 
mov edi, esi
shl edi, 5
add edi, window_data
 
mov eax, ebx
2316,23 → 2381,23
mov bx, word[edi + BOX.top]
add bx, word[edi + BOX.height]
call draw_rectangle.forced
pop esi ebx eax
ret
;------------------------------------------------------------------------------
align 4
;------------------------------------------------------------------------------
window._.end_moving__box: ;//////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? Draw positive box
;------------------------------------------------------------------------------
;> edi = pointer to BOX struct
;------------------------------------------------------------------------------
push eax ebx esi
xor esi, esi
jmp window._.draw_negative_box.1
;------------------------------------------------------------------------------
align 4
;------------------------------------------------------------------------------
pop esi ebx eax
ret
;------------------------------------------------------------------------------
;align 4
;------------------------------------------------------------------------------
;window._.end_moving__box: ;//////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? Draw positive box
;------------------------------------------------------------------------------
;> edi = pointer to BOX struct
;------------------------------------------------------------------------------
; push eax ebx esi
; xor esi, esi
; jmp window._.draw_negative_box.1
;------------------------------------------------------------------------------
align 4
;------------------------------------------------------------------------------
window._.get_rect: ;/////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? <description> void __fastcall get_window_rect(struct RECT* rc);
/kernel/branches/net/hid/keyboard.inc
5,7 → 5,7
;; Distributed under terms of the GNU General Public License ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
$Revision $
 
 
VKEY_LSHIFT = 0000000000000001b
34,6 → 34,7
ctrl_alt_del db 0
 
kb_lights db 0
old_kb_lights db 0
 
align 4
hotkey_scancodes rd 256 ; we have 256 scancodes
113,6 → 114,83
pop ebp edi esi ebx
ret
;---------------------------------------------------------------------
struct KEYBOARD
next dd ?
prev dd ?
functions dd ?
userdata dd ?
ends
struct KBDFUNC
strucsize dd ?
close dd ?
setlights dd ?
ends
 
iglobal
keyboards:
dd keyboards
dd keyboards
endg
uglobal
keyboard_list_mutex MUTEX
endg
 
register_keyboard:
push ebx
push sizeof.KEYBOARD
pop eax
call malloc
test eax, eax
jz .nothing
mov ecx, [esp+4+4]
mov [eax+KEYBOARD.functions], ecx
mov ecx, [esp+8+4]
mov [eax+KEYBOARD.userdata], ecx
xchg eax, ebx
mov ecx, keyboard_list_mutex
call mutex_lock
mov ecx, keyboards
mov edx, [ecx+KEYBOARD.prev]
mov [ebx+KEYBOARD.next], ecx
mov [ebx+KEYBOARD.prev], edx
mov [edx+KEYBOARD.next], ebx
mov [ecx+KEYBOARD.prev], ebx
mov ecx, [ebx+KEYBOARD.functions]
cmp [ecx+KBDFUNC.strucsize], KBDFUNC.setlights
jbe .unlock
mov ecx, [ecx+KBDFUNC.setlights]
test ecx, ecx
jz .unlock
stdcall ecx, [ebx+KEYBOARD.userdata], dword [kb_lights]
.unlock:
mov ecx, keyboard_list_mutex
call mutex_unlock
xchg eax, ebx
.nothing:
pop ebx
ret 8
 
delete_keyboard:
push ebx
mov ebx, [esp+4+4]
mov ecx, keyboard_list_mutex
call mutex_lock
mov eax, [ebx+KEYBOARD.next]
mov edx, [ebx+KEYBOARD.prev]
mov [eax+KEYBOARD.prev], edx
mov [edx+KEYBOARD.next], eax
call mutex_unlock
mov ecx, [ebx+KEYBOARD.functions]
cmp [ecx+KBDFUNC.strucsize], KBDFUNC.close
jbe .nothing
mov ecx, [ecx+KBDFUNC.close]
test ecx, ecx
jz .nothing
stdcall ecx, [ebx+KEYBOARD.userdata]
.nothing:
pop ebx
ret 4
;---------------------------------------------------------------------
align 4
irq1:
movzx eax, word[TASK_COUNT]; top window process
281,8 → 359,11
xor [kb_state], eax
xor [kb_lights], bl
push ecx
call set_lights
pop ecx
.writekey:
pushad
; test for system hotkeys
movzx eax, ch
cmp bh, 1
335,9 → 416,16
mov [edi+4], ax
mov eax, [kb_state]
mov [edi+6], ax
 
cmp [PID_lock_input], dword 0
je .nohotkey
 
popad
jmp .exit.irq1
;--------------------------------------
.nohotkey:
popad
 
cmp [keyboard_mode], 0; return from keymap
jne .scancode
384,10 → 472,43
ret
;---------------------------------------------------------------------
set_lights:
push ebx esi
mov ecx, keyboard_list_mutex
call mutex_lock
mov esi, keyboards
.loop:
mov esi, [esi+KEYBOARD.next]
cmp esi, keyboards
jz .done
mov eax, [esi+KEYBOARD.functions]
cmp dword [eax], KBDFUNC.setlights
jbe .loop
mov eax, [eax+KBDFUNC.setlights]
test eax, eax
jz .loop
stdcall eax, [esi+KEYBOARD.userdata], dword [kb_lights]
jmp .loop
.done:
mov ecx, keyboard_list_mutex
call mutex_unlock
pop esi ebx
ret
 
ps2_set_lights:
mov al, 0xED
call kb_write
mov al, [esp+8]
call kb_write
ret 8
 
;// mike.dld ]
check_lights_state:
mov al, [kb_lights]
call kb_write
cmp al, [old_kb_lights]
jz .nothing
mov [old_kb_lights], al
call set_lights
.nothing:
ret
;---------------------------------------------------------------------
numlock_map:
/kernel/branches/net/hid/mousedrv.inc
23,20 → 23,20
 
uglobal
;--------------------------------------
align 4
mousecount dd 0x0
mousedata dd 0x0
Y_UNDER_subtraction_CUR_hot_y:
dd 0
X_UNDER_subtraction_CUR_hot_x:
dd 0
Y_UNDER_sub_CUR_hot_y_add_curh:
dd 0
X_UNDER_sub_CUR_hot_x_add_curh:
dd 0
endg
 
iglobal
align 4
mousecount dd 0x0
mousedata dd 0x0
Y_UNDER_sub_CUR_hot_y_add_curh:
dw 0
Y_UNDER_subtraction_CUR_hot_y:
dw 0
X_UNDER_sub_CUR_hot_x_add_curh:
dw 0
X_UNDER_subtraction_CUR_hot_x:
dw 0
endg
 
iglobal
;--------------------------------------
align 4
mouse_delay dd 10
121,12 → 121,24
shl edx, 8
mov esi, [edx+SLOT_BASE+APPDATA.cursor]
 
cmp esi, [current_cursor]
je .draw
 
push esi
call [_display.select_cursor]
mov [current_cursor], esi
cmp esi, [current_cursor]
je .draw
 
mov eax, [TASK_COUNT]
movzx eax, word [WIN_POS+eax*2]
shl eax, 8
 
cmp eax, edx
je @F
 
mov esi, [def_cursor]
cmp esi, [current_cursor]
je .draw
 
@@:
push esi
call [_display.select_cursor]
mov [current_cursor], esi
;--------------------------------------
align 4
.draw:
444,21 → 456,21
 
xor eax, eax
mov esi, [current_cursor]
 
mov ax, [Y_UNDER]
sub eax, [esi+CURSOR.hot_y]
mov [Y_UNDER_subtraction_CUR_hot_y], eax
add eax, [cur.h]
mov [Y_UNDER_sub_CUR_hot_y_add_curh], eax
 
mov ax, [X_UNDER]
sub eax, [esi+CURSOR.hot_x]
mov [X_UNDER_subtraction_CUR_hot_x], eax
add eax, [cur.w]
mov [X_UNDER_sub_CUR_hot_x_add_curh], eax
;--------------------------------------
align 4
@@:
 
mov ax, [Y_UNDER]
sub eax, [esi+CURSOR.hot_y]
mov [Y_UNDER_subtraction_CUR_hot_y], ax
add eax, [cur.h]
mov [Y_UNDER_sub_CUR_hot_y_add_curh], ax
 
mov ax, [X_UNDER]
sub eax, [esi+CURSOR.hot_x]
mov [X_UNDER_subtraction_CUR_hot_x], ax
add eax, [cur.w]
mov [X_UNDER_sub_CUR_hot_x_add_curh], ax
;--------------------------------------
align 4
@@:
popfd
;--------------------------------------
align 4
/kernel/branches/net/kernel.asm
334,6 → 334,9
mov ecx, disk_list_mutex
call mutex_init
 
mov ecx, keyboard_list_mutex
call mutex_init
 
mov ecx, unpack_mutex
call mutex_init
 
382,11 → 385,13
 
movzx eax, word [BOOT_VAR+BOOT_X_RES]; X max
mov [_display.width], eax
mov [display_width_standard], eax
dec eax
mov [Screen_Max_X], eax
mov [screen_workarea.right], eax
movzx eax, word [BOOT_VAR+BOOT_Y_RES]; Y max
mov [_display.height], eax
mov [display_height_standard], eax
dec eax
mov [Screen_Max_Y], eax
mov [screen_workarea.bottom], eax
446,6 → 451,10
mov [GETPIXEL], dword Vesa20_getpixel32
no_mode_0x12:
 
mov [MOUSE_PICTURE], dword mousepointer
mov [_display.check_mouse], check_mouse_area_for_putpixel
mov [_display.check_m_pixel], check_mouse_area_for_getpixel
 
; -------- Fast System Call init ----------
; Intel SYSENTER/SYSEXIT (AMD CPU support it too)
bt [cpu_caps], CAPS_SEP
531,7 → 540,7
mov ax, tss0
ltr ax
 
mov [LFBSize], 0x800000
mov [LFBSize], 0xC00000
call init_LFB
call init_fpu
call init_malloc
602,19 → 611,31
mov [SLOT_BASE + 256 + APPDATA.dir_table], sys_pgdir - OS_BASE
 
; REDIRECT ALL IRQ'S TO INT'S 0x20-0x2f
mov esi, boot_initirq
call boot_log
call init_irqs
 
call init_irqs
mov esi, boot_picinit
call boot_log
call PIC_init
 
mov esi, boot_v86machine
call boot_log
; Initialize system V86 machine
call init_sys_v86
 
mov esi, boot_inittimer
call boot_log
; Initialize system timer (IRQ0)
call PIT_init
 
mov esi, boot_initapic
call boot_log
; Try to Initialize APIC
call APIC_init
 
mov esi, boot_enableirq
call boot_log
; Enable timer IRQ (IRQ0) and hard drives IRQs (IRQ14, IRQ15)
; they are used: when partitions are scanned, hd_read relies on timer
call unmask_timer
624,6 → 645,8
stdcall enable_irq, 14
stdcall enable_irq, 15
 
mov esi, boot_enablint_ide
call boot_log
; Enable interrupts in IDE controller
mov al, 0
mov dx, 0x3F6
632,9 → 655,25
out dx, al
 
;!!!!!!!!!!!!!!!!!!!!!!!!!!
include 'detect/disks.inc'
; mov esi, boot_detectdisks
; call boot_log
;include 'detect/disks.inc'
mov esi, boot_detectfloppy
call boot_log
include 'detect/dev_fd.inc'
mov esi, boot_detecthdcd
call boot_log
include 'detect/dev_hdcd.inc'
mov esi, boot_getcache
call boot_log
include 'detect/getcache.inc'
mov esi, boot_detectpart
call boot_log
include 'detect/sear_par.inc'
;!!!!!!!!!!!!!!!!!!!!!!!!!!
 
mov esi, boot_init_sys
call boot_log
call Parser_params
 
if ~ defined extended_primary_loader
654,6 → 693,9
mov ax, [OS_BASE+0x10000+bx_from_load]
cmp ax, 'r1'; if using not ram disk, then load librares and parameters {SPraid.simba}
je no_lib_load
 
mov esi, boot_loadlibs
call boot_log
; LOADING LIBRARES
stdcall dll.Load, @IMPORT ; loading librares for kernel (.obj files)
call load_file_parse_table ; prepare file parse table
661,18 → 703,6
no_lib_load:
end if
 
; LOAD FONTS I and II
 
stdcall read_file, char, FONT_I, 0, 2304
stdcall read_file, char2, FONT_II, 0, 2560
 
mov [MOUSE_PICTURE], dword mousepointer
mov [_display.check_mouse], check_mouse_area_for_putpixel
mov [_display.check_m_pixel], check_mouse_area_for_getpixel
 
mov esi, boot_fonts
call boot_log
 
; Display APIC status
mov esi, boot_APIC_found
cmp [irq_mode], IRQ_APIC
679,6 → 709,7
je @f
mov esi, boot_APIC_nfound
@@:
call boot_log
 
; PRINT AMOUNT OF MEMORY
mov esi, boot_memdetect
701,10 → 732,10
 
; BUILD SCHEDULER
 
call build_scheduler; sys32.inc
; call build_scheduler; sys32.inc
 
mov esi, boot_devices
call boot_log
; mov esi, boot_devices
; call boot_log
 
mov [pci_access_enabled], 1
 
901,6 → 932,8
; SET KEYBOARD PARAMETERS
mov al, 0xf6 ; reset keyboard, scan enabled
call kb_write
test ah, ah
jnz .no_keyboard
 
; wait until 8042 is ready
xor ecx, ecx
909,6 → 942,15
and al, 00000010b
loopnz @b
 
iglobal
align 4
ps2_keyboard_functions:
dd .end - $
dd 0 ; no close
dd ps2_set_lights
.end:
endg
stdcall register_keyboard, ps2_keyboard_functions, 0
; mov al, 0xED ; Keyboard LEDs - only for testing!
; call kb_write
; call kb_read
926,6 → 968,7
call set_lights
;// mike.dld ]
stdcall attach_int_handler, 1, irq1, 0
.no_keyboard:
 
; SET MOUSE
 
1047,6 → 1090,7
call checkidle
call check_fdd_motor_status
call check_ATAPI_device_event
call check_lights_state
call check_timers
jmp osloop
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2010,6 → 2054,8
dd sysfn_meminfo ; 20 = get extended memory info
dd sysfn_pid_to_slot ; 21 = get slot number for pid
dd sysfn_min_rest_window ; 22 = minimize and restore any window
dd sysfn_min_windows ; 23 = minimize all windows
dd sysfn_set_screen_sizes ; 24 = set screen sizes for Vesa
sysfn_num = ($ - sys_system_table)/4
endg
;------------------------------------------------------------------------------
2083,8 → 2129,6
jne noatsc
and [application_table_status], 0
noatsc:
; for guarantee the updating data
call change_task
noprocessterminate:
add esp, 4
ret
2324,20 → 2368,19
shl eax, 2
mov [esp+32], eax
ret
 
;------------------------------------------------------------------------------
sysfn_getallmem:
mov eax, [MEM_AMOUNT]
shr eax, 10
mov [esp+32], eax
ret
 
; // Alver, 2007-22-08 // {
;------------------------------------------------------------------------------
sysfn_pid_to_slot:
mov eax, ecx
call pid_to_slot
mov [esp+32], eax
ret
 
;------------------------------------------------------------------------------
sysfn_min_rest_window:
pushad
mov eax, edx ; ebx - operating
2368,14 → 2411,52
dec eax
mov [esp+32], eax
ret
; } \\ Alver, 2007-22-08 \\
;------------------------------------------------------------------------------
sysfn_min_windows:
call minimize_all_window
mov [esp+32], eax
call change_task
ret
;------------------------------------------------------------------------------
sysfn_set_screen_sizes:
cmp [SCR_MODE], word 0x13
jbe .exit
 
cmp [_display.select_cursor], select_cursor
jne .exit
 
cmp ecx, [display_width_standard]
ja .exit
 
cmp edx, [display_height_standard]
ja .exit
 
pushfd
cli
mov eax, ecx
mov ecx, [BytesPerScanLine]
mov [_display.width], eax
dec eax
mov [_display.height], edx
dec edx
; eax - new Screen_Max_X
; edx - new Screen_Max_Y
mov [do_not_touch_winmap], 1
call set_screen
mov [do_not_touch_winmap], 0
popfd
call change_task
.exit:
ret
;------------------------------------------------------------------------------
uglobal
;// mike.dld, 2006-29-01 [
screen_workarea RECT
;// mike.dld, 2006-29-01 ]
display_width_standard dd 0
display_height_standard dd 0
do_not_touch_winmap db 0
window_minimize db 0
sound_flag db 0
 
endg
 
UID_NONE=0
2430,10 → 2511,9
cmp ebx, 1 ; BACKGROUND SIZE
jnz nosb1
test ecx, ecx
; cmp ecx,0
jz sbgrr
 
test edx, edx
; cmp edx,0
jz sbgrr
;--------------------------------------
align 4
2703,9 → 2783,52
;------------------------------------------------------------------------------
align 4
nosb8:
cmp ebx, 9
jnz nosb9
; ecx = [left]*65536 + [right]
; edx = [top]*65536 + [bottom]
mov eax, [Screen_Max_X]
mov ebx, [Screen_Max_Y]
; check [right]
cmp cx, ax
ja .exit
; check [left]
ror ecx, 16
cmp cx, ax
ja .exit
; check [bottom]
cmp dx, bx
ja .exit
; check [top]
ror edx, 16
cmp dx, bx
ja .exit
 
movzx eax, cx ; [left]
movzx ebx, dx ; [top]
 
shr ecx, 16 ; [right]
shr edx, 16 ; [bottom]
 
mov [background_defined], 1
 
mov [draw_data+32 + RECT.left], eax
mov [draw_data+32 + RECT.top], ebx
 
mov [draw_data+32 + RECT.right], ecx
mov [draw_data+32 + RECT.bottom], edx
 
inc byte[REDRAW_BACKGROUND]
;--------------------------------------
align 4
.exit:
ret
;------------------------------------------------------------------------------
align 4
nosb9:
ret
;------------------------------------------------------------------------------
align 4
uglobal
BG_Rect_X_left_right dd 0x0
BG_Rect_Y_top_bottom dd 0x0
3297,9 → 3420,7
;--------------------------------------
align 4
mouse_not_active:
xor eax, eax
xchg al, [REDRAW_BACKGROUND]
test al, al ; background update ?
cmp byte[REDRAW_BACKGROUND], 0 ; background update ?
jz nobackgr
 
cmp [background_defined], 0
3320,6 → 3441,9
pop eax
 
call drawbackground
; DEBUGF 1, "K : drawbackground\n"
; DEBUGF 1, "K : backg x %x\n",[BG_Rect_X_left_right]
; DEBUGF 1, "K : backg y %x\n",[BG_Rect_Y_top_bottom]
;--------- set event 5 start ----------
push ecx edi
xor edi, edi
3334,9 → 3458,7
; call change_task - because the application must have time to call f.15.8
call change_task
;--------- set event 5 stop -----------
xor eax, eax
xchg al, [REDRAW_BACKGROUND]
test al, al ; got new update request?
dec byte[REDRAW_BACKGROUND] ; got new update request?
jnz @b
 
mov [draw_data+32 + RECT.left], eax
3994,6 → 4116,14
;--------------------------------------
align 4
@@:
cmp esi, 9
jnz @f
mov ebp, putimage_get9bpp
mov esi, putimage_init9bpp
jmp sys_putimage_bpp
;--------------------------------------
align 4
@@:
cmp esi, 15
jnz @f
mov ebp, putimage_get15bpp
4054,6 → 4184,7
putimage_init24bpp:
lea eax, [eax*3]
putimage_init8bpp:
putimage_init9bpp:
ret
;-----------------------------------------------------------------------------
align 16
4074,6 → 4205,14
inc esi
ret 4
;-----------------------------------------------------------------------------
align 16
putimage_get9bpp:
lodsb
mov ah, al
shl eax, 8
mov al, ah
ret 4
;-----------------------------------------------------------------------------
align 4
putimage_init1bpp:
add eax, ecx
4500,17 → 4639,17
dd sys_process_def.1 ; 1 = set keyboard mode
dd sys_process_def.2 ; 2 = get keyboard mode
dd sys_process_def.3 ; 3 = get keyboard ctrl, alt, shift
dd sys_process_def.4
dd sys_process_def.5
dd sys_process_def.4 ; 4 = set system-wide hotkey
dd sys_process_def.5 ; 5 = delete installed hotkey
dd sys_process_def.6 ; 6 = disable input, work only hotkeys
dd sys_process_def.7 ; 7 = enable input, opposition to f.66.6
endg
 
 
 
 
;-----------------------------------------------------------------------------
align 4
sys_process_def:
dec ebx
cmp ebx, 5
jae .not_support ;if >=6 then or eax,-1
cmp ebx, 7
jae .not_support ;if >=8 then or eax,-1
 
mov edi, [CURRENT_TASK]
jmp dword [f66call+ebx*4]
4518,33 → 4657,28
.not_support:
or eax, -1
ret
 
;-----------------------------------------------------------------------------
align 4
.1:
shl edi, 8
mov [edi+SLOT_BASE + APPDATA.keyboard_mode], cl
 
ret
 
;-----------------------------------------------------------------------------
align 4
.2: ; 2 = get keyboard mode
shl edi, 8
movzx eax, byte [SLOT_BASE+edi + APPDATA.keyboard_mode]
mov [esp+32], eax
ret
; xor eax,eax
; movzx eax,byte [shift]
; movzx ebx,byte [ctrl]
; shl ebx,2
; add eax,ebx
; movzx ebx,byte [alt]
; shl ebx,3
; add eax,ebx
;-----------------------------------------------------------------------------
align 4
.3: ;3 = get keyboard ctrl, alt, shift
;// mike.dld [
mov eax, [kb_state]
;// mike.dld ]
mov [esp+32], eax
ret
 
;-----------------------------------------------------------------------------
align 4
.4:
mov eax, hotkey_list
@@:
4569,7 → 4703,8
@@:
and dword [esp+32], 0
ret
 
;-----------------------------------------------------------------------------
align 4
.5:
movzx ebx, cl
lea ebx, [hotkey_scancodes+ebx*4]
4603,8 → 4738,45
mov [eax], edx
mov [esp+32], edx
ret
;-----------------------------------------------------------------------------
align 4
.6:
pushfd
cli
mov eax, [PID_lock_input]
test eax, eax
jnz @f
; get current PID
mov eax, [CURRENT_TASK]
shl eax, 5
mov eax, [eax+CURRENT_TASK+TASKDATA.pid]
; set current PID for lock input
mov [PID_lock_input], eax
@@:
popfd
ret
;-----------------------------------------------------------------------------
align 4
.7:
mov eax, [PID_lock_input]
test eax, eax
jz @f
; get current PID
mov ebx, [CURRENT_TASK]
shl ebx, 5
mov ebx, [ebx+CURRENT_TASK+TASKDATA.pid]
; compare current lock input with current PID
cmp ebx, eax
jne @f
 
 
xor eax, eax
mov [PID_lock_input], eax
@@:
ret
;-----------------------------------------------------------------------------
uglobal
PID_lock_input dd 0x0
endg
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 61 sys function. ;;
;; in eax=61,ebx in [1..3] ;;
4961,7 → 5133,7
align 4
.no_put:
pop ecx eax
 
sub ebp, 4
dec ecx
jnz .start_x
5020,22 → 5192,6
mov [esp+32], eax
ret
 
align 4
 
read_from_hd: ; Read from hd - fn not in use
 
mov edi, [TASK_BASE]
add edi, TASKDATA.mem_start
add eax, [edi]
add ecx, [edi]
add edx, [edi]
call file_read
 
mov [esp+36], eax
mov [esp+24], ebx
 
ret
 
paleholder:
ret
;------------------------------------------------------------------------------
5071,6 → 5227,10
;------------------------------------------------------------------------------
align 4
set_screen:
; in:
; eax - new Screen_Max_X
; ecx - new BytesPerScanLine
; edx - new Screen_Max_Y
cmp eax, [Screen_Max_X]
jne .set
 
5094,6 → 5254,9
 
pushad
 
cmp [do_not_touch_winmap], 1
je @f
 
stdcall kernel_free, [_WinMapAddress]
 
mov eax, [_display.width]
5104,9 → 5267,18
mov [_WinMapAddress], eax
test eax, eax
jz .epic_fail
; store for f.18.24
mov eax, [_display.width]
mov [display_width_standard], eax
 
mov eax, [_display.height]
mov [display_height_standard], eax
@@:
call calculate_fast_getting_offset_for_WinMapAddress
 
; for Qemu or non standart video cards
; Unfortunately [BytesPerScanLine] does not always
; equal to [_display.width] * [ScreenBPP] / 8
call calculate_fast_getting_offset_for_LFB
popad
 
call repos_windows
/kernel/branches/net/memmap.inc
144,14 → 144,14
; FFFF byte do not change task for 1/100 sec.
;
; 0x80010000 -> 6CBFF kernel, 32-bit run-time code (up to 371 Kb)
 
; 0x8006CC00 -> 6DBFF stack at boot time (4Kb)
;
; 0x8006DC00 -> 6E5FF basic text font II
; 0x8006E600 -> 6Efff basic text font I
; 0x8006F000 -> 6FFFF main page directory
 
; 0x80070000 -> 7FFFF data of retrieved disks and partitions (Mario79)
 
; 0x8006CC00 -> 6DBFF stack at boot time (4Kb)
;
; 0x8006DC00 -> 6E5FF free (2560)
; 0x8006E600 -> 6Efff free (2560)
; 0x8006F000 -> 6FFFF main page directory
 
; 0x80070000 -> 7FFFF data of retrieved disks and partitions (Mario79)
; 0x80080000 -> 8FFFF additional app info, in 256 byte steps - 256 entries
;
; 00 11db name of app running
/kernel/branches/net/video/blitter.inc
14,8 → 14,8
 
 
struct BLITTER
dc BLITTER_BLOCK
sc BLITTER_BLOCK
dc RECT
sc RECT
dst_x dd ? ; 32
dst_y dd ? ; 36
src_x dd ? ; 40
28,180 → 28,111
ends
 
 
 
align 4
block_clip:
;esi= clip RECT ptr
;edi= RECT ptr
;return code:
;eax= 0 - draw, 1 - don't draw
 
__L1OutCode:
push ebx
mov ebx, 8
cmp edx, [eax]
jl .L2
xor ebx, ebx
cmp edx, [eax+8]
setg bl
sal ebx, 2
.L2:
cmp ecx, [eax+4]
jge .L3
or ebx, 1
jmp .L4
 
.L3:
cmp ecx, [eax+12]
jle .L4
or ebx, 2
.L4:
mov eax, ebx
pop ebx
ret
 
align 4
block_clip:
push ebp
push edi
push ebx
 
mov eax, [edi+RECT.left]
mov ebx, [edi+RECT.right]
mov ecx, [esi+RECT.left] ;clip.left
mov edx, [esi+RECT.right] ;clip.right
 
cmp eax, edx ;left >= clip.right
jge .fail
 
cmp ebx, ecx ;right < clip.left
jl .fail
 
cmp eax, ecx ;left >= clip.left
jae @F
 
mov eax, ecx
@@:
mov [edi+RECT.left], eax
 
cmp ebx, edx ;right <= clip.right
jle @f
mov ebx, edx
@@:
mov [edi+RECT.right], ebx
 
mov eax, [edi+RECT.top]
mov ebx, [edi+RECT.bottom]
mov ecx, [esi+RECT.top] ;clip.top
mov edx, [esi+RECT.bottom] ;clip.bottom
 
cmp eax, edx ;top >= clip.bottom
jge .fail
 
cmp ebx, ecx ;bottom < clip.top
jl .fail
 
cmp eax, ecx ;top >= clip.top
jae @F
 
mov eax, ecx
@@:
mov [edi+RECT.top], eax
 
cmp ebx, edx ;bottom <= clip.bottom
jle @f
mov ebx, edx
@@:
mov [edi+RECT.bottom], ebx
pop ebx
xor eax, eax
ret
.fail:
pop ebx
mov eax, 1
ret
 
 
align 4
blit_clip:
 
.sx0 equ 8
.sy0 equ 12
.sx1 equ 16
.sy1 equ 20
 
.dx0 equ 24
.dy0 equ 28
.dx1 equ 32
.dy1 equ 36
 
 
push edi
push esi
push ebx
sub esp, 4
 
mov ebx, eax
mov [esp], edx
mov ebp, ecx
mov ecx, [ecx]
mov edx, [edx]
call __L1OutCode
 
mov esi, eax
mov edx, [esp+28]
mov ecx, [edx]
.L21:
mov eax, [esp+24]
mov edx, [eax]
mov eax, ebx
call __L1OutCode
 
mov edi, eax
.L20:
mov eax, edi
and eax, esi
jne .L9
cmp esi, edi
je .L9
test esi, esi
jne .L10
test edi, 1
je .L11
mov eax, [ebx+4]
jmp .L25
.L11:
test edi, 2
je .L13
mov eax, [ebx+12]
.L25:
mov edx, [esp+28]
jmp .L22
.L13:
test edi, 4
je .L14
mov eax, [ebx+8]
jmp .L26
.L14:
and edi, 8
je .L12
mov eax, [ebx]
.L26:
mov edx, [esp+24]
.L22:
mov [edx], eax
.L12:
mov eax, [esp+28]
mov ecx, [eax]
jmp .L21
.L10:
test esi, 1
je .L16
mov eax, [ebx+4]
jmp .L23
.L16:
test esi, 2
je .L18
mov eax, [ebx+12]
.L23:
mov [ebp+0], eax
jmp .L17
.L18:
test esi, 4
je .L19
mov eax, [ebx+8]
jmp .L24
.L19:
and esi, 8
je .L17
mov eax, [ebx]
.L24:
mov edx, [esp]
mov [edx], eax
.L17:
mov ecx, [ebp+0]
mov eax, [esp]
mov edx, [eax]
mov eax, ebx
call __L1OutCode
mov esi, eax
jmp .L20
.L9:
add esp, 4
pop ebx
pop esi
pop edi
pop ebp
ret
 
align 4
blit_clip:
 
.sx0 equ 36
.sy0 equ 32
.sx1 equ 28
.sy1 equ 24
 
.dx0 equ 20
.dy0 equ 16
.dx1 equ 12
.dy1 equ 8
 
 
push edi
push esi
push ebx
sub esp, 40
 
mov ebx, ecx
mov edx, [ecx+BLITTER.src_x]
mov [esp+.sx0], edx
mov eax, [ecx+BLITTER.src_y]
mov [esp+.sy0], eax
add edx, [ecx+BLITTER.w]
dec edx
mov [esp+.sx1], edx
add eax, [ecx+BLITTER.h]
dec eax
mov [esp+.sy1], eax
 
lea ecx, [esp+.sy0]
lea edx, [esp+.sx0]
lea eax, [ebx+BLITTER.sc]
lea esi, [esp+.sy1]
 
mov [esp+4], esi
lea esi, [esp+.sx1]
mov [esp], esi
call block_clip
 
mov esi, 1
test eax, eax
jne .L28
 
mov edi, [esp+.sx0]
mov edx, [ebx+BLITTER.dst_x]
mov eax, [ecx+BLITTER.src_y]
mov [esp+.sy0], eax
add edx, [ecx+BLITTER.w]
add eax, [ecx+BLITTER.h]
mov [esp+.sx1], edx
mov [esp+.sy1], eax
 
lea edi, [esp+.sx0]
lea esi, [ebx+BLITTER.sc]
 
call block_clip
test eax, eax
mov esi, 1
jnz .done
 
mov edi, [esp+.sx0]
mov edx, [ebx+BLITTER.dst_x]
add edx, edi
sub edx, [ebx+BLITTER.src_x]
mov [esp+.dx0], edx
208,40 → 139,35
 
mov ecx, [esp+.sy0]
mov eax, [ebx+BLITTER.dst_y]
add eax, ecx
sub eax, [ebx+BLITTER.src_y]
mov [esp+.dy0], eax
sub edx, edi
add edx, [esp+.sx1]
mov [esp+.dx1], edx
add eax, ecx
sub eax, [ebx+BLITTER.src_y]
mov [esp+.dy0], eax
 
sub edx, edi
add edx, [esp+.sx1]
mov [esp+.dx1], edx
 
sub eax, ecx
add eax, [esp+.sy1]
mov [esp+.dy1], eax
 
lea ecx, [esp+.dy0]
lea edx, [esp+.dx0]
lea eax, [esp+.dy1]
mov [esp+4], eax
lea eax, [esp+.dx1]
mov [esp], eax
mov eax, ebx
call block_clip
test eax, eax
jne .L28
 
mov edx, [esp+.dx0]
mov eax, [esp+.dx1]
inc eax
sub eax, edx
mov [ebx+BLITTER.w], eax
 
mov eax, [esp+.dy0]
mov ecx, [esp+.dy1]
inc ecx
sub ecx, eax
mov [ebx+BLITTER.h], ecx
 
add eax, [esp+.sy1]
mov [esp+.dy1], eax
 
lea edi, [esp+.dx0]
lea esi, [ebx+BLITTER.dc]
call block_clip
test eax, eax
mov esi, 1
jnz .done
 
mov edx, [esp+.dx0]
mov eax, [esp+.dx1]
sub eax, edx
mov [ebx+BLITTER.w], eax
 
mov eax, [esp+.dy0]
mov ecx, [esp+.dy1]
sub ecx, eax
mov [ebx+BLITTER.h], ecx
 
mov ecx, [ebx+BLITTER.src_x]
add ecx, edx
sub ecx, [ebx+BLITTER.dst_x]
251,13 → 177,13
add ecx, eax
sub ecx, [ebx+BLITTER.dst_y]
mov [ebx+BLITTER.src_y], ecx
mov [ebx+BLITTER.dst_x], edx
mov [ebx+BLITTER.dst_y], eax
xor esi, esi
.L28:
mov eax, esi
add esp, 40
pop ebx
mov [ebx+BLITTER.dst_x], edx
mov [ebx+BLITTER.dst_y], eax
xor esi, esi
.done:
mov eax, esi
add esp, 40
pop ebx
pop esi
pop edi
 
271,43 → 197,42
purge .dy0
purge .dx1
purge .dy1
 
ret
 
 
 
align 4
 
blit_32:
push ebp
push edi
 
ret
 
align 4
blit_32:
push ebp
push edi
push esi
push ebx
sub esp, 72
 
mov eax, [TASK_BASE]
mov ebx, [eax-twdw + WDATA.box.width]
mov edx, [eax-twdw + WDATA.box.height]
 
xor eax, eax
 
mov [esp+BLITTER.dc.xmin], eax
mov [esp+BLITTER.dc.ymin], eax
mov [esp+BLITTER.dc.xmax], ebx
mov [esp+BLITTER.dc.ymax], edx
 
mov [esp+BLITTER.sc.xmin], eax
mov [esp+BLITTER.sc.ymin], eax
mov eax, [ecx+24]
dec eax
mov [esp+BLITTER.sc.xmax], eax
mov eax, [ecx+28]
dec eax
mov [esp+BLITTER.sc.ymax], eax
 
mov eax, [ecx]
mov [esp+BLITTER.dst_x], eax
mov eax, [ecx+4]
mov eax, [TASK_BASE]
mov ebx, [eax-twdw + WDATA.box.width]
mov edx, [eax-twdw + WDATA.box.height]
inc ebx
inc edx
 
xor eax, eax
 
mov [esp+BLITTER.dc.left], eax
mov [esp+BLITTER.dc.top], eax
mov [esp+BLITTER.dc.right], ebx
mov [esp+BLITTER.dc.bottom], edx
 
mov [esp+BLITTER.sc.left], eax
mov [esp+BLITTER.sc.top], eax
mov eax, [ecx+24]
 
mov [esp+BLITTER.sc.right], eax
mov eax, [ecx+28]
 
mov [esp+BLITTER.sc.bottom], eax
 
mov eax, [ecx]
mov [esp+BLITTER.dst_x], eax
mov eax, [ecx+4]
mov [esp+BLITTER.dst_y], eax
 
mov eax, [ecx+16]
429,7 → 354,7
 
.done:
; call [draw_pointer]
call __sys_draw_pointer
; call __sys_draw_pointer
.L57:
add esp, 72
pop ebx
/kernel/branches/net/video/cursors.inc
444,22 → 444,17
.fail2:
ret
endp
;------------------------------------------------------------------------------
align 4
proc delete_cursor stdcall, hcursor:dword
locals
hsrv dd ?
io_code dd ?
input dd ?
inp_size dd ?
output dd ?
out_size dd ?
endl
 
mov esi, [hcursor]
cmp [esi+CURSOR.magic], 'CURS'
jne .fail
 
;------------------------------------------------------------------------------
align 4
proc delete_cursor stdcall, hcursor:dword
 
; DEBUGF 1,'K : delete_cursor %x\n', [hcursor]
 
mov esi, [hcursor]
 
cmp [esi+CURSOR.magic], 'CURS'
jne .fail
 
mov ebx, [CURRENT_TASK]
shl ebx, 5
mov ebx, [CURRENT_TASK+ebx+4]
639,12 → 634,14
mov [cur.bottom], edi
 
sub ebx, [x]
sub edi, [y]
inc ebx
inc edi
 
mov [cur.w], ebx
mov [cur.h], edi
sub edi, [y]
inc ebx
inc edi
sub ebx, [_dx]
sub edi, [_dy]
 
mov [cur.w], ebx
mov [cur.h], edi
mov [h], edi
 
mov eax, edi
755,12 → 752,14
mov [cur.bottom], edi
 
sub ebx, [x]
sub edi, [y]
inc ebx
inc edi
 
mov [cur.w], ebx
mov [cur.h], edi
sub edi, [y]
inc ebx
inc edi
sub ebx, [_dx]
sub edi, [_dy]
 
mov [cur.w], ebx
mov [cur.h], edi
mov [h], edi
 
mov eax, edi
832,16 → 831,16
 
cmp ax, [X_UNDER_sub_CUR_hot_x_add_curh]
jae .no_mouse_area
;--------------------------------------
push eax ebx
; offset X
mov ecx, [X_UNDER_subtraction_CUR_hot_x]
sub eax, ecx ; x1
; offset Y
mov ecx, [Y_UNDER_subtraction_CUR_hot_y]
sub ebx, ecx ; y1
;--------------------------------------
; ebx = offset y
;--------------------------------------
push eax ebx
; offset X
movzx ecx, word [X_UNDER_subtraction_CUR_hot_x]
sub eax, ecx ; x1
; offset Y
movzx ecx, word [Y_UNDER_subtraction_CUR_hot_y]
sub ebx, ecx ; y1
;--------------------------------------
; ebx = offset y
; eax = offset x
imul ebx, [cur.w] ;y
add eax, ebx
871,48 → 870,56
; ecx = x shl 16 + y
; eax = color
; out:
; eax = new color
;--------------------------------------
; check for Y
cmp cx, [Y_UNDER_subtraction_CUR_hot_y]
jb .no_mouse_area
 
cmp cx, [Y_UNDER_sub_CUR_hot_y_add_curh]
jae .no_mouse_area
 
rol ecx, 16
;--------------------------------------
; check for X
cmp cx, [X_UNDER_subtraction_CUR_hot_x]
jb .no_mouse_area
 
cmp cx, [X_UNDER_sub_CUR_hot_x_add_curh]
jae .no_mouse_area
;--------------------------------------
align 4
.1:
push eax
; offset X
mov ax, [X_UNDER_subtraction_CUR_hot_x]
sub cx, ax ; x1
ror ecx, 16
; offset Y
mov ax, [Y_UNDER_subtraction_CUR_hot_y]
sub cx, ax ; y1
;--------------------------------------
; ecx = (offset x) shl 16 + (offset y)
push ebx
; eax = new color
;--------------------------------------
; check for Y
cmp cx, [Y_UNDER_sub_CUR_hot_y_add_curh]
jae .no_mouse_area
 
sub cx, [Y_UNDER_subtraction_CUR_hot_y]
jb .no_mouse_area
 
rol ecx, 16
;--------------------------------------
; check for X
cmp cx, [X_UNDER_sub_CUR_hot_x_add_curh]
jae .no_mouse_area
 
sub cx, [X_UNDER_subtraction_CUR_hot_x]
jb .no_mouse_area
 
ror ecx, 16
;--------------------------------------
align 4
.1:
push eax
;--------------------------------------
; ecx = (offset x) shl 16 + (offset y)
push ebx
mov ebx, ecx
shr ebx, 16 ; x
and ecx, 0xffff ; y
 
cmp ecx, [cur.h]
jae @f
 
cmp ebx, [cur.w]
jb .ok
;--------------------------------------
align 4
@@:
; DEBUGF 1, "K : SHIT HAPPENS: %x %x \n", ecx,ebx
pop ebx
jmp .sh ; SORRY! SHIT HAPPENS!
;--------------------------------------
align 4
.ok:
; ecx = offset y
; ebx = offset x
push ebx ecx
imul ecx, [cur.w] ;y
add ecx, ebx
mov ebx, ecx
shr ebx, 16 ; x
and ecx, 0xffff ; y
; ecx = offset y
; ebx = offset x
mov eax, [esp + 4]
 
push ebx ecx
imul ecx, [cur.w] ;y
add ecx, ebx
mov ebx, ecx
shl ecx, 2
cmp [ScreenBPP], byte 24
je .24
941,17 → 948,21
 
pop ebx
 
test eax, 0xFF000000
jz @f
 
pop ecx
ret
;--------------------------------------
test eax, 0xFF000000
jz @f
 
add esp, 4
ret
;--------------------------------------
align 4
.sh:
mov ecx, -1
;--------------------------------------
align 4
@@:
pop eax
;--------------------------------------
align 4
@@:
pop eax
;--------------------------------------
align 4
.no_mouse_area:
ret
;------------------------------------------------------------------------------
/kernel/branches/net/video/vesa20.inc
403,35 → 403,44
mov eax, [putimg.ebp+4]
call eax
cmp [ebp], bl
jne .skip
;--------------------------------------
push ecx
mov ecx, [putimg.real_sy_and_abs_cy + 4]
sub ecx, edi
;--------------------------------------
; check for Y
cmp cx, [Y_UNDER_subtraction_CUR_hot_y]
jb .no_mouse_area
 
cmp cx, [Y_UNDER_sub_CUR_hot_y_add_curh]
jae .no_mouse_area
 
rol ecx, 16
add ecx, [putimg.real_sx_and_abs_cx + 4]
sub ecx, [esp]
;--------------------------------------
; check for X
cmp cx, [X_UNDER_subtraction_CUR_hot_x]
jb .no_mouse_area
 
cmp cx, [X_UNDER_sub_CUR_hot_x_add_curh]
jae .no_mouse_area
;--------------------------------------
; check mouse area for putpixel
call check_mouse_area_for_putpixel_new.1
;--------------------------------------
align 4
.no_mouse_area:
jne .skip
;--------------------------------------
push ecx
;--------------------------------------
align 4
.sh:
neg ecx
add ecx, [putimg.real_sx_and_abs_cx + 4]
;--------------------------------------
; check for X
cmp cx, [X_UNDER_sub_CUR_hot_x_add_curh]
jae .no_mouse_area
 
sub cx, [X_UNDER_subtraction_CUR_hot_x]
jb .no_mouse_area
 
shl ecx, 16
 
add ecx, [putimg.real_sy_and_abs_cy + 4]
sub ecx, edi
;--------------------------------------
; check for Y
cmp cx, [Y_UNDER_sub_CUR_hot_y_add_curh]
jae .no_mouse_area
 
sub cx, [Y_UNDER_subtraction_CUR_hot_y]
jb .no_mouse_area
;--------------------------------------
; check mouse area for putpixel
call check_mouse_area_for_putpixel_new.1
cmp ecx, -1 ;SHIT HAPPENS?
jne .no_mouse_area
 
mov ecx, [esp]
jmp .sh
;--------------------------------------
align 4
.no_mouse_area:
pop ecx
; store to real LFB
mov [LFB_BASE+edx], ax
605,35 → 614,44
mov eax, [putimg.ebp+4]
call eax
cmp [ebp], bl
jne .skip
;--------------------------------------
push ecx
mov ecx, [putimg.real_sy_and_abs_cy + 4]
sub ecx, edi
;--------------------------------------
; check for Y
cmp cx, [Y_UNDER_subtraction_CUR_hot_y]
jb .no_mouse_area
 
cmp cx, [Y_UNDER_sub_CUR_hot_y_add_curh]
jae .no_mouse_area
 
rol ecx, 16
add ecx, [putimg.real_sx_and_abs_cx + 4]
sub ecx, [esp]
;--------------------------------------
; check for X
cmp cx, [X_UNDER_subtraction_CUR_hot_x]
jb .no_mouse_area
 
cmp cx, [X_UNDER_sub_CUR_hot_x_add_curh]
jae .no_mouse_area
;--------------------------------------
; check mouse area for putpixel
call check_mouse_area_for_putpixel_new.1
;--------------------------------------
align 4
.no_mouse_area:
jne .skip
;--------------------------------------
push ecx
;--------------------------------------
align 4
.sh:
neg ecx
add ecx, [putimg.real_sx_and_abs_cx + 4]
;--------------------------------------
; check for X
cmp cx, [X_UNDER_sub_CUR_hot_x_add_curh]
jae .no_mouse_area
 
sub cx, [X_UNDER_subtraction_CUR_hot_x]
jb .no_mouse_area
 
shl ecx, 16
 
add ecx, [putimg.real_sy_and_abs_cy + 4]
sub ecx, edi
;--------------------------------------
; check for Y
cmp cx, [Y_UNDER_sub_CUR_hot_y_add_curh]
jae .no_mouse_area
 
sub cx, [Y_UNDER_subtraction_CUR_hot_y]
jb .no_mouse_area
;--------------------------------------
; check mouse area for putpixel
call check_mouse_area_for_putpixel_new.1
cmp ecx, -1 ;SHIT HAPPENS?
jne .no_mouse_area
 
mov ecx, [esp]
jmp .sh
;--------------------------------------
align 4
.no_mouse_area:
pop ecx
; store to real LFB
mov [LFB_BASE+edx], eax
764,27 → 782,29
jne @f
; check mouse area for putpixel
test eax, 0x04000000
jnz @f
;--------------------------------------
; check for Y
cmp cx, [Y_UNDER_subtraction_CUR_hot_y]
jb @f
 
cmp cx, [Y_UNDER_sub_CUR_hot_y_add_curh]
jae @f
 
rol ecx, 16
;--------------------------------------
; check for X
cmp cx, [X_UNDER_subtraction_CUR_hot_x]
jb @f
 
cmp cx, [X_UNDER_sub_CUR_hot_x_add_curh]
jae @f
 
call check_mouse_area_for_putpixel_new.1
;--------------------------------------
align 4
jnz @f
;--------------------------------------
; check for Y
cmp cx, [Y_UNDER_sub_CUR_hot_y_add_curh]
jae @f
 
sub cx, [Y_UNDER_subtraction_CUR_hot_y]
jb @f
 
rol ecx, 16
;--------------------------------------
; check for X
cmp cx, [X_UNDER_sub_CUR_hot_x_add_curh]
jae @f
 
sub cx, [X_UNDER_subtraction_CUR_hot_x]
jb @f
 
ror ecx, 16
 
call check_mouse_area_for_putpixel_new.1
;--------------------------------------
align 4
@@:
; store to real LFB
mov [LFB_BASE+ebx+edi], ax
838,27 → 858,29
jne @f
; check mouse area for putpixel
test eax, 0x04000000
jnz @f
;--------------------------------------
; check for Y
cmp cx, [Y_UNDER_subtraction_CUR_hot_y]
jb @f
 
cmp cx, [Y_UNDER_sub_CUR_hot_y_add_curh]
jae @f
 
rol ecx, 16
;--------------------------------------
; check for X
cmp cx, [X_UNDER_subtraction_CUR_hot_x]
jb @f
 
cmp cx, [X_UNDER_sub_CUR_hot_x_add_curh]
jae @f
 
call check_mouse_area_for_putpixel_new.1
;--------------------------------------
align 4
jnz @f
;--------------------------------------
; check for Y
cmp cx, [Y_UNDER_sub_CUR_hot_y_add_curh]
jae @f
 
sub cx, [Y_UNDER_subtraction_CUR_hot_y]
jb @f
 
rol ecx, 16
;--------------------------------------
; check for X
cmp cx, [X_UNDER_sub_CUR_hot_x_add_curh]
jae @f
 
sub cx, [X_UNDER_subtraction_CUR_hot_x]
jb @f
 
ror ecx, 16
 
call check_mouse_area_for_putpixel_new.1
;--------------------------------------
align 4
@@:
and eax, 0xffffff
; store to real LFB
1369,28 → 1391,30
jne .skip
;--------------------------------------
mov ecx, [drbar.real_sy_and_abs_cy]
sub ecx, esi
;--------------------------------------
; check for Y
cmp cx, [Y_UNDER_subtraction_CUR_hot_y]
jb .no_mouse_area
 
cmp cx, [Y_UNDER_sub_CUR_hot_y_add_curh]
jae .no_mouse_area
 
rol ecx, 16
add ecx, [drbar.real_sx_and_abs_cx]
sub ecx, edi
;--------------------------------------
; check for X
cmp cx, [X_UNDER_subtraction_CUR_hot_x]
jb .no_mouse_area
 
cmp cx, [X_UNDER_sub_CUR_hot_x_add_curh]
jae .no_mouse_area
;--------------------------------------
; check mouse area for putpixel
push eax
sub ecx, esi
;--------------------------------------
; check for Y
cmp cx, [Y_UNDER_sub_CUR_hot_y_add_curh]
jae .no_mouse_area
 
sub cx, [Y_UNDER_subtraction_CUR_hot_y]
jb .no_mouse_area
 
rol ecx, 16
add ecx, [drbar.real_sx_and_abs_cx]
sub ecx, edi
;--------------------------------------
; check for X
cmp cx, [X_UNDER_sub_CUR_hot_x_add_curh]
jae .no_mouse_area
 
sub cx, [X_UNDER_subtraction_CUR_hot_x]
jb .no_mouse_area
 
ror ecx, 16
;--------------------------------------
; check mouse area for putpixel
push eax
call check_mouse_area_for_putpixel_new.1
mov [edx], ax
shr eax, 16
1554,28 → 1578,30
jne .skip
;--------------------------------------
mov ecx, [drbar.real_sy_and_abs_cy]
sub ecx, esi
;--------------------------------------
; check for Y
cmp cx, [Y_UNDER_subtraction_CUR_hot_y]
jb .no_mouse_area
 
cmp cx, [Y_UNDER_sub_CUR_hot_y_add_curh]
jae .no_mouse_area
 
rol ecx, 16
add ecx, [drbar.real_sx_and_abs_cx]
sub ecx, edi
;--------------------------------------
; check for X
cmp cx, [X_UNDER_subtraction_CUR_hot_x]
jb .no_mouse_area
 
cmp cx, [X_UNDER_sub_CUR_hot_x_add_curh]
jae .no_mouse_area
;--------------------------------------
; check mouse area for putpixel
push eax
sub ecx, esi
;--------------------------------------
; check for Y
cmp cx, [Y_UNDER_sub_CUR_hot_y_add_curh]
jae .no_mouse_area
 
sub cx, [Y_UNDER_subtraction_CUR_hot_y]
jb .no_mouse_area
 
rol ecx, 16
add ecx, [drbar.real_sx_and_abs_cx]
sub ecx, edi
;--------------------------------------
; check for X
cmp cx, [X_UNDER_sub_CUR_hot_x_add_curh]
jae .no_mouse_area
 
sub cx, [X_UNDER_subtraction_CUR_hot_x]
jb .no_mouse_area
 
ror ecx, 16
;--------------------------------------
; check mouse area for putpixel
push eax
call check_mouse_area_for_putpixel_new.1
mov [edx], eax
pop eax