diff --git a/kernel/branches/net/blkdev/disk.inc b/kernel/branches/net/blkdev/disk.inc index 3ff11425f0..fecdf96c27 100644 --- a/kernel/branches/net/blkdev/disk.inc +++ b/kernel/branches/net/blkdev/disk.inc @@ -347,14 +347,16 @@ disk_add: 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 @@ disk_add: ; [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_closemedia: 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 @@ disk_detect_partition: ; 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 @@ dyndisk_handler: ; 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 @@ fs_dyndisk: 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 diff --git a/kernel/branches/net/blkdev/disk_cache.inc b/kernel/branches/net/blkdev/disk_cache.inc index 795c991b0e..6542796f40 100644 --- a/kernel/branches/net/blkdev/disk_cache.inc +++ b/kernel/branches/net/blkdev/disk_cache.inc @@ -15,15 +15,17 @@ $Revision: 2381 $ ; 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 @@ fs_read32_sys: ; 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 @@ fs_read32_common: 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 @@ end virtual 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 @@ end virtual ; 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 @@ fs_write32_sys: ; 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,34 +235,35 @@ fs_write32_common: 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 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 @@ end virtual 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 @@ find_empty_slot64: 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 @@ endl 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 @@ endl .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 @@ disk_init_cache: 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 @@ disk_init_cache: 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 @@ disk_init_cache: .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 diff --git a/kernel/branches/net/blkdev/hd_drv.inc b/kernel/branches/net/blkdev/hd_drv.inc index aa5f7c679d..374a178087 100644 --- a/kernel/branches/net/blkdev/hd_drv.inc +++ b/kernel/branches/net/blkdev/hd_drv.inc @@ -942,6 +942,86 @@ int13_call: 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 +;******************************************** diff --git a/kernel/branches/net/blkdev/ide_cache.inc b/kernel/branches/net/blkdev/ide_cache.inc index 38e2098805..309cb27282 100644 --- a/kernel/branches/net/blkdev/ide_cache.inc +++ b/kernel/branches/net/blkdev/ide_cache.inc @@ -134,14 +134,12 @@ found_slot: 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 diff --git a/kernel/branches/net/boot/preboot.inc b/kernel/branches/net/boot/preboot.inc index dd048debba..1938b126be 100644 --- a/kernel/branches/net/boot/preboot.inc +++ b/kernel/branches/net/boot/preboot.inc @@ -33,6 +33,6 @@ preboot_biosdisk db 0 ; use V86 to access disks through BIOS (1-yes, 2-no) 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 diff --git a/kernel/branches/net/boot/rdload.inc b/kernel/branches/net/boot/rdload.inc index b86a13d734..4393e7575d 100644 --- a/kernel/branches/net/boot/rdload.inc +++ b/kernel/branches/net/boot/rdload.inc @@ -86,19 +86,28 @@ $Revision $ 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) diff --git a/kernel/branches/net/const.inc b/kernel/branches/net/const.inc index 8da15d3db5..a93a9911db 100644 --- a/kernel/branches/net/const.inc +++ b/kernel/branches/net/const.inc @@ -260,15 +260,12 @@ BANK_RW equ (OS_BASE+0x000FFF2) MOUSE_BACKGROUND equ (OS_BASE+0x000FFF4) DONT_DRAW_MOUSE equ (OS_BASE+0x000FFF5) DONT_SWITCH equ (OS_BASE+0x000FFFF) - -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) + +TMP_STACK_TOP equ 0x006CC00 + +sys_pgdir equ (OS_BASE+0x006F000) + +DRIVE_DATA equ (OS_BASE+0x0070000) SLOT_BASE equ (OS_BASE+0x0080000) diff --git a/kernel/branches/net/core/dll.inc b/kernel/branches/net/core/dll.inc index 29e36beb8a..024c1eed7b 100644 --- a/kernel/branches/net/core/dll.inc +++ b/kernel/branches/net/core/dll.inc @@ -807,21 +807,13 @@ proc load_driver stdcall, driver_name:dword 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] diff --git a/kernel/branches/net/core/exports.inc b/kernel/branches/net/core/exports.inc index 274f5a4d4d..9aa44612e9 100644 --- a/kernel/branches/net/core/exports.inc +++ b/kernel/branches/net/core/exports.inc @@ -69,12 +69,15 @@ iglobal 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 @@ kernel_export: 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 diff --git a/kernel/branches/net/core/malloc.inc b/kernel/branches/net/core/malloc.inc index 2e45257d52..9c72e5051b 100644 --- a/kernel/branches/net/core/malloc.inc +++ b/kernel/branches/net/core/malloc.inc @@ -338,16 +338,15 @@ free: mov [esi+edi], esi -; insert_chunk(p,psize); - - mov eax, esi - pop esi - mov ecx, edi - pop edi - jmp insert_chunk -.unl_large: - -; unlink_large_chunk((tchunkptr)next); +; insert_chunk(p,psize); + + mov eax, esi + mov ecx, edi + call insert_chunk + jmp .fail2 +.unl_large: + +; unlink_large_chunk((tchunkptr)next); mov edx, ebx call unlink_large_chunk @@ -361,16 +360,15 @@ free: 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 @@ free: ; (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 @@ insert_chunk: 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 diff --git a/kernel/branches/net/core/memory.inc b/kernel/branches/net/core/memory.inc index 9220632335..0fd08df800 100644 --- a/kernel/branches/net/core/memory.inc +++ b/kernel/branches/net/core/memory.inc @@ -439,78 +439,89 @@ proc init_LFB 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 - 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 - +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 shr edi, 10 add edi, page_tabs @@ -521,57 +532,44 @@ proc new_mem_resize stdcall, new_size:dword 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,14 +603,18 @@ update_mem_size: ; ; retval ; eax= phisical page address - -align 4 -get_pg_addr: - shr eax, 12 - mov eax, [page_tabs+eax*4] - and eax, 0xFFFFF000 - ret - + +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 ; Now it is called from core/sys32::exc_c (see stack frame there) @@ -1250,13 +1252,13 @@ f68: 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 diff --git a/kernel/branches/net/core/peload.inc b/kernel/branches/net/core/peload.inc index 65faa50baa..eb686c3cec 100644 --- a/kernel/branches/net/core/peload.inc +++ b/kernel/branches/net/core/peload.inc @@ -297,12 +297,13 @@ __exports: 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 \ diff --git a/kernel/branches/net/core/sys32.inc b/kernel/branches/net/core/sys32.inc index b88fbb3fbd..7b45691e25 100644 --- a/kernel/branches/net/core/sys32.inc +++ b/kernel/branches/net/core/sys32.inc @@ -428,12 +428,23 @@ term9: 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 @@ term9: ;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 diff --git a/kernel/branches/net/core/taskman.inc b/kernel/branches/net/core/taskman.inc index 4d0d63c430..4c261ee4de 100644 --- a/kernel/branches/net/core/taskman.inc +++ b/kernel/branches/net/core/taskman.inc @@ -81,19 +81,21 @@ proc fs_execute hdr_mem dd ? ;0x10 hdr_i_end dd ? ;0x14 endl - - 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 + + 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 lea edi, [filename] lea ecx, [edi+1024] @@ -182,13 +184,13 @@ proc fs_execute 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 @@ end if 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 diff --git a/kernel/branches/net/core/test_malloc.asm b/kernel/branches/net/core/test_malloc.asm index e158474f88..1197e24184 100644 --- a/kernel/branches/net/core/test_malloc.asm +++ b/kernel/branches/net/core/test_malloc.asm @@ -47,18 +47,18 @@ run_test1: 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 @@ run_test3: 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 @@ run_test3: 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 @@ malloc_with_test: 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 @@ error1: 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 @@ check_range: 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 @@ error_with_code: ; 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 diff --git a/kernel/branches/net/data32.inc b/kernel/branches/net/data32.inc index 280a68b520..dcb4572e23 100644 --- a/kernel/branches/net/data32.inc +++ b/kernel/branches/net/data32.inc @@ -46,17 +46,29 @@ keymap_alt: 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,57 +78,69 @@ if lang eq ru 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 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_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 + 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 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 @@ notifyapp db '@notify',0 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' diff --git a/kernel/branches/net/detect/sear_par.inc b/kernel/branches/net/detect/sear_par.inc index 17a0520961..61c74e7012 100644 --- a/kernel/branches/net/detect/sear_par.inc +++ b/kernel/branches/net/detect/sear_par.inc @@ -130,12 +130,16 @@ search_partitions_bd: 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 diff --git a/kernel/branches/net/fs/ext2.inc b/kernel/branches/net/fs/ext2.inc index dca7c7406e..477e402452 100644 --- a/kernel/branches/net/fs/ext2.inc +++ b/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 @@ struct EXT2_DIR_STRUC 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 @@ struct EXT2_SB_STRUC 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 - -ext2_test_superblock: - cmp [fs_type], 0x83 - jne .no + 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 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 @@ ext2_setup: 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 @@ ext2_setup: 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,128 +264,242 @@ ext2_setup: 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] - 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 + + ; ╨▓ 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 ; ╨┐╤А╨╕╨▒╨░╨▓╨╕╨╝ ╨╗╨╛╨║╨░╨╗╤М╨╜╤Л╨╣ ╨░╨┤╤А╨╡╤Б inode-╨░ pop eax ; index @@ -368,81 +508,25 @@ ext2_get_inode: 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 @@ ext2_test_block_by_name: ; 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 @@ ext2_HdReadFolder: 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 @@ utf8toansi_str: ; 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 - - @@: - 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 + 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 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 @@ ext2_HdRead: 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,25 +1199,25 @@ ext2_HdGetFileInfo: 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 - 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 + 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 xor eax, eax @@ -979,340 +1229,6 @@ ext2_HdSetFileEnd: 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 diff --git a/kernel/branches/net/fs/fat12.inc b/kernel/branches/net/fs/fat12.inc index 731030edc1..c7152794e7 100644 --- a/kernel/branches/net/fs/fat12.inc +++ b/kernel/branches/net/fs/fat12.inc @@ -631,37 +631,40 @@ found_file_analyze_flp: ; \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 - 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 +; [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-8] jc .reterr diff --git a/kernel/branches/net/fs/fat32.inc b/kernel/branches/net/fs/fat32.inc index 81f4a0e3de..644a3080ae 100644 --- a/kernel/branches/net/fs/fat32.inc +++ b/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 - - 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 + 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 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,326 +570,167 @@ add_disk_free_space: ; 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 - - 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 +;----------------------------------------------------- + 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 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: -;----------------------------------------------------- -; 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 + 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 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: 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 @@ hd_find_lfn: 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 @@ fs_HdRead: 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 @@ fs_HdRead: @@: 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,337 +921,394 @@ fs_HdRead: 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 ; ; 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 @@ fat_notroot_extend_dir: 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 @@ fat_notroot_extend_dir: 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 - 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 +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 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 @@ fs_HdRewrite: 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,26 +1605,28 @@ fs_HdRewrite: 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 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 @@ fs_HdRewrite: 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,43 +1683,47 @@ fs_HdRewrite: push -1 push -1 ; find 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 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 @@ fs_HdRewrite: 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 @@ fs_HdRewrite: 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] - call set_FAT - xchg eax, ecx - mov edx, ecx + 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 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,95 +1980,106 @@ fs_HdRewrite: 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 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 @@ fs_HdWrite: 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 @@ fs_HdWrite: 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 @@ hd_extend_file: 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,388 +2347,468 @@ hd_extend_file: @@: 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 - pop eax - dec ecx - imul ecx, [SECTORS_PER_CLUSTER] - add ecx, [DATA_START] - push eax - sar eax, 9 - add ecx, eax +@@: +; 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 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 - 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 + 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 .found: cmp dword [edi], '. ' @@ -2825,116 +2816,128 @@ fs_HdDelete: 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 - 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 + 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 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} diff --git a/kernel/branches/net/fs/fs.inc b/kernel/branches/net/fs/fs.inc index 79206a814b..6f22526b9a 100644 --- a/kernel/branches/net/fs/fs.inc +++ b/kernel/branches/net/fs/fs.inc @@ -166,16 +166,12 @@ endg 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' - je fs_info_r - 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 mov eax, 3 ;if unknown disk xor ebx, ebx @@ -186,15 +182,12 @@ endg 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 @@ choice_necessity_partition_1: 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] diff --git a/kernel/branches/net/fs/fs_lfn.inc b/kernel/branches/net/fs/fs_lfn.inc index 4b46a99cfd..c1e7e37761 100644 --- a/kernel/branches/net/fs/fs_lfn.inc +++ b/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 diff --git a/kernel/branches/net/fs/part_set.inc b/kernel/branches/net/fs/part_set.inc index 391c7b1158..235ca8223e 100644 --- a/kernel/branches/net/fs/part_set.inc +++ b/kernel/branches/net/fs/part_set.inc @@ -30,31 +30,15 @@ PARTITION_END dd 0 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 @@ virtual at fs_dependent_data_start ; 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 @@ boot_read_ok: 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 diff --git a/kernel/branches/net/gui/char.mt b/kernel/branches/net/gui/char.mt new file mode 100644 index 0000000000..e9b702604c Binary files /dev/null and b/kernel/branches/net/gui/char.mt differ diff --git a/kernel/branches/net/gui/char2.mt b/kernel/branches/net/gui/char2.mt new file mode 100644 index 0000000000..d275251663 Binary files /dev/null and b/kernel/branches/net/gui/char2.mt differ diff --git a/kernel/branches/net/gui/font.inc b/kernel/branches/net/gui/font.inc index 0e30d9461c..1f3b3c57ff 100644 --- a/kernel/branches/net/gui/font.inc +++ b/kernel/branches/net/gui/font.inc @@ -225,7 +225,15 @@ draw_text_to_user_area: 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' ;------------------------------------------------------------------------------ \ No newline at end of file diff --git a/kernel/branches/net/gui/mouse.inc b/kernel/branches/net/gui/mouse.inc index fe430150cd..e5885e933e 100644 --- a/kernel/branches/net/gui/mouse.inc +++ b/kernel/branches/net/gui/mouse.inc @@ -255,14 +255,14 @@ mouse._.left_button_press_handler: ;/////////////////////////////////////////// @@: test dl, mouse.WINDOW_RESIZE_E_FLAG jz .call_window_handler - call .calculate_e_delta - - .call_window_handler: - mov eax, mouse.active_sys_window.old_box - call sys_window_start_moving_handler - - .exit: - ret + call .calculate_e_delta + + .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] diff --git a/kernel/branches/net/gui/window.inc b/kernel/branches/net/gui/window.inc index c2172f0dbf..e077eaddcd 100644 --- a/kernel/branches/net/gui/window.inc +++ b/kernel/branches/net/gui/window.inc @@ -1023,12 +1023,61 @@ align 4 mov byte[MOUSE_DOWN], 0 inc eax ret -;------------------------------------------------------------------------------ -align 4 -;------------------------------------------------------------------------------ -minimize_window: ;///////////////////////////////////////////////////////////// -;------------------------------------------------------------------------------ -;> eax = window number on screen +;------------------------------------------------------------------------------ +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 ;------------------------------------------------------------------------------ ;# corrupts [dl*] ;------------------------------------------------------------------------------ @@ -1044,27 +1093,43 @@ minimize_window: ;///////////////////////////////////////////////////////////// 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 @@ align 4 call window._.set_window_box add esp, sizeof.BOX ret -;------------------------------------------------------------------------------ -align 4 -;------------------------------------------------------------------------------ -sys_window_start_moving_handler: ;///////////////////////////////////////////// -;------------------------------------------------------------------------------ -;? -;------------------------------------------------------------------------------ -;> 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: ;///////////////////////////////////////////// +;------------------------------------------------------------------------------ +;? +;------------------------------------------------------------------------------ +;> eax = old (original) window box +;> esi = process slot +;------------------------------------------------------------------------------ +; mov edi, eax +; call window._.draw_negative_box +; ret +;------------------------------------------------------------------------------ +align 4 +;------------------------------------------------------------------------------ sys_window_end_moving_handler: ;/////////////////////////////////////////////// ;------------------------------------------------------------------------------ ;? ;------------------------------------------------------------------------------ ;> 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 @@ align 4 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: ;///////////////////////////////////////////////////// ;------------------------------------------------------------------------------ ;? void __fastcall get_window_rect(struct RECT* rc); diff --git a/kernel/branches/net/hid/keyboard.inc b/kernel/branches/net/hid/keyboard.inc index b13f1b1a76..409663da2b 100644 --- a/kernel/branches/net/hid/keyboard.inc +++ b/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 @@ uglobal 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 @@ set_keyboard_data: 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 @@ send_scancode: 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 @@ send_scancode: 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 @@ send_scancode: 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, [kb_lights] + mov al, [esp+8] call kb_write + ret 8 + +;// mike.dld ] +check_lights_state: + mov al, [kb_lights] + cmp al, [old_kb_lights] + jz .nothing + mov [old_kb_lights], al + call set_lights +.nothing: ret ;--------------------------------------------------------------------- numlock_map: diff --git a/kernel/branches/net/hid/mousedrv.inc b/kernel/branches/net/hid/mousedrv.inc index 56d738ee2b..c6bb821748 100644 --- a/kernel/branches/net/hid/mousedrv.inc +++ b/kernel/branches/net/hid/mousedrv.inc @@ -23,20 +23,20 @@ $Revision $ 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 @@ save_draw_mouse: 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 @@ redrawmouse: 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 diff --git a/kernel/branches/net/kernel.asm b/kernel/branches/net/kernel.asm index 4240a70fb3..e67d10764b 100644 --- a/kernel/branches/net/kernel.asm +++ b/kernel/branches/net/kernel.asm @@ -334,6 +334,9 @@ high_code: 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 @@ high_code: 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 @@ v20ga24: 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 @@ no_mode_0x12: mov ax, tss0 ltr ax - mov [LFBSize], 0x800000 + mov [LFBSize], 0xC00000 call init_LFB call init_fpu call init_malloc @@ -602,19 +611,31 @@ no_mode_0x12: 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 + + 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 @@ no_mode_0x12: 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 @@ no_mode_0x12: 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 @@ if 0 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,24 +703,13 @@ if 0 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 je @f mov esi, boot_APIC_nfound @@: + call boot_log ; PRINT AMOUNT OF MEMORY mov esi, boot_memdetect @@ -701,10 +732,10 @@ end if ; 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 @@ first_app_found: ; 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 @@ first_app_found: 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 @@ first_app_found: call set_lights ;// mike.dld ] stdcall attach_int_handler, 1, irq1, 0 +.no_keyboard: ; SET MOUSE @@ -1047,6 +1090,7 @@ osloop: 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 @@ sys_system_table: 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 @@ sysfn_terminate: ; 18.2 = TERMINATE 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 @@ sysfn_getfreemem: 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 @@ sysfn_min_rest_window: 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 @@ sys_background: 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,6 +2783,49 @@ nosb7: ;------------------------------------------------------------------------------ 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 @@ -3297,9 +3420,7 @@ align 4 ;-------------------------------------- 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 @@ align 4 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 @@ set_bgr_event: ; 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 @@ -3993,6 +4115,14 @@ align 4 jmp sys_putimage_bpp ;-------------------------------------- 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 @@ -4054,6 +4184,7 @@ align 4 putimage_init24bpp: lea eax, [eax*3] putimage_init8bpp: +putimage_init9bpp: ret ;----------------------------------------------------------------------------- align 16 @@ -4074,6 +4205,14 @@ putimage_get8bpp: 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 @@ f66call: 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 @@ sys_process_def: .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 @@ sys_process_def: @@: and dword [esp+32], 0 ret - +;----------------------------------------------------------------------------- +align 4 .5: movzx ebx, cl lea ebx, [hotkey_scancodes+ebx*4] @@ -4603,8 +4738,45 @@ sys_process_def: 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 align 4 .no_put: pop ecx eax - + sub ebp, 4 dec ecx jnz .start_x @@ -5020,22 +5192,6 @@ syscall_threads: ; CreateThreads 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 @@ calculate_fast_getting_offset_for_LFB: ;------------------------------------------------------------------------------ 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 @@ set_screen: pushad + cmp [do_not_touch_winmap], 1 + je @f + stdcall kernel_free, [_WinMapAddress] mov eax, [_display.width] @@ -5104,9 +5267,18 @@ set_screen: 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 diff --git a/kernel/branches/net/memmap.inc b/kernel/branches/net/memmap.inc index cbf5f4bf82..bcf2c22043 100644 --- a/kernel/branches/net/memmap.inc +++ b/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 diff --git a/kernel/branches/net/video/blitter.inc b/kernel/branches/net/video/blitter.inc index 622bc1a4c8..c8334c0ccb 100644 --- a/kernel/branches/net/video/blitter.inc +++ b/kernel/branches/net/video/blitter.inc @@ -14,8 +14,8 @@ ends 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,148 +28,87 @@ struct BLITTER ends -align 4 -__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 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 +align 4 +block_clip: +;esi= clip RECT ptr +;edi= RECT ptr +;return code: +;eax= 0 - draw, 1 - don't draw + + 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, 40 @@ -177,71 +116,58 @@ blit_clip: 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 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 @@ blit_clip: 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 .dx0 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 @@ align 4 .done: ; call [draw_pointer] - call __sys_draw_pointer +; call __sys_draw_pointer .L57: add esp, 72 pop ebx diff --git a/kernel/branches/net/video/cursors.inc b/kernel/branches/net/video/cursors.inc index f34bfd1e1b..f3e5f678c6 100644 --- a/kernel/branches/net/video/cursors.inc +++ b/kernel/branches/net/video/cursors.inc @@ -444,22 +444,17 @@ align 4 .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 @@ align 4 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 @@ align 4 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 @@ check_mouse_area_for_getpixel_new: 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,47 +870,55 @@ check_mouse_area_for_putpixel_new: ; 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 - 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 +; 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 shl ecx, 2 cmp [ScreenBPP], byte 24 @@ -941,16 +948,20 @@ align 4 pop ebx - test eax, 0xFF000000 - jz @f - - pop ecx - ret -;-------------------------------------- -align 4 -@@: - pop eax -;-------------------------------------- + test eax, 0xFF000000 + jz @f + + add esp, 4 + ret +;-------------------------------------- +align 4 +.sh: + mov ecx, -1 +;-------------------------------------- +align 4 +@@: + pop eax +;-------------------------------------- align 4 .no_mouse_area: ret diff --git a/kernel/branches/net/video/vesa20.inc b/kernel/branches/net/video/vesa20.inc index 7f3b4c9557..d57873bbc3 100644 --- a/kernel/branches/net/video/vesa20.inc +++ b/kernel/branches/net/video/vesa20.inc @@ -403,35 +403,44 @@ align 4 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 @@ align 4 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 @@ Vesa20_putpixel24_new: 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 @@ Vesa20_putpixel32_new: 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 @@ align 4 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 @@ align 4 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