diff --git a/kernel/trunk/blkdev/cd_drv.inc b/kernel/trunk/blkdev/cd_drv.inc index e3dba90a7e..a88f7fb2ad 100644 --- a/kernel/trunk/blkdev/cd_drv.inc +++ b/kernel/trunk/blkdev/cd_drv.inc @@ -768,6 +768,8 @@ check_ATAPI_device_event: cmp [cd_status], 0 jne .end mov [IDE_Channel_2], 1 + mov ecx, ide_channel2_mutex + call mutex_lock call reserve_ok2 mov [ChannelNumber], 2 mov [DiskNumber], 1 @@ -791,6 +793,8 @@ check_ATAPI_device_event: cmp [cd_status], 0 jne .end mov [IDE_Channel_2], 1 + mov ecx, ide_channel2_mutex + call mutex_lock call reserve_ok2 mov [ChannelNumber], 2 mov [DiskNumber], 0 @@ -814,6 +818,8 @@ check_ATAPI_device_event: cmp [cd_status], 0 jne .end mov [IDE_Channel_1], 1 + mov ecx, ide_channel1_mutex + call mutex_lock call reserve_ok2 mov [ChannelNumber], 1 mov [DiskNumber], 1 @@ -837,6 +843,8 @@ check_ATAPI_device_event: cmp [cd_status], 0 jne .end mov [IDE_Channel_1], 1 + mov ecx, ide_channel1_mutex + call mutex_lock call reserve_ok2 mov [ChannelNumber], 1 mov [DiskNumber], 0 diff --git a/kernel/trunk/blkdev/disk.inc b/kernel/trunk/blkdev/disk.inc index 48a3b28d93..af56fdadde 100644 --- a/kernel/trunk/blkdev/disk.inc +++ b/kernel/trunk/blkdev/disk.inc @@ -186,9 +186,9 @@ struct PARTITION ; Pointer to parent DISK structure. FSUserFunctions dd ? ; Handlers for the sysfunction 70h. This field is a pointer to the following -; array. The first dword is a number of supported subfunctions, other dwords +; array. The first dword is pointer to disconnect handler. +; The first dword is a number of supported subfunctions, other dwords ; point to handlers of corresponding subfunctions. -; This field is 0 if file system is not recognized. ; ...fs-specific data may follow... ends @@ -501,7 +501,8 @@ disk_media_dereference: jz .nofree .freeloop: lodsd - call free + mov ecx, [eax+PARTITION.FSUserFunctions] + call dword [ecx] dec edi jnz .freeloop .nofree: @@ -727,7 +728,7 @@ disk_scan_partitions: ; 10. This is not an MBR. The media is not partitioned. Create one partition ; which covers all the media and abort the loop. stdcall disk_add_partition, 0, 0, \ - dword [esi+DISK.MediaInfo.Capacity], dword [esi+DISK.MediaInfo.Capacity+4] + dword [esi+DISK.MediaInfo.Capacity], dword [esi+DISK.MediaInfo.Capacity+4], esi jmp .done .mbr: ; 11. Process all entries of the new MBR/EBR @@ -855,7 +856,7 @@ irp type,\ adc edx, 0 push ecx stdcall disk_add_partition, eax, edx, \ - [ecx+PARTITION_TABLE_ENTRY.Length], 0 + [ecx+PARTITION_TABLE_ENTRY.Length], 0, esi pop ecx .nothing: ; 5. Return. @@ -869,7 +870,10 @@ irp type,\ ; This is an internal function called from disk_scan_partitions and ; process_partition_table_entry. It adds one partition to the list of ; partitions for the media. -proc disk_add_partition stdcall uses ebx edi, start:qword, length:qword +; Important note: start, length, disk MUST be present and +; MUST be in the same order as in PARTITION structure. +; esi duplicates [disk]. +proc disk_add_partition stdcall uses ebx edi, start:qword, length:qword, disk:dword ; 1. Check that this partition will not exceed the limit on total number. cmp [esi+DISK.NumPartitions], MAX_NUM_PARTITIONS jae .nothing @@ -974,49 +978,64 @@ disk_detect_partition: virtual at ebp+8 .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 ? +.disk 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 +; When disk_add_partition is called, ebx contains a pointer to +; a three-sectors-sized buffer. This function saves ebx in the stack +; immediately before ebp. + mov ebx, [ebp-4] ; get buffer + add ebx, 512 ; advance over MBR data to bootsector data + add ebp, 8 ; ebp points to part of PARTITION structure + xor eax, eax ; first sector of the partition + call fs_read32_sys + push eax ; 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. +; For tests: +; ebp -> first three fields of PARTITION structure, .start, .length, .disk; +; [esp] = error code after bootsector read: 0 = ok, otherwise = failed, +; ebx points to the buffer for bootsector, +; ebx+512 points to 512-bytes buffer that can be used for anything. call fat_create_partition test eax, eax jnz .success + call ntfs_create_partition + test eax, eax + jnz .success + call ext2_create_partition + test eax, eax + jnz .success ; 3. No file system has recognized the volume, so just allocate the PARTITION ; structure without extra fields. movi eax, sizeof.PARTITION call malloc test eax, eax jz .nothing - mov edx, dword [.start] + mov edx, dword [ebp+PARTITION.FirstSector] mov dword [eax+PARTITION.FirstSector], edx - mov edx, dword [.start+4] + mov edx, dword [ebp+PARTITION.FirstSector+4] mov dword [eax+PARTITION.FirstSector+4], edx - mov edx, dword [.length] + mov edx, dword [ebp+PARTITION.Length] mov dword [eax+PARTITION.Length], edx - mov edx, dword [.length+4] + mov edx, dword [ebp+PARTITION.Length+4] mov dword [eax+PARTITION.Length+4], edx mov [eax+PARTITION.Disk], esi - and [eax+PARTITION.FSUserFunctions], 0 + mov [eax+PARTITION.FSUserFunctions], default_fs_functions .success: .nothing: + sub ebp, 8 ; restore ebp ; 4. Return with eax = pointer to PARTITION or NULL. pop ecx ret +iglobal +align 4 +default_fs_functions: + dd free + dd 0 ; no user functions +endg + ; 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. @@ -1200,15 +1219,13 @@ fs_dyndisk: 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 + cmp [edi+4], ecx jbe .unsupported push edx push ebp mov ebp, eax - call dword [edi+4+ecx*4] + call dword [edi+8+ecx*4] pop ebp pop edx mov dword [esp+32], eax @@ -1225,6 +1242,8 @@ fs_dyndisk: mov dword [esp+32], ERROR_FILE_NOT_FOUND jmp .cleanup .unsupported: + cmp edi, default_fs_functions + jz .nofs mov dword [esp+32], ERROR_UNSUPPORTED_FS jmp .cleanup .nomedia: diff --git a/kernel/trunk/blkdev/disk_cache.inc b/kernel/trunk/blkdev/disk_cache.inc index ea7702d22c..565a6d5881 100644 --- a/kernel/trunk/blkdev/disk_cache.inc +++ b/kernel/trunk/blkdev/disk_cache.inc @@ -14,19 +14,7 @@ $Revision$ ; eax is relative to partition start ; 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 - 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. +; Save ecx, set ecx to SysCache and let the common part do its work. push ecx mov ecx, [ebp+PARTITION.Disk] add ecx, DISK.SysCache @@ -39,18 +27,7 @@ fs_read32_sys: ; eax is relative to partition start ; 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 - 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. +; 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 @@ -185,19 +162,7 @@ end virtual ; eax is relative to partition start ; 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 - 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. +; Save ecx, set ecx to SysCache and let the common part do its work. push ecx mov ecx, [ebp+PARTITION.Disk] add ecx, DISK.SysCache @@ -210,18 +175,7 @@ fs_write32_sys: ; eax is relative to partition start ; 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 - 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. +; 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 @@ -622,17 +576,6 @@ disk_free_cache: ; 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 - call write_cache - mov eax, [hd_error] - ret -@@: ; The algorithm is straightforward. push esi push esi ; for second write_cache64 diff --git a/kernel/trunk/blkdev/hd_drv.inc b/kernel/trunk/blkdev/hd_drv.inc index 5871e162c8..22b04c0118 100644 --- a/kernel/trunk/blkdev/hd_drv.inc +++ b/kernel/trunk/blkdev/hd_drv.inc @@ -1,6 +1,6 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; -;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;; +;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;; ;; Distributed under terms of the GNU General Public License ;; ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -13,39 +13,93 @@ $Revision$ ; Access through BIOS by diamond ; LBA48 support by Mario79 ;----------------------------------------------------------------------------- +struct HD_DATA +hdbase dd ? +hdid dd ? +hdpos dd ? +ends + +iglobal align 4 -hd_read: -;----------------------------------------------------------- -; input : eax = block to read -; ebx = destination -;----------------------------------------------------------- +ide_callbacks: + dd ide_callbacks.end - ide_callbacks ; strucsize + dd 0 ; no close function + dd 0 ; no closemedia function + dd ide_querymedia + dd ide_read + dd ide_write + dd 0 ; no flush function + dd 0 ; use default cache size +.end: + +bd_callbacks: + dd bd_callbacks.end - bd_callbacks ; strucsize + dd 0 ; no close function + dd 0 ; no closemedia function + dd bd_querymedia + dd bd_read_interface + dd bd_write_interface + dd 0 ; no flush function + dd 0 ; use default cache size +.end: + +hd0_data HD_DATA ?, 0, 1 +hd1_data HD_DATA ?, 0x10, 2 +hd2_data HD_DATA ?, 0, 3 +hd3_data HD_DATA ?, 0x10, 4 +endg + +uglobal +ide_mutex MUTEX +ide_channel1_mutex MUTEX +ide_channel2_mutex MUTEX +endg + +proc ide_read stdcall uses edi, \ + hd_data, buffer, startsector:qword, numsectors + ; hd_data = pointer to hd*_data + ; buffer = pointer to buffer for data + ; startsector = 64-bit start sector + ; numsectors = pointer to number of sectors on input, + ; must be filled with number of sectors really read +locals +sectors_todo dd ? +channel_lock dd ? +endl +; 1. Initialize number of sectors: get number of requested sectors +; and say that no sectors were read yet. + mov ecx, [numsectors] + mov eax, [ecx] + mov dword [ecx], 0 + mov [sectors_todo], eax +; 2. Acquire the global lock. + mov ecx, ide_mutex + call mutex_lock + mov ecx, ide_channel2_mutex + mov eax, [hd_data] + cmp [eax+HD_DATA.hdbase], 0x1F0 + jne .IDE_Channel_2 + mov ecx, ide_channel1_mutex +.IDE_Channel_2: + mov [channel_lock], ecx + call mutex_lock +; 3. Convert parameters to the form suitable for worker procedures. +; Underlying procedures do not know about 64-bit sectors. +; Worker procedures use global variables and edi for [buffer]. + cmp dword [startsector+4], 0 + jnz .fail and [hd_error], 0 - push ecx esi edi ; scan cache - - call calculate_cache - add esi, 8 - - mov edi, 1 - -hdreadcache: - cmp dword [esi+4], 0 ; empty - je nohdcache - - cmp [esi], eax ; correct sector - je yeshdcache - -nohdcache: - add esi, 8 - inc edi - dec ecx - jnz hdreadcache - - call find_empty_slot ; ret in edi - cmp [hd_error], 0 - jne return_01 -; Read through BIOS? - cmp [hdpos], 0x80 - jae .bios + mov ecx, [hd_data] + mov eax, [ecx+HD_DATA.hdbase] + mov [hdbase], eax + mov eax, [ecx+HD_DATA.hdid] + mov [hdid], eax + mov eax, [ecx+HD_DATA.hdpos] + mov [hdpos], eax + mov eax, dword [startsector] + mov edi, [buffer] +; 4. Worker procedures take one sectors per time, so loop over all sectors to read. +.sectors_loop: ; DMA read is permitted if [allow_dma_access]=1 or 2 cmp [allow_dma_access], 2 ja .nodma @@ -55,38 +109,273 @@ nohdcache: jmp @f .nodma: call hd_read_pio - jmp @f -.bios: - call bd_read @@: cmp [hd_error], 0 - jne return_01 - - call calculate_cache_1 - lea esi, [edi*8+esi] - - mov [esi], eax ; sector number - mov dword [esi+4], 1 ; hd read - mark as same as in hd - -yeshdcache: - mov esi, edi - shl esi, 9 - - push eax - call calculate_cache_2 - add esi, eax - pop eax - - mov edi, ebx - mov ecx, 512/4 - cld - rep movsd ; move data - -return_01: - pop edi esi ecx + jnz .fail + mov ecx, [numsectors] + inc dword [ecx] ; one more sector is read + dec [sectors_todo] + jz .done + inc eax + jnz .sectors_loop +; 5. Loop is done, either due to error or because everything is done. +; Release the global lock and return the corresponding status. +.fail: + mov ecx, [channel_lock] + call mutex_unlock + mov ecx, ide_mutex + call mutex_unlock + or eax, -1 ret +.done: + mov ecx, [channel_lock] + call mutex_unlock + mov ecx, ide_mutex + call mutex_unlock + xor eax, eax + ret +endp + +proc ide_write stdcall uses esi edi, \ + hd_data, buffer, startsector:qword, numsectors + ; hd_data = pointer to hd*_data + ; buffer = pointer to buffer with data + ; startsector = 64-bit start sector + ; numsectors = pointer to number of sectors on input, + ; must be filled with number of sectors really written +locals +sectors_todo dd ? +channel_lock dd ? +endl +; 1. Initialize number of sectors: get number of requested sectors +; and say that no sectors were read yet. + mov ecx, [numsectors] + mov eax, [ecx] + mov dword [ecx], 0 + mov [sectors_todo], eax +; 2. Acquire the global lock. + mov ecx, ide_mutex + call mutex_lock + mov ecx, ide_channel2_mutex + mov eax, [hd_data] + cmp [eax+HD_DATA.hdbase], 0x1F0 + jne .IDE_Channel_2 + mov ecx, ide_channel1_mutex +.IDE_Channel_2: + mov [channel_lock], ecx + call mutex_lock +; 3. Convert parameters to the form suitable for worker procedures. +; Underlying procedures do not know about 64-bit sectors. +; Worker procedures use global variables and esi for [buffer]. + cmp dword [startsector+4], 0 + jnz .fail + and [hd_error], 0 + mov ecx, [hd_data] + mov eax, [ecx+HD_DATA.hdbase] + mov [hdbase], eax + mov eax, [ecx+HD_DATA.hdid] + mov [hdid], eax + mov eax, [ecx+HD_DATA.hdpos] + mov [hdpos], eax + mov esi, [buffer] + lea edi, [startsector] + mov [cache_chain_ptr], edi +; 4. Worker procedures take max 16 sectors per time, +; loop until all sectors will be processed. +.sectors_loop: + mov ecx, 16 + cmp ecx, [sectors_todo] + jbe @f + mov ecx, [sectors_todo] +@@: + mov [cache_chain_size], cl +; DMA write is permitted only if [allow_dma_access]=1 + cmp [allow_dma_access], 2 + jae .nodma + cmp [dma_hdd], 1 + jnz .nodma + call cache_write_dma + jmp .common +.nodma: + mov [cache_chain_size], 1 + call cache_write_pio +.common: + cmp [hd_error], 0 + jnz .fail + movzx ecx, [cache_chain_size] + mov eax, [numsectors] + add [eax], ecx + sub [sectors_todo], ecx + jz .done + add [edi], ecx + jc .fail + shl ecx, 9 + add esi, ecx + jmp .sectors_loop +; 5. Loop is done, either due to error or because everything is done. +; Release the global lock and return the corresponding status. +.fail: + mov ecx, [channel_lock] + call mutex_unlock + mov ecx, ide_mutex + call mutex_unlock + or eax, -1 + ret +.done: + mov ecx, [channel_lock] + call mutex_unlock + mov ecx, ide_mutex + call mutex_unlock + xor eax, eax + ret +endp + +; This is a stub. +proc ide_querymedia stdcall, hd_data, mediainfo + mov eax, [mediainfo] + mov [eax+DISKMEDIAINFO.Flags], 0 + mov [eax+DISKMEDIAINFO.SectorSize], 512 + or dword [eax+DISKMEDIAINFO.Capacity], 0xFFFFFFFF + or dword [eax+DISKMEDIAINFO.Capacity+4], 0xFFFFFFFF + xor eax, eax + ret +endp + +proc bd_read_interface stdcall uses edi, \ + userdata, buffer, startsector:qword, numsectors + ; userdata = old [hdpos] = 80h + index in NumBiosDisks + ; buffer = pointer to buffer for data + ; startsector = 64-bit start sector + ; numsectors = pointer to number of sectors on input, + ; must be filled with number of sectors really read +locals +sectors_todo dd ? +endl +; 1. Initialize number of sectors: get number of requested sectors +; and say that no sectors were read yet. + mov ecx, [numsectors] + mov eax, [ecx] + mov dword [ecx], 0 + mov [sectors_todo], eax +; 2. Acquire the global lock. + mov ecx, ide_mutex + call mutex_lock +; 3. Convert parameters to the form suitable for worker procedures. +; Underlying procedures do not know about 64-bit sectors. +; Worker procedures use global variables and edi for [buffer]. + cmp dword [startsector+4], 0 + jnz .fail + and [hd_error], 0 + mov eax, [userdata] + mov [hdpos], eax + mov eax, dword [startsector] + mov edi, [buffer] +; 4. Worker procedures take one sectors per time, so loop over all sectors to read. +.sectors_loop: + call bd_read + cmp [hd_error], 0 + jnz .fail + mov ecx, [numsectors] + inc dword [ecx] ; one more sector is read + dec [sectors_todo] + jz .done + inc eax + jnz .sectors_loop +; 5. Loop is done, either due to error or because everything is done. +; Release the global lock and return the corresponding status. +.fail: + mov ecx, ide_mutex + call mutex_unlock + or eax, -1 + ret +.done: + mov ecx, ide_mutex + call mutex_unlock + xor eax, eax + ret +endp + +proc bd_write_interface stdcall uses esi edi, \ + userdata, buffer, startsector:qword, numsectors + ; userdata = old [hdpos] = 80h + index in NumBiosDisks + ; buffer = pointer to buffer with data + ; startsector = 64-bit start sector + ; numsectors = pointer to number of sectors on input, + ; must be filled with number of sectors really written +locals +sectors_todo dd ? +endl +; 1. Initialize number of sectors: get number of requested sectors +; and say that no sectors were read yet. + mov ecx, [numsectors] + mov eax, [ecx] + mov dword [ecx], 0 + mov [sectors_todo], eax +; 2. Acquire the global lock. + mov ecx, ide_mutex + call mutex_lock +; 3. Convert parameters to the form suitable for worker procedures. +; Underlying procedures do not know about 64-bit sectors. +; Worker procedures use global variables and esi for [buffer]. + cmp dword [startsector+4], 0 + jnz .fail + and [hd_error], 0 + mov eax, [userdata] + mov [hdpos], eax + mov esi, [buffer] + lea edi, [startsector] + mov [cache_chain_ptr], edi +; 4. Worker procedures take max 16 sectors per time, +; loop until all sectors will be processed. +.sectors_loop: + mov ecx, 16 + cmp ecx, [sectors_todo] + jbe @f + mov ecx, [sectors_todo] +@@: + mov [cache_chain_size], cl + call bd_write_cache_chain + cmp [hd_error], 0 + jnz .fail + movzx ecx, [cache_chain_size] + mov eax, [numsectors] + add [eax], ecx + sub [sectors_todo], ecx + jz .done + add [edi], ecx + jc .fail + shl ecx, 9 + add esi, ecx + jmp .sectors_loop +; 5. Loop is done, either due to error or because everything is done. +; Release the global lock and return the corresponding status. +.fail: + mov ecx, ide_mutex + call mutex_unlock + or eax, -1 + ret +.done: + mov ecx, ide_mutex + call mutex_unlock + xor eax, eax + ret +endp + +; This is a stub. +proc bd_querymedia stdcall, hd_data, mediainfo + mov eax, [mediainfo] + mov [eax+DISKMEDIAINFO.Flags], 0 + mov [eax+DISKMEDIAINFO.SectorSize], 512 + or dword [eax+DISKMEDIAINFO.Capacity], 0xFFFFFFFF + or dword [eax+DISKMEDIAINFO.Capacity+4], 0xFFFFFFFF + xor eax, eax + ret +endp + ;----------------------------------------------------------------------------- align 4 +; input: eax = sector, edi -> buffer +; output: edi = edi + 512 hd_read_pio: push eax edx @@ -184,80 +473,18 @@ hd_read_pio: pushfd cli - push edi - shl edi, 9 - - push eax - call calculate_cache_2 - add edi, eax - pop eax mov ecx, 256 mov edx, [hdbase] cld rep insw - pop edi popfd pop edx eax ret ;----------------------------------------------------------------------------- align 4 -hd_write: -;----------------------------------------------------------- -; input : eax = block -; ebx = pointer to memory -;----------------------------------------------------------- - push ecx esi edi - -; check if the cache already has the sector and overwrite it - call calculate_cache - add esi, 8 - mov edi, 1 - -hdwritecache: - cmp dword [esi+4], 0 ; if cache slot is empty - je not_in_cache_write - - cmp [esi], eax ; if the slot has the sector - je yes_in_cache_write - -not_in_cache_write: - add esi, 8 - inc edi - dec ecx - jnz hdwritecache - -; sector not found in cache -; write the block to a new location - call find_empty_slot ; ret in edi - cmp [hd_error], 0 - jne hd_write_access_denied - - call calculate_cache_1 - lea esi, [edi*8+esi] - mov [esi], eax ; sector number - -yes_in_cache_write: - mov dword [esi+4], 2 ; write - differs from hd - - shl edi, 9 - - push eax - call calculate_cache_2 - add edi, eax - pop eax - - mov esi, ebx - mov ecx, 512/4 - cld - rep movsd ; move data - -hd_write_access_denied: - pop edi esi ecx - ret -;----------------------------------------------------------------------------- -align 4 +; edi -> sector, esi -> data cache_write_pio: ; Select the desired drive mov edx, [hdbase] @@ -271,7 +498,7 @@ cache_write_pio: jne hd_write_error ; ATA with 28 or 48 bit for sector number? - mov eax, [esi] + mov eax, [edi] cmp eax, 0x10000000 jae .lba48 ;-------------------------------------- @@ -286,7 +513,7 @@ cache_write_pio: inc eax out dx, al ; ATA Sector Counter счётчик секторов inc edx - mov eax, [esi] ; eax = sector to write + mov eax, [edi] ; eax = sector to write out dx, al ; LBA Low LBA (7:0) shr eax, 8 inc edx @@ -319,7 +546,7 @@ cache_write_pio: inc eax out dx, al ; Sector Count Current Sector count (7:0) inc edx - mov eax, [esi] + mov eax, [edi] rol eax, 8 out dx, al ; LBA Low Previous LBA (31:24) xor eax, eax ; because only 32 bit cache @@ -328,7 +555,7 @@ cache_write_pio: inc edx out dx, al ; LBA High Previous LBA (47:40) sub edx, 2 - mov eax, [esi] + mov eax, [edi] out dx, al ; LBA Low Current LBA (7:0) shr eax, 8 inc edx @@ -355,14 +582,6 @@ cache_write_pio: pushfd cli - mov esi, edi - shl esi, 9 - - push eax - call calculate_cache_2 - add esi, eax - pop eax - mov ecx, 256 mov edx, [hdbase] cld @@ -605,19 +824,13 @@ hd_read_dma: sub eax, [dma_cur_sector] shl eax, 9 add eax, (OS_BASE+IDE_DMA) - push ecx esi edi + push ecx esi mov esi, eax - shl edi, 9 - - push eax - call calculate_cache_2 - add edi, eax - pop eax mov ecx, 512/4 cld rep movsd - pop edi esi ecx + pop esi ecx pop edx pop eax ret @@ -766,24 +979,12 @@ hd_read_dma: mov [dma_cur_sector], eax jmp hd_read_dma ;----------------------------------------------------------------------------- -align 4 -write_cache_sector: - mov [cache_chain_size], 1 - mov [cache_chain_pos], edi -;-------------------------------------- -align 4 -write_cache_chain: - cmp [hdpos], 0x80 - jae bd_write_cache_chain +cache_write_dma: mov eax, [cache_chain_ptr] push esi mov eax, IDE_descriptor_table mov edx, eax pusha - mov esi, [cache_chain_pos] - shl esi, 9 - call calculate_cache_2 - add esi, eax mov edi, (OS_BASE+IDE_DMA) mov dword [edx], IDE_DMA movzx ecx, [cache_chain_size] @@ -965,19 +1166,12 @@ bd_read: sub eax, [bios_cur_sector] shl eax, 9 add eax, (OS_BASE+0x9A000) - push ecx esi edi + push ecx esi mov esi, eax - shl edi, 9 - - push eax - call calculate_cache_2 - add edi, eax - pop eax - mov ecx, 512/4 cld rep movsd - pop edi esi ecx + pop esi ecx pop edx pop eax ret @@ -1006,10 +1200,6 @@ bd_read: align 4 bd_write_cache_chain: pusha - mov esi, [cache_chain_pos] - shl esi, 9 - call calculate_cache_2 - add esi, eax mov edi, OS_BASE + 0x9A000 movzx ecx, [cache_chain_size] push ecx @@ -1041,7 +1231,7 @@ align 4 int13_call: ; Because this code uses fixed addresses, ; it can not be run simultaniously by many threads. -; In current implementation it is protected by common mutex 'hd1_status' +; In current implementation it is protected by common mutex 'ide_status' mov word [OS_BASE + 510h], 10h ; packet length mov word [OS_BASE + 512h], cx ; number of sectors mov dword [OS_BASE + 514h], 9A000000h ; buffer 9A00:0000 @@ -1088,82 +1278,3 @@ int13_call: @@: ret ; \end{diamond} -;----------------------------------------------------------------------------- -align 4 -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 -;----------------------------------------------------------------------------- -align 4 -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/trunk/blkdev/ide_cache.inc b/kernel/trunk/blkdev/ide_cache.inc index 35814cfc31..36c6efaf03 100644 --- a/kernel/trunk/blkdev/ide_cache.inc +++ b/kernel/trunk/blkdev/ide_cache.inc @@ -23,545 +23,6 @@ $Revision$ - -align 4 -write_cache: -;----------------------------------------------------------- -; write all changed sectors to disk -;----------------------------------------------------------- - push eax ecx edx esi edi - - ; write difference ( 2 ) from cache to hd - call calculate_cache - add esi, 8 - mov edi, 1 -write_cache_more: - cmp dword [esi+4], 2; if cache slot is not different - jne .write_chain - mov dword [esi+4], 1; same as in hd - mov eax, [esi] ; eax = sector to write - cmp eax, [PARTITION_START] - jb danger - cmp eax, [PARTITION_END] - ja danger - cmp [hdpos], 0x80 - jae @f -; DMA write is permitted only if [allow_dma_access]=1 - cmp [allow_dma_access], 2 - jae .nodma - cmp [dma_hdd], 1 - jnz .nodma -@@: -; Объединяем запись цепочки последовательных секторов в одно обращение к диску - cmp ecx, 1 - jz .nonext - cmp dword [esi+8+4], 2 - jnz .nonext - push eax - inc eax - cmp eax, [esi+8] - pop eax - jnz .nonext - cmp [cache_chain_started], 1 - jz @f - mov [cache_chain_started], 1 - mov [cache_chain_size], 0 - mov [cache_chain_pos], edi - mov [cache_chain_ptr], esi -@@: - inc [cache_chain_size] - cmp [cache_chain_size], 16 - jnz .continue - jmp .write_chain -.nonext: - call flush_cache_chain - mov [cache_chain_size], 1 - mov [cache_chain_ptr], esi - call write_cache_sector - jmp .continue -.nodma: - call cache_write_pio -.write_chain: - call flush_cache_chain -.continue: -danger: - add esi, 8 - inc edi - dec ecx - jnz write_cache_more - call flush_cache_chain - return_02: - pop edi esi edx ecx eax - ret - -flush_cache_chain: - cmp [cache_chain_started], 0 - jz @f - call write_cache_chain - mov [cache_chain_started], 0 -@@: - ret -;-------------------------------------------------------------------- -align 4 -find_empty_slot: -;----------------------------------------------------------- -; find empty or read slot, flush cache if next 10% is used by write -; output : edi = cache slot -;----------------------------------------------------------- -; push ecx esi - -search_again: - call calculate_cache_3 - shr ecx, 3 -search_for_empty: - inc edi - call calculate_cache_4 - jbe inside_cache - mov edi, 1 -inside_cache: - push esi - call calculate_cache_1 - cmp dword [edi*8+esi+4], 2 - pop esi - jb found_slot ; it's empty or read - dec ecx - jnz search_for_empty - call write_cache ; no empty slots found, write all - cmp [hd_error], 0 - jne found_slot_access_denied - jmp search_again ; and start again -found_slot: - call calculate_cache_5 -found_slot_access_denied: - ret -;-------------------------------------------------------------------- -align 4 -calculate_cache: -; 1 - IDE0 ... 4 - IDE3 -.ide0: - cmp [hdpos], 1 - jne .ide1 - cmp [hdd_appl_data], 0 - jne .ide0_appl_data - mov ecx, [cache_ide0_system_sad_size] - mov esi, [cache_ide0_pointer] - ret -.ide0_appl_data: - mov ecx, [cache_ide0_appl_sad_size] - mov esi, [cache_ide0_data_pointer] - ret -.ide1: - cmp [hdpos], 2 - jne .ide2 - cmp [hdd_appl_data], 0 - jne .ide1_appl_data - mov ecx, [cache_ide1_system_sad_size] - mov esi, [cache_ide1_pointer] - ret -.ide1_appl_data: - mov ecx, [cache_ide1_appl_sad_size] - mov esi, [cache_ide1_data_pointer] - ret -.ide2: - cmp [hdpos], 3 - jne .ide3 - cmp [hdd_appl_data], 0 - jne .ide2_appl_data - mov ecx, [cache_ide2_system_sad_size] - mov esi, [cache_ide2_pointer] - ret -.ide2_appl_data: - mov ecx, [cache_ide2_appl_sad_size] - mov esi, [cache_ide2_data_pointer] - ret -.ide3: - cmp [hdpos], 4 - jne .noide - cmp [hdd_appl_data], 0 - jne .ide3_appl_data - mov ecx, [cache_ide3_system_sad_size] - mov esi, [cache_ide3_pointer] - ret -.ide3_appl_data: - mov ecx, [cache_ide3_appl_sad_size] - mov esi, [cache_ide3_data_pointer] - ret -.noide: - push eax - mov eax, [hdpos] - sub eax, 80h - cmp byte [BiosDisksData+eax*4+2], -1 - jz @f - movzx eax, byte [BiosDisksData+eax*4+2] - imul eax, cache_ide1-cache_ide0 - add eax, cache_ide0 - jmp .get -@@: - imul eax, cache_ide1-cache_ide0 - add eax, BiosDiskCaches -.get: - cmp [hdd_appl_data], 0 - jne .bd_appl_data - mov ecx, [cache_ide0_system_sad_size-cache_ide0+eax] - mov esi, [cache_ide0_pointer-cache_ide0+eax] - pop eax - ret -.bd_appl_data: - mov ecx, [cache_ide0_appl_sad_size-cache_ide0+eax] - mov esi, [cache_ide0_data_pointer-cache_ide0+eax] - pop eax - ret -;-------------------------------------------------------------------- -align 4 -calculate_cache_1: -; 1 - IDE0 ... 4 - IDE3 -.ide0: - cmp [hdpos], 1 - jne .ide1 - cmp [hdd_appl_data], 0 - jne .ide0_appl_data - mov esi, [cache_ide0_pointer] - ret -.ide0_appl_data: - mov esi, [cache_ide0_data_pointer] - ret -.ide1: - cmp [hdpos], 2 - jne .ide2 - cmp [hdd_appl_data], 0 - jne .ide1_appl_data - mov esi, [cache_ide1_pointer] - ret -.ide1_appl_data: - mov esi, [cache_ide1_data_pointer] - ret -.ide2: - cmp [hdpos], 3 - jne .ide3 - cmp [hdd_appl_data], 0 - jne .ide2_appl_data - mov esi, [cache_ide2_pointer] - ret -.ide2_appl_data: - mov esi, [cache_ide2_data_pointer] - ret -.ide3: - cmp [hdpos], 4 - jne .noide - cmp [hdd_appl_data], 0 - jne .ide3_appl_data - mov esi, [cache_ide3_pointer] - ret -.ide3_appl_data: - mov esi, [cache_ide3_data_pointer] - ret -.noide: - push eax - mov eax, [hdpos] - sub eax, 80h - cmp byte [BiosDisksData+eax*4+2], -1 - jz @f - movzx eax, byte [BiosDisksData+eax*4+2] - imul eax, cache_ide1-cache_ide0 - add eax, cache_ide0 - jmp .get -@@: - imul eax, cache_ide1-cache_ide0 - add eax, BiosDiskCaches -.get: - cmp [hdd_appl_data], 0 - jne .bd_appl_data - mov esi, [cache_ide0_pointer-cache_ide0+eax] - pop eax - ret -.bd_appl_data: - mov esi, [cache_ide0_data_pointer-cache_ide0+eax] - pop eax - ret - -;-------------------------------------------------------------------- -align 4 -calculate_cache_2: -; 1 - IDE0 ... 4 - IDE3 -.ide0: - cmp [hdpos], 1 - jne .ide1 - cmp [hdd_appl_data], 0 - jne .ide0_appl_data - mov eax, [cache_ide0_system_data] - ret -.ide0_appl_data: - mov eax, [cache_ide0_appl_data] - ret -.ide1: - cmp [hdpos], 2 - jne .ide2 - cmp [hdd_appl_data], 0 - jne .ide1_appl_data - mov eax, [cache_ide1_system_data] - ret -.ide1_appl_data: - mov eax, [cache_ide1_appl_data] - ret -.ide2: - cmp [hdpos], 3 - jne .ide3 - cmp [hdd_appl_data], 0 - jne .ide2_appl_data - mov eax, [cache_ide2_system_data] - ret -.ide2_appl_data: - mov eax, [cache_ide2_appl_data] - ret -.ide3: - cmp [hdpos], 4 - jne .noide - cmp [hdd_appl_data], 0 - jne .ide3_appl_data - mov eax, [cache_ide3_system_data] - ret -.ide3_appl_data: - mov eax, [cache_ide3_appl_data] - ret -.noide: - mov eax, [hdpos] - sub eax, 80h - cmp byte [BiosDisksData+eax*4+2], -1 - jz @f - movzx eax, byte [BiosDisksData+eax*4+2] - imul eax, cache_ide1-cache_ide0 - add eax, cache_ide0 - jmp .get -@@: - imul eax, cache_ide1-cache_ide0 - add eax, BiosDiskCaches -.get: - cmp [hdd_appl_data], 0 - jne .bd_appl_data - mov eax, [cache_ide0_system_data-cache_ide0+eax] - ret -.bd_appl_data: - mov eax, [cache_ide0_appl_data-cache_ide0+eax] - ret -;-------------------------------------------------------------------- -align 4 -calculate_cache_3: -; mov ecx,cache_max*10/100 -; mov edi,[cache_search_start] - -; 1 - IDE0 ... 4 - IDE3 -.ide0: - cmp [hdpos], 1 - jne .ide1 - cmp [hdd_appl_data], 0 - jne .ide0_appl_data - mov ecx, [cache_ide0_system_sad_size] - mov edi, [cache_ide0_search_start] - ret -.ide0_appl_data: - mov ecx, [cache_ide0_appl_sad_size] - mov edi, [cache_ide0_appl_search_start] - ret -.ide1: - cmp [hdpos], 2 - jne .ide2 - cmp [hdd_appl_data], 0 - jne .ide1_appl_data - mov ecx, [cache_ide1_system_sad_size] - mov edi, [cache_ide1_search_start] - ret -.ide1_appl_data: - mov ecx, [cache_ide1_appl_sad_size] - mov edi, [cache_ide1_appl_search_start] - ret -.ide2: - cmp [hdpos], 3 - jne .ide3 - cmp [hdd_appl_data], 0 - jne .ide2_appl_data - mov ecx, [cache_ide2_system_sad_size] - mov edi, [cache_ide2_search_start] - ret -.ide2_appl_data: - mov ecx, [cache_ide2_appl_sad_size] - mov edi, [cache_ide2_appl_search_start] - ret -.ide3: - cmp [hdpos], 4 - jne .noide - cmp [hdd_appl_data], 0 - jne .ide3_appl_data - mov ecx, [cache_ide3_system_sad_size] - mov edi, [cache_ide3_search_start] - ret -.ide3_appl_data: - mov ecx, [cache_ide3_appl_sad_size] - mov edi, [cache_ide3_appl_search_start] - ret -.noide: - push eax - mov eax, [hdpos] - sub eax, 80h - cmp byte [BiosDisksData+eax*4+2], -1 - jz @f - movzx eax, byte [BiosDisksData+eax*4+2] - imul eax, cache_ide1-cache_ide0 - add eax, cache_ide0 - jmp .get -@@: - imul eax, cache_ide1-cache_ide0 - add eax, BiosDiskCaches -.get: - cmp [hdd_appl_data], 0 - jne .bd_appl_data - mov ecx, [cache_ide0_system_sad_size-cache_ide0+eax] - mov edi, [cache_ide0_search_start-cache_ide0+eax] - pop eax - ret -.bd_appl_data: - mov ecx, [cache_ide0_appl_sad_size-cache_ide0+eax] - mov edi, [cache_ide0_appl_search_start-cache_ide0+eax] - pop eax - ret -;-------------------------------------------------------------------- -align 4 -calculate_cache_4: -; cmp edi,cache_max -; 1 - IDE0 ... 4 - IDE3 -.ide0: - cmp [hdpos], 1 - jne .ide1 - cmp [hdd_appl_data], 0 - jne .ide0_appl_data - cmp edi, [cache_ide0_system_sad_size] - ret -.ide0_appl_data: - cmp edi, [cache_ide0_appl_sad_size] - ret -.ide1: - cmp [hdpos], 2 - jne .ide2 - cmp [hdd_appl_data], 0 - jne .ide1_appl_data - cmp edi, [cache_ide1_system_sad_size] - ret -.ide1_appl_data: - cmp edi, [cache_ide1_appl_sad_size] - ret -.ide2: - cmp [hdpos], 3 - jne .ide3 - cmp [hdd_appl_data], 0 - jne .ide2_appl_data - cmp edi, [cache_ide2_system_sad_size] - ret -.ide2_appl_data: - cmp edi, [cache_ide2_appl_sad_size] - ret -.ide3: - cmp [hdpos], 4 - jne .noide - cmp [hdd_appl_data], 0 - jne .ide3_appl_data - cmp edi, [cache_ide3_system_sad_size] - ret -.ide3_appl_data: - cmp edi, [cache_ide3_appl_sad_size] - ret -.noide: - push eax - mov eax, [hdpos] - sub eax, 80h - cmp byte [BiosDisksData+eax*4+2], -1 - jz @f - movzx eax, byte [BiosDisksData+eax*4+2] - imul eax, cache_ide1-cache_ide0 - add eax, cache_ide0 - jmp .get -@@: - imul eax, cache_ide1-cache_ide0 - add eax, BiosDiskCaches -.get: - cmp [hdd_appl_data], 0 - jne .bd_appl_data - cmp edi, [cache_ide0_system_sad_size-cache_ide0+eax] - pop eax - ret -.bd_appl_data: - cmp edi, [cache_ide0_appl_sad_size-cache_ide0+eax] - pop eax - ret - -;-------------------------------------------------------------------- -align 4 -calculate_cache_5: -; mov [cache_search_start],edi -; 1 - IDE0 ... 4 - IDE3 -.ide0: - cmp [hdpos], 1 - jne .ide1 - cmp [hdd_appl_data], 0 - jne .ide0_appl_data - mov [cache_ide0_search_start], edi - ret -.ide0_appl_data: - mov [cache_ide0_appl_search_start], edi - ret -.ide1: - cmp [hdpos], 2 - jne .ide2 - cmp [hdd_appl_data], 0 - jne .ide1_appl_data - mov [cache_ide1_search_start], edi - ret -.ide1_appl_data: - mov [cache_ide1_appl_search_start], edi - ret -.ide2: - cmp [hdpos], 3 - jne .ide3 - cmp [hdd_appl_data], 0 - jne .ide2_appl_data - mov [cache_ide2_search_start], edi - ret -.ide2_appl_data: - mov [cache_ide2_appl_search_start], edi - ret -.ide3: - cmp [hdpos], 4 - jne .noide - cmp [hdd_appl_data], 0 - jne .ide3_appl_data - mov [cache_ide3_search_start], edi - ret -.ide3_appl_data: - mov [cache_ide3_appl_search_start], edi - ret -.noide: - push eax - mov eax, [hdpos] - sub eax, 80h - cmp byte [BiosDisksData+eax*4+2], -1 - jz @f - movzx eax, byte [BiosDisksData+eax*4+2] - imul eax, cache_ide1-cache_ide0 - add eax, cache_ide0 - jmp .get -@@: - imul eax, cache_ide1-cache_ide0 - add eax, BiosDiskCaches -.get: - cmp [hdd_appl_data], 0 - jne .bd_appl_data - mov [cache_ide0_search_start-cache_ide0+eax], edi - pop eax - ret -.bd_appl_data: - mov [cache_ide0_appl_search_start-cache_ide0+eax], edi - pop eax - ret - -;-------------------------------------------------------------------- align 4 find_empty_slot_CD_cache: ;----------------------------------------------------------- diff --git a/kernel/trunk/boot/rdload.inc b/kernel/trunk/boot/rdload.inc index 5794cb4849..97cc8b3814 100644 --- a/kernel/trunk/boot/rdload.inc +++ b/kernel/trunk/boot/rdload.inc @@ -1,6 +1,6 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; -;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;; +;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;; ;; Distributed under terms of the GNU General Public License ;; ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -8,87 +8,70 @@ $Revision$ +read_ramdisk: ; READ RAMDISK IMAGE FROM HD cmp [boot_dev+OS_BASE+0x10000], 1 jne no_sys_on_hd - test [DRIVE_DATA+1], byte 0x40 - jz position_2 - mov [hdbase], 0x1f0 - mov [hdid], 0x0 - mov [hdpos], 1 - mov [fat32part], 0 - position_1_1: - inc [fat32part] - call search_and_read_image - cmp [image_retrieved], 1 - je yes_sys_on_hd - movzx eax, byte [DRIVE_DATA+2] - cmp [fat32part], eax - jle position_1_1 - position_2: - test [DRIVE_DATA+1], byte 0x10 - jz position_3 - mov [hdbase], 0x1f0 - mov [hdid], 0x10 - mov [hdpos], 2 - mov [fat32part], 0 - position_2_1: - inc [fat32part] - call search_and_read_image - cmp [image_retrieved], 1 - je yes_sys_on_hd - movzx eax, byte [DRIVE_DATA+3] - cmp eax, [fat32part] - jle position_2_1 - position_3: - test [DRIVE_DATA+1], byte 0x4 - jz position_4 - mov [hdbase], 0x170 - mov [hdid], 0x0 - mov [hdpos], 3 - mov [fat32part], 0 - position_3_1: - inc [fat32part] - call search_and_read_image - cmp [image_retrieved], 1 - je yes_sys_on_hd - movzx eax, byte [DRIVE_DATA+4] - cmp eax, [fat32part] - jle position_3_1 - position_4: - test [DRIVE_DATA+1], byte 0x1 - jz no_sys_on_hd - mov [hdbase], 0x170 - mov [hdid], 0x10 - mov [hdpos], 4 - mov [fat32part], 0 - position_4_1: - inc [fat32part] - call search_and_read_image - cmp [image_retrieved], 1 - je yes_sys_on_hd - movzx eax, byte [DRIVE_DATA+5] - cmp eax, [fat32part] - jle position_4_1 + xor ebp, ebp +.hd_loop: + lea eax, [ebp+'0'] + mov [read_image_fsinfo.name_digit], al + movzx eax, byte [DRIVE_DATA+2+ebp] + test eax, eax + jz .next_hd + push eax + mov esi, 1 +.partition_loop: + mov eax, esi + push -'0' +@@: + xor edx, edx + div [_10] + push edx + test eax, eax + jnz @b + mov edi, read_image_fsinfo.partition +@@: + pop eax + add al, '0' + stosb + jnz @b + mov byte [edi-1], '/' + push esi edi + mov esi, bootpath1 + mov ecx, bootpath1.len + rep movsb + call read_image + test eax, eax + jz .yes + cmp eax, 6 + jz .yes + pop edi + push edi + mov esi, bootpath2 + mov ecx, bootpath2.len + rep movsb + call read_image + test eax, eax + jz .yes + cmp eax, 6 + jz .yes + pop edi esi + inc esi + cmp esi, [esp] + jbe .partition_loop + pop eax +.next_hd: + inc ebp + cmp ebp, 4 + jb .hd_loop + jmp no_sys_on_hd +.yes: + pop edi esi eax jmp yes_sys_on_hd - search_and_read_image: - call set_FAT32_variables - mov edx, bootpath - call read_image - test eax, eax - jz image_present - mov edx, bootpath2 - call read_image - test eax, eax - jz image_present - ret - image_present: - mov [image_retrieved], 1 - ret - iglobal align 4 read_image_fsinfo: @@ -96,8 +79,16 @@ read_image_fsinfo: dq 0 ; offset: zero dd 1474560/512 ; size dd RAMDISK ; buffer - db 0 - dd hdsysimage+OS_BASE+0x10000 + db '/hd' +.name_digit db '0' + db '/' +.partition: + rb 64 ; should be enough for '255/KOLIBRI/KOLIBRI.IMG' + +bootpath1 db 'KOLIBRI.IMG',0 +.len = $ - bootpath1 +bootpath2 db 'KOLIBRI/KOLIBRI.IMG',0 +.len = $ - bootpath2 endg read_image: @@ -107,8 +98,6 @@ read_image: 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) cmp [boot_dev+OS_BASE+0x10000], 3 diff --git a/kernel/trunk/core/sys32.inc b/kernel/trunk/core/sys32.inc index 3f8b77a12f..f3511109db 100644 --- a/kernel/trunk/core/sys32.inc +++ b/kernel/trunk/core/sys32.inc @@ -578,11 +578,6 @@ terminate: ; terminate application push esi ; remove hd1 & cd & flp reservation shl esi, 5 mov esi, [esi+CURRENT_TASK+TASKDATA.pid] - cmp [hd1_status], esi - jnz @f - call free_hd_channel - and [hd1_status], 0 -@@: cmp [cd_status], esi jnz @f call free_cd_channel diff --git a/kernel/trunk/data32.inc b/kernel/trunk/data32.inc index 0c7e619682..0cb6041fd8 100644 --- a/kernel/trunk/data32.inc +++ b/kernel/trunk/data32.inc @@ -164,8 +164,6 @@ else if ~ lang eq sp 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/trunk/detect/getcache.inc b/kernel/trunk/detect/getcache.inc index 7d572d9983..994c1d855a 100644 --- a/kernel/trunk/detect/getcache.inc +++ b/kernel/trunk/detect/getcache.inc @@ -36,65 +36,27 @@ $Revision$ xor eax, eax mov [hdd_appl_data], 1;al mov [cd_appl_data], 1 - - mov ch, [DRIVE_DATA+1] - mov cl, ch - and cl, 11b - je .ide2 + + test byte [DRIVE_DATA+1], 2 + je .ide2 mov esi, cache_ide3 call get_cache_ide .ide2: - mov cl, ch - shr cl, 2 - and cl, 11b + test byte [DRIVE_DATA+1], 8 je .ide1 mov esi, cache_ide2 call get_cache_ide .ide1: - mov cl, ch - shr cl, 4 - and cl, 11b + test byte [DRIVE_DATA+1], 0x20 je .ide0 mov esi, cache_ide1 call get_cache_ide .ide0: - mov cl, ch - shr cl, 6 - and cl, 11b + test byte [DRIVE_DATA+1], 0x80 je @f mov esi, cache_ide0 call get_cache_ide @@: - xor ecx, ecx - cmp [NumBiosDisks], ecx - jz .endbd - mov esi, BiosDiskCaches -.loopbd: - push ecx - movsx ecx, byte [BiosDisksData+ecx*4+2] - inc ecx - jz .getbd - add ecx, ecx - movzx eax, byte [DRIVE_DATA+1] - shl eax, cl - and ah, 3 - cmp ah, 1 - jz .contbd - pop ecx - mov byte [BiosDisksData+ecx*4+2], -1 - push ecx -.getbd: - mov eax, [cache_ide0_size] - mov [esi+cache_ide0_size-cache_ide0], eax - mov cl, 1 - call get_cache_ide -.contbd: - pop ecx - add esi, cache_ide1-cache_ide0 - inc ecx - cmp ecx, [NumBiosDisks] - jb .loopbd -.endbd: jmp end_get_cache get_cache_ide: @@ -114,33 +76,6 @@ get_cache_ide: add ebx, edx mov [esi+cache_ide0_data_pointer-cache_ide0], ebx - cmp cl, 10b - je .cd - push ecx - mov eax, [esi+cache_ide0_system_data_size-cache_ide0] - call calculate_for_hd - add eax, [esi+cache_ide0_pointer-cache_ide0] - mov [esi+cache_ide0_system_data-cache_ide0], eax - mov [esi+cache_ide0_system_sad_size-cache_ide0], ecx - - push edi - mov edi, [esi+cache_ide0_pointer-cache_ide0] - call clear_ide_cache - pop edi - - mov eax, [esi+cache_ide0_appl_data_size-cache_ide0] - call calculate_for_hd - add eax, [esi+cache_ide0_data_pointer-cache_ide0] - mov [esi+cache_ide0_appl_data-cache_ide0], eax - mov [esi+cache_ide0_appl_sad_size-cache_ide0], ecx - - push edi - mov edi, [esi+cache_ide0_data_pointer-cache_ide0] - call clear_ide_cache - pop edi - - pop ecx - ret .cd: push ecx mov eax, [esi+cache_ide0_system_data_size-cache_ide0] @@ -168,20 +103,6 @@ get_cache_ide: pop ecx ret -calculate_for_hd: - push eax - mov ebx, eax - shr eax, 9 - shl eax, 3 - sub ebx, eax - shr ebx, 9 - mov ecx, ebx - shl ebx, 9 - pop eax - sub eax, ebx - dec ecx - ret - calculate_for_cd: push eax mov ebx, eax diff --git a/kernel/trunk/detect/sear_par.inc b/kernel/trunk/detect/sear_par.inc index e56a92a641..b53e1205b6 100644 --- a/kernel/trunk/detect/sear_par.inc +++ b/kernel/trunk/detect/sear_par.inc @@ -1,165 +1,139 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; -;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;; +;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;; ;; Distributed under terms of the GNU General Public License ;; ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; $Revision$ - -;**************************************************** -; поиск логических дисков на обнаруженных HDD -; и занесение данных в область таблицы -; автор Mario79 -;**************************************************** - mov [transfer_adress], DRIVE_DATA+0xa - search_partitions_ide0: +search_partitions: +; 1. Fill missing parameters in HD_DATA structures. + mov eax, [hd_address_table] + mov [hd0_data.hdbase], eax ;0x1f0 + mov [hd1_data.hdbase], eax + mov eax, [hd_address_table+16] + mov [hd2_data.hdbase], eax + mov [hd3_data.hdbase], eax +; 2. Notify the system about /hd* disks. +; For every existing disk, call ide_disk_add with correct parameters. +; Generate name "hdN" on the stack; this is 4 bytes including terminating zero. +; 2a. /hd0: exists if mask 0x40 in [DRIVE_DATA+1] is set, +; data: hd0_data, +; number of partitions: [DRIVE_DATA+2] test [DRIVE_DATA+1], byte 0x40 - jz search_partitions_ide1 - mov eax, [hd_address_table] - mov [hdbase], eax ;0x1f0 - mov [hdid], 0x0 - mov [hdpos], 1 - mov [known_part], 1 - search_partitions_ide0_1: - call set_PARTITION_variables - test [problem_partition], 2 - jnz search_partitions_ide1 ; not found part - test [problem_partition], 1 - jnz @F ; not found known_part - ;cmp [problem_partition],0 - ;jne search_partitions_ide1 - inc byte [DRIVE_DATA+2] - call partition_data_transfer - add [transfer_adress], 100 - @@: - inc [known_part] - jmp search_partitions_ide0_1 - - search_partitions_ide1: + jz @f + push 'hd0' + mov eax, esp ; name + mov edx, hd0_data + call ide_disk_add + mov [DRIVE_DATA+2], al + pop ecx ; restore the stack +@@: +; 2b. /hd1: exists if mask 0x10 in [DRIVE_DATA+1] is set, +; data: hd1_data, +; number of partitions: [DRIVE_DATA+3] test [DRIVE_DATA+1], byte 0x10 - jz search_partitions_ide2 - mov eax, [hd_address_table] - mov [hdbase], eax ;0x1f0 - mov [hdid], 0x10 - mov [hdpos], 2 - mov [known_part], 1 - search_partitions_ide1_1: - call set_PARTITION_variables - test [problem_partition], 2 - jnz search_partitions_ide2 - test [problem_partition], 1 - jnz @F - ;cmp [problem_partition],0 - ;jne search_partitions_ide2 - inc byte [DRIVE_DATA+3] - call partition_data_transfer - add [transfer_adress], 100 - @@: - inc [known_part] - jmp search_partitions_ide1_1 - - search_partitions_ide2: - test [DRIVE_DATA+1], byte 0x4 - jz search_partitions_ide3 - mov eax, [hd_address_table+16] - mov [hdbase], eax ;0x170 - mov [hdid], 0x0 - mov [hdpos], 3 - mov [known_part], 1 - search_partitions_ide2_1: - call set_PARTITION_variables - test [problem_partition], 2 - jnz search_partitions_ide3 - test [problem_partition], 1 - jnz @F - ;cmp [problem_partition],0 - ;jne search_partitions_ide3 - inc byte [DRIVE_DATA+4] - call partition_data_transfer - add [transfer_adress], 100 - @@: - inc [known_part] - jmp search_partitions_ide2_1 - - search_partitions_ide3: - test [DRIVE_DATA+1], byte 0x1 - jz end_search_partitions_ide - mov eax, [hd_address_table+16] - mov [hdbase], eax ;0x170 - mov [hdid], 0x10 - mov [hdpos], 4 - mov [known_part], 1 - search_partitions_ide3_1: - call set_PARTITION_variables - test [problem_partition], 2 - jnz end_search_partitions_ide - test [problem_partition], 1 - jnz @F - ;cmp [problem_partition],0 - ;jne end_search_partitions_ide - inc byte [DRIVE_DATA+5] - call partition_data_transfer - add [transfer_adress], 100 - @@: - inc [known_part] - jmp search_partitions_ide3_1 - -end_search_partitions_ide: - mov [hdpos], 80h - mov ecx, [NumBiosDisks] - test ecx, ecx - jz end_search_partitions -start_search_partitions_bd: - push ecx - mov eax, [hdpos] - and [BiosDiskPartitions+(eax-80h)*4], 0 - mov [known_part], 1 -search_partitions_bd: - call set_PARTITION_variables - test [problem_partition], 2 - jnz end_search_partitions_bd - test [problem_partition], 1 - jnz @F - ;cmp [problem_partition], 0 - ;jne end_search_partitions_bd - mov eax, [hdpos] - inc [BiosDiskPartitions+(eax-80h)*4] - call partition_data_transfer - add [transfer_adress], 100 - @@: - inc [known_part] - jmp search_partitions_bd -end_search_partitions_bd: + jz @f + push 'hd1' + mov eax, esp + mov edx, hd1_data + call ide_disk_add + mov [DRIVE_DATA+3], al pop ecx - inc [hdpos] - loop start_search_partitions_bd +@@: +; 2c. /hd2: exists if mask 4 in [DRIVE_DATA+1] is set, +; data: hd2_data, +; number of partitions: [DRIVE_DATA+4] + test [DRIVE_DATA+1], byte 4 + jz @f + push 'hd2' + mov eax, esp + mov edx, hd2_data + call ide_disk_add + mov [DRIVE_DATA+4], al + pop ecx +@@: +; 2d. /hd3: exists if mask 1 in [DRIVE_DATA+1] is set, +; data: hd3_data, +; number of partitions: [DRIVE_DATA+5] + test [DRIVE_DATA+1], byte 1 + jz @f + push 'hd3' + mov eax, esp + mov edx, hd3_data + call ide_disk_add + mov [DRIVE_DATA+5], al + pop ecx +@@: +; 3. Notify the system about /bd* disks. +; 3a. Check whether there are BIOS disks. If no, skip step 3. + xor esi, esi + cmp esi, [NumBiosDisks] + jz .nobd +; Loop over all disks. + push 0 + push 'bd' +.bdloop: +; 3b. Get the drive number for using in /bd* name. + movzx eax, byte [BiosDisksData+esi*4] + sub al, 80h +; 3c. Convert eax to decimal and store starting with [esp+3]. +; First 2 bytes in [esp] are "bd". + lea edi, [esp+2] +; store digits in the stack, ending with -'0' + push -'0' +@@: + xor edx, edx +iglobal +align 4 +_10 dd 10 +endg + div [_10] + push edx + test eax, eax + jnz @b +; restore digits from the stack, this reverses the order; +; add '0', stop, when zero is reached +@@: + pop eax + add al, '0' + stosb + jnz @b +; 3e. Call the API with userdata = 80h + ecx. + mov eax, esp + lea edx, [esi+80h] + stdcall disk_add, bd_callbacks, eax, edx, 0 + test eax, eax + jz @f + stdcall disk_media_changed, eax, 1 +@@: +; 3f. Continue the loop. + inc esi + cmp esi, [NumBiosDisks] + jnz .bdloop + pop ecx ecx ; restore stack after name +.nobd: 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 -uglobal -transfer_adress dd 0 -endg -partition_data_transfer_1: -; cli - push edi - mov edi, PARTITION_START - mov esi, [transfer_adress] - mov ecx, (file_system_data_size+3)/4 - rep movsd - pop edi -; sti +; Helper procedure for search_partitions, adds one IDE disk. +; For compatibility, number of partitions for IDE disks is kept in a separate variable, +; so the procedure returns number of partitions. +; eax -> name, edx -> disk data +proc ide_disk_add + stdcall disk_add, ide_callbacks, eax, edx, 0 + test eax, eax + jz @f + push eax + stdcall disk_media_changed, eax, 1 + pop eax + mov eax, [eax+DISK.NumPartitions] + cmp eax, 255 + jbe @f + mov eax, 255 +@@: ret +endp end_search_partitions: diff --git a/kernel/trunk/fs/ext2.inc b/kernel/trunk/fs/ext2.inc index bced74315c..ffefc05517 100644 --- a/kernel/trunk/fs/ext2.inc +++ b/kernel/trunk/fs/ext2.inc @@ -1,6 +1,6 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; -;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;; +;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;; ;; Distributed under terms of the GNU General Public License ;; ;; 02.02.2010 turbanoff - support 70.5 ;; ;; 23.01.2010 turbanoff - support 70.0 70.1 ;; @@ -177,13 +177,49 @@ struct EXT4_EXTENT_IDX ;RUS: индекс - указатель на б ei_unused dw ? ;RUS: зарезервировано ;ENG: reserved ends -ext2_test_superblock: - cmp [fs_type], 0x83 - jne .no +struct EXTFS PARTITION + Lock MUTEX + log_block_size dd ? + block_size dd ? + count_block_in_block dd ? + blocks_per_group dd ? + global_desc_table dd ? + root_inode dd ? ; pointer to root inode in memory + inode_size dd ? + count_pointer_in_block dd ? ; block_size / 4 + count_pointer_in_block_square dd ? ; (block_size / 4)**2 + ext2_save_block dd ? ;RUS: блок на глобальную 1 процедуру ;ENG: block for 1 global procedure + ext2_temp_block dd ? ;RUS: блок для мелких процедур ;ENG: block for small procedures + ext2_save_inode dd ? ;RUS: inode на глобальную процедуру ;ENG: inode for global procedure + ext2_temp_inode dd ? ;RUS: inode для мелких процедур ;ENG: inode for small procedures + groups_count dd ? + superblock rd 512/4 +ends - mov eax, [PARTITION_START] - add eax, 2 ;superblock start at 1024b - call hd_read +iglobal +align 4 +ext2_user_functions: + dd ext2_free + dd (ext2_user_functions_end - ext2_user_functions - 4) / 4 + dd ext2_Read + dd ext2_ReadFolder + dd ext2_Rewrite + dd ext2_Write + dd ext2_SetFileEnd + dd ext2_GetFileInfo + dd ext2_SetFileInfo + dd 0 + dd ext2_Delete + dd ext2_CreateFolder +ext2_user_functions_end: +endg + +proc ext2_create_partition + push ebx + + mov eax, 2 ;superblock start at 1024b + add ebx, 512 ; get pointer to fs-specific buffer + call fs_read32_sys cmp [ebx + EXT2_SB_STRUC.log_block_size], 3 ;0,1,2,3 ja .no @@ -198,27 +234,41 @@ ext2_test_superblock: test eax, EXT2_FEATURE_INCOMPAT_FILETYPE jz .no test eax, not EXT4_FEATURE_INCOMPAT_SUPP - jnz .no + jz ext2_setup - ; OK, this is correct EXT2 superblock - clc - ret .no: ; No, this superblock isn't EXT2 - stc + pop ebx + xor eax, eax ret + ; OK, this is correct EXT2 superblock ext2_setup: - mov [fs_type], 2 + movi eax, sizeof.EXTFS + call malloc + test eax, eax + jz ext2_create_partition.no + + mov ecx, dword [ebp+PARTITION.FirstSector] + mov dword [eax+EXTFS.FirstSector], ecx + mov ecx, dword [ebp+PARTITION.FirstSector+4] + mov dword [eax+EXTFS.FirstSector+4], ecx + mov ecx, dword [ebp+PARTITION.Length] + mov dword [eax+EXTFS.Length], ecx + mov ecx, dword [ebp+PARTITION.Length+4] + mov dword [eax+EXTFS.Length+4], ecx + mov ecx, [ebp+PARTITION.Disk] + mov [eax+EXTFS.Disk], ecx + mov [eax+EXTFS.FSUserFunctions], ext2_user_functions + push ebp esi + mov ebp, eax + lea ecx, [eax+EXTFS.Lock] + call mutex_init - push 512 - call kernel_alloc ; mem for superblock mov esi, ebx - mov edi, eax + lea edi, [ebp+EXTFS.superblock] mov ecx, 512/4 rep movsd ; copy sb to reserved mem - mov ebx, eax - mov [ext2_data.sb], eax mov eax, [ebx + EXT2_SB_STRUC.blocks_count] sub eax, [ebx + EXT2_SB_STRUC.first_data_block] @@ -226,72 +276,103 @@ ext2_setup: xor edx, edx div [ebx + EXT2_SB_STRUC.blocks_per_group] inc eax - mov [ext2_data.groups_count], eax + mov [ebp+EXTFS.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 [ebp+EXTFS.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 + mov [ebp+EXTFS.count_block_in_block], eax shl eax, 7 - mov [ext2_data.count_pointer_in_block], eax + mov [ebp+EXTFS.count_pointer_in_block], eax mov edx, eax ;RUS: потом еще квадрат найдем ;ENG: we'll find a square later shl eax, 2 - mov [ext2_data.block_size], eax + mov [ebp+EXTFS.block_size], eax push eax eax ; 2 kernel_alloc mov eax, edx mul edx - mov [ext2_data.count_pointer_in_block_square], eax + mov [ebp+EXTFS.count_pointer_in_block_square], eax call kernel_alloc - mov [ext2_data.ext2_save_block], eax ; and for temp block + mov [ebp+EXTFS.ext2_save_block], eax ; and for temp block call kernel_alloc - mov [ext2_data.ext2_temp_block], eax ; and for get_inode proc + mov [ebp+EXTFS.ext2_temp_block], eax ; and for get_inode proc - movzx ebp, word [ebx + EXT2_SB_STRUC.inode_size] + movzx eax, 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 + mov [ebp+EXTFS.inode_size], eax + mov [ebp+EXTFS.blocks_per_group], ecx - push ebp ebp ebp ;3 kernel_alloc + push eax eax eax ;3 kernel_alloc call kernel_alloc - mov [ext2_data.ext2_save_inode], eax + mov [ebp+EXTFS.ext2_save_inode], eax call kernel_alloc - mov [ext2_data.ext2_temp_inode], eax + mov [ebp+EXTFS.ext2_temp_inode], eax call kernel_alloc - mov [ext2_data.root_inode], eax + mov [ebp+EXTFS.root_inode], eax mov ebx, eax mov eax, EXT2_ROOT_INO call ext2_get_inode ; read root inode - jmp return_from_part_set + mov eax, ebp ; return pointer to EXTFS + pop esi ebp ebx + ret +endp + +proc ext2_free + push ebp + xchg ebp, eax + stdcall kernel_free, [ebp+EXTFS.ext2_save_block] + stdcall kernel_free, [ebp+EXTFS.ext2_temp_block] + stdcall kernel_free, [ebp+EXTFS.ext2_save_inode] + stdcall kernel_free, [ebp+EXTFS.ext2_temp_inode] + stdcall kernel_free, [ebp+EXTFS.root_inode] + xchg ebp, eax + call free + pop ebp + ret +endp + +proc ext2_lock + lea ecx, [ebp+EXTFS.Lock] + jmp mutex_lock +endp + +proc ext2_unlock + lea ecx, [ebp+EXTFS.Lock] + jmp mutex_unlock +endp ;================================================================== ;read ext2 block form FS to memory ;in: eax = i_block (address of block in ext2 terms) ; ebx = pointer to return memory +; ebp = pointer to EXTFS ;out: eax - error code (0 = no_error) ext2_get_block: push ebx ecx - mov ecx, [ext2_data.log_block_size] + mov ecx, [ebp+EXTFS.log_block_size] shl eax, cl - add eax, [PARTITION_START] - mov ecx, [ext2_data.count_block_in_block] + mov ecx, eax + push [ebp+EXTFS.count_block_in_block] @@: - call hd_read - cmp [hd_error], 0 + mov eax, ecx + call fs_read32_sys + test eax, eax jnz .fail - inc eax + inc ecx add ebx, 512 - loop @B + dec dword [esp] + jnz @B + pop ecx xor eax, eax @@: pop ecx ebx @@ -304,16 +385,17 @@ ext2_get_block: ;=================================================================== ;RUS: получает номер блока из extent inode ;ENG: receives block number from extent inode ;RUS: in: ecx = номер блока по порядку ;ENG: in: ecx = consecutive block number -;RUS: ebp = адрес extent header`а ;ENG: ebp = address of extent header +;RUS: esi = адрес extent header`а ;ENG: esi = address of extent header +;RUS: ebp = указатель на структуру EXTFS ;ENG: ebp = pointer to EXTFS ;RUS: out: ecx - адрес очередного блока в случае успеха ;ENG: out: ecx - address of next block, if successful ;RUS: eax - номер ошибки (если равно 0, то ошибки нет) ;ENG: eax - error number (0 - no error) ext4_block_recursive_search: - cmp word [ebp + EXT4_EXTENT_HEADER.eh_magic], 0xF30A ;EXT4_EXT_MAGIC + cmp word [esi + 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 + movzx ebx, [esi + EXT4_EXTENT_HEADER.eh_entries] + add esi, sizeof.EXT4_EXTENT_HEADER + cmp word [esi - sizeof.EXT4_EXTENT_HEADER + EXT4_EXTENT_HEADER.eh_depth], 0 je .leaf_block ;листовой ли это блок? ;не листовой блок, а индексный ; eax - ext4_extent_idx @@ -325,48 +407,48 @@ ext4_block_recursive_search: cmp ebx, 1 ;у индексов не хранится длина, je .end_search_index ;поэтому, если остался последний - то это нужный - cmp ecx, [ebp + EXT4_EXTENT_IDX.ei_block] + cmp ecx, [esi + EXT4_EXTENT_IDX.ei_block] jb .fail - cmp ecx, [ebp + sizeof.EXT4_EXTENT_IDX + EXT4_EXTENT_IDX.ei_block] ;блок слeдующего индекса + cmp ecx, [esi + sizeof.EXT4_EXTENT_IDX + EXT4_EXTENT_IDX.ei_block] ;блок слeдующего индекса jb .end_search_index ;следующий дальше - значит текущий, то что нам нужен - add ebp, sizeof.EXT4_EXTENT_IDX + add esi, 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] + mov ebx, [ebp+EXTFS.ext2_temp_block] + mov eax, [esi + EXT4_EXTENT_IDX.ei_leaf_lo] call ext2_get_block test eax, eax jnz .fail - mov ebp, ebx + mov esi, ebx jmp ext4_block_recursive_search ;рекурсивно прыгаем в начало - .leaf_block: ;листовой блок ebp - ext4_extent + .leaf_block: ;листовой блок esi - ext4_extent ;цикл по экстентам @@: test ebx, ebx jz .fail ;ни один узел не подошел - ошибка - mov edx, [ebp + EXT4_EXTENT.ee_block] + mov edx, [esi + EXT4_EXTENT.ee_block] cmp ecx, edx jb .fail ;если меньше, значит он был в предыдущих блоках -> ошибка - movzx edi, [ebp + EXT4_EXTENT.ee_len] + movzx edi, [esi + EXT4_EXTENT.ee_len] add edx, edi cmp ecx, edx jb .end_search_extent ;нашли нужный блок - add ebp, sizeof.EXT4_EXTENT + add esi, 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 блоках + mov edx, [esi + EXT4_EXTENT.ee_start_lo] + sub ecx, [esi + EXT4_EXTENT.ee_block] ;разница в ext4 блоках add ecx, edx xor eax, eax ret @@ -378,15 +460,16 @@ ext4_block_recursive_search: ;=================================================================== ;получает адрес ext2 блока из inode с определнным номером ;RUS: in: ecx = номер блока в inode (0..) ;ENG: in: ecx = number of block in inode (0..) -;RUS: ebp = адрес inode ;ENG: ebp = inode address +;RUS: esi = адрес inode ;ENG: esi = inode address +;RUS: ebp = указатель на структуру EXTFS;ENG: ebp = pointer to EXTFS ;RUS: out: ecx = адрес очередного блока ;ENG: out: ecx = next block address ;RUS: eax - error code ;ENG: eax - error code ext2_get_inode_block: - test [ebp + EXT2_INODE_STRUC.i_flags], EXT2_EXTENTS_FL + test [esi + EXT2_INODE_STRUC.i_flags], EXT2_EXTENTS_FL jz @F pushad - add ebp, EXT2_INODE_STRUC.i_block ;ebp - extent_header + add esi, EXT2_INODE_STRUC.i_block ;esi - extent_header call ext4_block_recursive_search mov PUSHAD_ECX, ecx mov PUSHAD_EAX, eax @@ -398,26 +481,26 @@ ext2_get_inode_block: jb .get_direct_block sub ecx, 12 - cmp ecx, [ext2_data.count_pointer_in_block] ; 12.. - indirect blocks + cmp ecx, [ebp+EXTFS.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] + sub ecx, [ebp+EXTFS.count_pointer_in_block] + cmp ecx, [ebp+EXTFS.count_pointer_in_block_square] jb .get_double_indirect_block - sub ecx, [ext2_data.count_pointer_in_block_square] + sub ecx, [ebp+EXTFS.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] + mov eax, [esi + EXT2_INODE_STRUC.i_block + 14*4] + mov ebx, [ebp+EXTFS.ext2_temp_block] call ext2_get_block test eax, eax jnz .fail xor edx, edx mov eax, ecx - div [ext2_data.count_pointer_in_block_square] + div [ebp+EXTFS.count_pointer_in_block_square] ;RUS: eax - номер в полученном блоке edx - номер дальше ;ENG: eax - current block number, edx - next block number @@ -432,8 +515,8 @@ ext2_get_inode_block: .get_double_indirect_block: push edx ebx - mov eax, [ebp + EXT2_INODE_STRUC.i_block + 13*4] - mov ebx, [ext2_data.ext2_temp_block] + mov eax, [esi + EXT2_INODE_STRUC.i_block + 13*4] + mov ebx, [ebp+EXTFS.ext2_temp_block] call ext2_get_block test eax, eax jnz .fail @@ -441,7 +524,7 @@ ext2_get_inode_block: mov eax, ecx @@: xor edx, edx - div [ext2_data.count_pointer_in_block] + div [ebp+EXTFS.count_pointer_in_block] mov eax, [ebx + eax*4] call ext2_get_block @@ -455,8 +538,8 @@ ext2_get_inode_block: .get_indirect_block: push ebx - mov eax, [ebp + EXT2_INODE_STRUC.i_block + 12*4] - mov ebx, [ext2_data.ext2_temp_block] + mov eax, [esi + EXT2_INODE_STRUC.i_block + 12*4] + mov ebx, [ebp+EXTFS.ext2_temp_block] call ext2_get_block test eax, eax jnz @F ;RUS: если не было ошибки ;ENG: if there was no error @@ -467,7 +550,7 @@ ext2_get_inode_block: ret .get_direct_block: - mov ecx, [ebp + EXT2_INODE_STRUC.i_block + ecx*4] + mov ecx, [esi + EXT2_INODE_STRUC.i_block + ecx*4] xor eax, eax ret @@ -475,6 +558,7 @@ ext2_get_inode_block: ;get content inode by num ;in: eax = inode_num ; ebx = address of inode content +; ebp = pointer to EXTFS ;out: eax - error code ext2_get_inode: pushad @@ -482,8 +566,7 @@ ext2_get_inode: dec eax xor edx, edx - mov ecx, [ext2_data.sb] - div [ecx + EXT2_SB_STRUC.inodes_per_group] + div [ebp + EXT2_SB_STRUC.inodes_per_group + EXTFS.superblock] push edx ;locale num in group @@ -494,10 +577,10 @@ ext2_get_inode: ;RUS: найдем блок в котором он находится ;ENG: in eax - inode group offset relative to global descriptor table start ;ENG: let's find the block this inode is in - div [ext2_data.block_size] - add eax, [ecx + EXT2_SB_STRUC.first_data_block] + div [ebp+EXTFS.block_size] + add eax, [ebp + EXT2_SB_STRUC.first_data_block + EXTFS.superblock] inc eax - mov ebx, [ext2_data.ext2_temp_block] + mov ebx, [ebp+EXTFS.ext2_temp_block] call ext2_get_block test eax, eax jnz .fail @@ -505,27 +588,28 @@ ext2_get_inode: add ebx, edx ;RUS: локальный номер в блоке ;ENG: local number inside block mov eax, [ebx + EXT2_BLOCK_GROUP_DESC.inode_table] ;RUS: номер блока - в терминах ext2 ;ENG: block number - in ext2 terms - mov ecx, [ext2_data.log_block_size] + mov ecx, [ebp+EXTFS.log_block_size] shl eax, cl - add eax, [PARTITION_START] ;RUS: а старт раздела - в терминах hdd (512) - ;ENG: partition start - in HDD terms (512) ;RUS: eax - указывает на таблицу inode-ов на hdd ;ENG: eax - points to inode table on HDD mov esi, eax ;RUS: сохраним его пока в esi ;ENG: let's save it in esi for now ;RUS: прибавим локальный адрес inode-а ;ENG: add local address of inode pop eax ; index - mov ecx, [ext2_data.inode_size] + mov ecx, [ebp+EXTFS.inode_size] mul ecx ; (index * inode_size) - mov ebp, 512 - div ebp ;RUS: поделим на размер блока ;ENG: divide by block size + ;RUS: поделим на размер блока ;ENG: divide by block size + mov ecx, eax + and ecx, 512 - 1 + shrd eax, edx, 9 add eax, esi ;RUS: нашли адрес блока для чтения ;ENG: found block address to read - mov ebx, [ext2_data.ext2_temp_block] - call hd_read - cmp [hd_error], 0 + mov ebx, [ebp+EXTFS.ext2_temp_block] + call fs_read32_sys + test eax, eax jnz .fail - mov esi, edx ;RUS: добавим "остаток" ;ENG: add the "remainder" + mov esi, ecx ;RUS: добавим "остаток" ;ENG: add the "remainder" + mov ecx, [ebp+EXTFS.inode_size] add esi, ebx ;RUS: к адресу ;ENG: to the address rep movsb ;RUS: копируем inode ;ENG: copy inode xor eax, eax @@ -535,55 +619,47 @@ ext2_get_inode: ret ;---------------------------------------------------------------- -; -; ext2_HdReadFolder - read disk folder -; -; 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 -; -;-------------------------------------------------------------- -ext2_HdReadFolder: +; ext2_ReadFolder - EXT2FS implementation of reading a folder +; in: ebp = pointer to EXTFS structure +; in: esi+[esp+4] = name +; in: ebx = pointer to parameters from sysfunc 70 +; out: eax, ebx = return values for sysfunc 70 +;---------------------------------------------------------------- +ext2_ReadFolder: + call ext2_lock cmp byte [esi], 0 jz .root_folder - push ebx ecx edx - call ext2_find_lfn ;вернет в ebp адрес inode - pop edx ecx ebx + push ebx + stdcall ext2_find_lfn, [esp+4+4] ;вернет в esi адрес inode + pop ebx test eax, eax jnz .error_ret - test [ebp + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR + test [esi + 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 + mov esi, [ebp+EXTFS.root_inode] + test [esi + 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] + mov edi, [ebp+EXTFS.ext2_save_inode] + mov ecx, [ebp+EXTFS.inode_size] shr ecx, 2 - mov ebp, edi + push edi rep movsd - pop ecx + pop esi @@: - cmp [ebp + EXT2_INODE_STRUC.i_size], 0 ;папка пуста + cmp [esi + EXT2_INODE_STRUC.i_size], 0 ;папка пуста je .error_empty_dir + mov edx, [ebx + 16] push edx ;адрес результата [edi + 28] push 0 ;конец очередного блока папки [edi + 24] - push ecx ;сколько файлов нужно прочитать [edi + 20] - push dword [ebx] ;первый "нужный" файл [edi + 16] - push dword [ebx + 4];флаги [edi + 12] + push dword [ebx +12];сколько файлов нужно прочитать [edi + 20] + push dword [ebx + 4];первый "нужный" файл [edi + 16] + push dword [ebx + 8];флаги [edi + 12] push 0 ;[EXT2_read_in_folder] [edi + 8] push 0 ;[EXT2_files_in_folder] [edi + 4] push 0 ;номер блока по порядку [edi] @@ -601,40 +677,40 @@ ext2_HdReadFolder: jnz .error_get_block mov eax, ecx - mov ebx, [ext2_data.ext2_save_block] + mov ebx, [ebp+EXTFS.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 eax, ebx ; ebx = current dir record + add eax, [ebp+EXTFS.block_size] + mov [edi + 24], eax ; запомним конец очередного блока mov ecx, [edi + 16] ; ecx = first wanted (flags ommited) .find_wanted_start: jecxz .find_wanted_end .find_wanted_cycle: - cmp [esi + EXT2_DIR_STRUC.inode], 0 ; if (inode = 0) => not used + cmp [ebx + EXT2_DIR_STRUC.inode], 0 ; if (inode = 0) => not used jz @F inc dword [edi + 4] ; EXT2_files_in_folder dec ecx @@: - movzx ebx, [esi + EXT2_DIR_STRUC.rec_len] + movzx eax, [ebx + EXT2_DIR_STRUC.rec_len] - cmp ebx, 12 ; минимальная длина записи + cmp eax, 12 ; минимальная длина записи jb .error_bad_len - test ebx, 0x3 ; длина записи должна делиться на 4 + test eax, 0x3 ; длина записи должна делиться на 4 jnz .error_bad_len - sub [ebp + EXT2_INODE_STRUC.i_size], ebx ;вычитаем напрямую из структуры inode - add esi, ebx ; к следующей записи - cmp esi, [edi + 24] ; сравниваем с концом блока + sub [esi + EXT2_INODE_STRUC.i_size], eax ;вычитаем напрямую из структуры inode + add ebx, eax ; к следующей записи + cmp ebx, [edi + 24] ; сравниваем с концом блока jb .find_wanted_start push .find_wanted_start .end_block: ;вылетели из цикла - cmp [ebp + EXT2_INODE_STRUC.i_size], 0 + cmp [esi + EXT2_INODE_STRUC.i_size], 0 jle .end_dir inc dword [edi] ;получаем новый блок @@ -645,15 +721,15 @@ ext2_HdReadFolder: jnz .error_get_block mov eax, ecx - mov ebx, [ext2_data.ext2_save_block] + mov ebx, [ebp+EXTFS.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 ;запомним конец блока + mov eax, ebx + add eax, [ebp+EXTFS.block_size] + mov [edi + 24], eax ;запомним конец блока ret ; опять в цикл .wanted_end: @@ -664,7 +740,7 @@ ext2_HdReadFolder: mov ecx, [edi + 20] .wanted_start: ; ищем first_wanted+count jecxz .wanted_end - cmp [esi + EXT2_DIR_STRUC.inode], 0 ; if (inode = 0) => not used + cmp [ebx + EXT2_DIR_STRUC.inode], 0 ; if (inode = 0) => not used jz .empty_rec inc dword [edi + 8] inc dword [edi + 4] @@ -676,9 +752,9 @@ ext2_HdReadFolder: rep stosd pop ecx edi - push esi edi edx - mov eax, [esi + EXT2_DIR_STRUC.inode] ;получим дочерний inode - mov ebx, [ext2_data.ext2_temp_inode] + push ebx edi edx + mov eax, [ebx + EXT2_DIR_STRUC.inode] ;получим дочерний inode + mov ebx, [ebp+EXTFS.ext2_temp_inode] call ext2_get_inode test eax, eax jnz .error_read_subinode @@ -716,13 +792,14 @@ ext2_HdReadFolder: xor dword [edx], FS_FT_DIR ;помечаем, что это файл ;теперь скопируем имя, сконвертировав из UTF-8 в CP866 - push ecx ;edi и esi уже сохранены в стеке + push ecx esi ;edi уже сохранен в стеке + mov esi, [esp+12] movzx ecx, [esi + EXT2_DIR_STRUC.name_len] lea edi, [edx + 40] lea esi, [esi + EXT2_DIR_STRUC.name] call utf8_to_cp866 and byte [edi], 0 - pop ecx edi esi + pop esi ecx edi ebx cmp byte [edx + 40], '.' ; в linux файл, начинающийся с точки - скрытый jne @F @@ -732,21 +809,22 @@ ext2_HdReadFolder: add edx, 40 + 264 ; go to next record dec ecx ; если запись пустая ecx не надо уменьшать .empty_rec: - movzx ebx, [esi + EXT2_DIR_STRUC.rec_len] - cmp ebx, 12 ; минимальная длина записи + movzx eax, [ebx + EXT2_DIR_STRUC.rec_len] + cmp eax, 12 ; минимальная длина записи jb .error_bad_len - test ebx, 0x3 ; длина записи должна делиться на 4 + test eax, 0x3 ; длина записи должна делиться на 4 jnz .error_bad_len - sub [ebp + EXT2_INODE_STRUC.i_size], ebx ;вычитаем напрямую из структуры inode - add esi, ebx - cmp esi, [edi + 24] ;дошли ли до конца блока? + sub [esi + EXT2_INODE_STRUC.i_size], eax ;вычитаем напрямую из структуры inode + add ebx, eax + cmp ebx, [edi + 24] ;дошли ли до конца блока? jb .wanted_start push .wanted_start ; дошли jmp .end_block .end_dir: ;конец папки, когда еще не дошли до нужного файла + call ext2_unlock mov edx, [edi + 28] ;адрес структуры результата mov ebx, [edi + 8] ;EXT2_read_in_folder mov ecx, [edi + 4] ;EXT2_files_in_folder @@ -770,6 +848,9 @@ ext2_HdReadFolder: lea esp, [edi + 32] .error_ret: or ebx, -1 + push eax + call ext2_unlock + pop eax ret .error_empty_dir: ;RUS: inode папки без блоков ;ENG: inode of folder without blocks @@ -834,84 +915,76 @@ utf8_to_cp866: ret ;---------------------------------------------------------------- -; -; ext2_HdRead - read hard disk -; -; 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 -; -; ret ebx = bytes read or 0xffffffff file not found -; eax = 0 ok read or other = errormsg - -;-------------------------------------------------------------- -ext2_HdRead: +; ext2_Read - EXT2FS implementation of reading a file +; in: ebp = pointer to FAT structure +; in: esi+[esp+4] = name +; in: ebx = pointer to parameters from sysfunc 70 +; out: eax, ebx = return values for sysfunc 70 +;---------------------------------------------------------------- +ext2_Read: + call ext2_lock cmp byte [esi], 0 jnz @F .this_is_nofile: + call ext2_unlock or ebx, -1 mov eax, ERROR_ACCESS_DENIED ret @@: - push ecx ebx edx - call ext2_find_lfn - pop edx ebx ecx + push ebx + stdcall ext2_find_lfn, [esp+4+4] + pop ebx test eax, eax jz @F + call ext2_unlock or ebx, -1 mov eax, ERROR_FILE_NOT_FOUND ret @@: - mov ax, [ebp + EXT2_INODE_STRUC.i_mode] + mov ax, [esi + EXT2_INODE_STRUC.i_mode] and ax, EXT2_S_IFMT ;оставляем только тип inode в ax cmp ax, EXT2_S_IFREG jne .this_is_nofile - mov edi, edx ; edi = pointer to return mem + mov edi, [ebx+16] ; edi = pointer to return mem + mov ecx, [ebx+12] - test ebx, ebx - jz @F - mov esi, ebx ; esi = pointer to first_wanted - mov ebx, [esi+4] - mov eax, [esi] ;RUS: ebx : eax - стартовый номер байта ;ENG: ebx : eax - start byte number + mov eax, [ebx+4] + mov edx, [ebx+8] ;RUS: edx : eax - стартовый номер байта ;ENG: edx : eax - start byte number ;RUS: ///// сравним хватит ли нам файла или нет ;ENG: ///// check if file is big enough for us - cmp [ebp + EXT2_INODE_STRUC.i_dir_acl], ebx + cmp [esi + EXT2_INODE_STRUC.i_dir_acl], edx ja .size_great jb .size_less - cmp [ebp + EXT2_INODE_STRUC.i_size], eax + cmp [esi + EXT2_INODE_STRUC.i_size], eax ja .size_great .size_less: + call ext2_unlock xor ebx, ebx mov eax, ERROR_END_OF_FILE ret - @@: - xor ebx, ebx - xor eax, eax .size_great: add eax, ecx ;RUS: add to first_wanted кол-во байт для чтения ;ENG: add to first_wanted number of bytes to read - adc ebx, 0 + adc edx, 0 - cmp [ebp + EXT2_INODE_STRUC.i_dir_acl], ebx + cmp [esi + EXT2_INODE_STRUC.i_dir_acl], edx ja .size_great_great jb .size_great_less - cmp [ebp + EXT2_INODE_STRUC.i_size], eax + cmp [esi + EXT2_INODE_STRUC.i_size], eax jae .size_great_great ; and if it's equal, no matter where we jump .size_great_less: push 1 ;RUS: читаем по границе размера ;ENG: reading till the end of file - mov ecx, [ebp + EXT2_INODE_STRUC.i_size] - sub ecx, [esi] ;RUS: (размер - старт) = сколько читать ;ENG: to read = (size - start) + mov ecx, [esi + EXT2_INODE_STRUC.i_size] + sub ecx, [ebx+4] ;RUS: (размер - старт) = сколько читать ;ENG: to read = (size - start) jmp @F .size_great_great: @@ -923,13 +996,11 @@ ext2_HdRead: ;esi -> first wanted push ecx ;количество считанных байт - test esi, esi - jz .zero_start ;получим кусок из первого блока - mov edx, [esi+4] - mov eax, [esi] - div [ext2_data.block_size] + mov edx, [ebx+8] + mov eax, [ebx+4] + div [ebp+EXTFS.block_size] push eax ;счетчик блоков ложим в стек @@ -938,7 +1009,7 @@ ext2_HdRead: call ext2_get_inode_block test eax, eax jnz .error_at_first_block - mov ebx, [ext2_data.ext2_save_block] + mov ebx, [ebp+EXTFS.ext2_save_block] mov eax, ecx call ext2_get_block test eax, eax @@ -947,7 +1018,7 @@ ext2_HdRead: add ebx, edx neg edx - add edx, [ext2_data.block_size] ;RUS: block_size - стартовый байт = сколько байт 1-го блока + add edx, [ebp+EXTFS.block_size] ;RUS: block_size - стартовый байт = сколько байт 1-го блока ;ENG: block_size - start byte = number of bytes in 1st block cmp ecx, edx jbe .only_one_block @@ -956,18 +1027,16 @@ ext2_HdRead: sub eax, edx mov ecx, edx + push esi mov esi, ebx rep movsb ;RUS: кусок 1-го блока ;ENG: part of 1st block - jmp .calc_blocks_count + pop esi - .zero_start: - mov eax, ecx - push 0 ;счетчик блоков ложим в стек ;теперь в eax кол-во оставшихся байт для чтения .calc_blocks_count: mov ebx, edi ;чтение блока прям в ->ebx xor edx, edx - div [ext2_data.block_size] ;кол-во байт в последнем блоке (остаток) в edx + div [ebp+EXTFS.block_size] ;кол-во байт в последнем блоке (остаток) в edx mov edi, eax ;кол-во целых блоков в edi @@: test edi, edi @@ -982,7 +1051,7 @@ ext2_HdRead: call ext2_get_block test eax, eax jnz .error_at_read_cycle - add ebx, [ext2_data.block_size] + add ebx, [ebp+EXTFS.block_size] dec edi jmp @B @@ -999,7 +1068,7 @@ ext2_HdRead: mov edi, ebx mov eax, ecx - mov ebx, [ext2_data.ext2_save_block] + mov ebx, [ebp+EXTFS.ext2_save_block] call ext2_get_block test eax, eax jnz .error_at_finish_block @@ -1013,6 +1082,7 @@ ext2_HdRead: pop ecx ;счетчик блоков, который хранился в стеке @@: pop ebx ;количество считанных байт + call ext2_unlock pop eax ; 1 или 0 - достигли ли конца файла test eax, eax jz @F @@ -1035,17 +1105,21 @@ ext2_HdRead: .error_at_finish_block: pop ecx edx or ebx, -1 + push eax + call ext2_unlock + pop eax ret ;---------------------------------------------------------------- ; in: esi = file path ; ebx = pointer to dir block +; ebp = pointer to EXTFS structure ; out: esi - name without parent or not_changed ; ebx - dir_rec of inode children ext2_test_block_by_name: sub esp, 256 ;EXT2_filename mov edx, ebx - add edx, [ext2_data.block_size] ;RUS: запомним конец блока ;ENG: save block end + add edx, [ebp+EXTFS.block_size] ;RUS: запомним конец блока ;ENG: save block end .start_rec: cmp [ebx + EXT2_DIR_STRUC.inode], 0 @@ -1097,32 +1171,37 @@ ext2_test_block_by_name: ;======================== ;Ищет inode по строке пути -;in: esi = name +;in: esi+[esp+4] = name +; ebp = pointer to EXTFS ;out: eax - error code -; ebp = inode +; esi = inode ; dl - первый байт из имени файла/папки ext2_find_lfn: - mov ebp, [ext2_data.root_inode] - cmp [ebp + EXT2_INODE_STRUC.i_blocks], 0 + mov edx, [ebp+EXTFS.root_inode] + cmp [edx + EXT2_INODE_STRUC.i_blocks], 0 je .error_empty_root .next_path_part: - push [ebp + EXT2_INODE_STRUC.i_blocks] + push [edx + EXT2_INODE_STRUC.i_blocks] xor ecx, ecx .folder_block_cycle: push ecx + xchg esi, edx call ext2_get_inode_block + xchg esi, edx test eax, eax jnz .error_get_inode_block mov eax, ecx - mov ebx, [ext2_data.ext2_save_block] ;ebx = cur dir record + mov ebx, [ebp+EXTFS.ext2_save_block] ;ebx = cur dir record call ext2_get_block test eax, eax jnz .error_get_block push esi + push edx call ext2_test_block_by_name + pop edx pop edi ecx cmp edi, esi ;RUS: нашли имя? ;ENG: did we find a name? @@ -1130,24 +1209,29 @@ ext2_find_lfn: cmp byte [esi], 0 ;RUS: дошли до "конца" пути -> возваращаемся ;ENG: reached the "end" of path -> returning + jnz @f + cmp dword [esp+8], 0 jz .get_inode_ret + mov esi, [esp+8] + mov dword [esp+8], 0 + @@: cmp [ebx + EXT2_DIR_STRUC.file_type], EXT2_FT_DIR ;RUS: нашли, но это не папка jne .not_found ;ENG: found, but it's not a folder mov eax, [ebx + EXT2_DIR_STRUC.inode] - mov ebx, [ext2_data.ext2_save_inode] ;RUS: все же папка. ;ENG: it's a folder afterall + mov ebx, [ebp+EXTFS.ext2_save_inode] ;RUS: все же папка. ;ENG: it's a folder afterall call ext2_get_inode test eax, eax jnz .error_get_inode pop ecx ;RUS: в стеке лежит кол-во блоков ;ENG: stack top contains number of blocks - mov ebp, ebx + mov edx, ebx jmp .next_path_part .next_folder_block: ;к следующему блоку в текущей папке pop eax ;RUS: счетчик блоков ;ENG: blocks counter - sub eax, [ext2_data.count_block_in_block] + sub eax, [ebp+EXTFS.count_block_in_block] jle .not_found push eax @@ -1156,17 +1240,17 @@ ext2_find_lfn: .not_found: mov eax, ERROR_FILE_NOT_FOUND - ret + ret 4 .get_inode_ret: pop ecx ;RUS: в стеке лежит кол-во блоков ;ENG: stack top contains number of blocks mov dl, [ebx + EXT2_DIR_STRUC.name] ;RUS: в dl - первый символ () ;ENG: ??? mov eax, [ebx + EXT2_DIR_STRUC.inode] - mov ebx, [ext2_data.ext2_save_inode] + mov ebx, [ebp+EXTFS.ext2_save_inode] call ext2_get_inode - mov ebp, ebx + mov esi, ebx xor eax, eax - ret + ret 4 .error_get_inode_block: .error_get_block: @@ -1175,30 +1259,35 @@ ext2_find_lfn: pop ebx .error_empty_root: mov eax, ERROR_FS_FAIL - ret + ret 4 ;---------------------------------------------------------------- -;ext2_HdGetFileInfo - read file info from block device -; -;in: esi points to filename -; edx mem location to return data -;-------------------------------------------------------------- -ext2_HdGetFileInfo: - xchg bx, bx +; ext2_GetFileInfo - EXT2 implementation of getting file info +; in: ebp = pointer to EXTFS structure +; in: esi+[esp+4] = name +; in: ebx = pointer to parameters from sysfunc 70 +; out: eax, ebx = return values for sysfunc 70 +;---------------------------------------------------------------- +ext2_GetFileInfo: + call ext2_lock + mov edx, [ebx+16] cmp byte [esi], 0 jz .is_root push edx - call ext2_find_lfn + stdcall ext2_find_lfn, [esp+4+4] mov ebx, edx pop edx test eax, eax jz @F + push eax + call ext2_unlock + pop eax ret .is_root: xor ebx, ebx ;RUS: root не может быть скрытым ;ENG: root cannot be hidden - mov ebp, [ext2_data.root_inode] + mov esi, [ebp+EXTFS.root_inode] @@: xor eax, eax mov edi, edx @@ -1210,10 +1299,10 @@ ext2_HdGetFileInfo: or dword [edx], FS_FT_HIDDEN @@: - test [ebp + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR + test [esi + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR jnz @F - mov eax, [ebp + EXT2_INODE_STRUC.i_size] ;low size - mov ebx, [ebp + EXT2_INODE_STRUC.i_dir_acl] ;high size + mov eax, [esi + EXT2_INODE_STRUC.i_size] ;low size + mov ebx, [esi + EXT2_INODE_STRUC.i_dir_acl] ;high size mov dword [edx+32], eax mov dword [edx+36], ebx xor dword [edx], FS_FT_DIR @@ -1221,33 +1310,34 @@ ext2_HdGetFileInfo: xor dword [edx], FS_FT_DIR lea edi, [edx + 8] - mov eax, [ebp + EXT2_INODE_STRUC.i_ctime] + mov eax, [esi + EXT2_INODE_STRUC.i_ctime] xor edx, edx add eax, 3054539008 adc edx, 2 call ntfs_datetime_to_bdfe.sec - mov eax, [ebp + EXT2_INODE_STRUC.i_atime] + mov eax, [esi + EXT2_INODE_STRUC.i_atime] xor edx, edx add eax, 3054539008 adc edx, 2 call ntfs_datetime_to_bdfe.sec - mov eax, [ebp + EXT2_INODE_STRUC.i_mtime] + mov eax, [esi + EXT2_INODE_STRUC.i_mtime] xor edx, edx add eax, 3054539008 adc edx, 2 call ntfs_datetime_to_bdfe.sec + call ext2_unlock xor eax, eax ret -ext2_HdRewrite: -ext2_HdWrite: -ext2_HdSetFileEnd: -ext2_HdSetFileInfo: -ext2_HdDelete: -ext2_HdCreateFolder: +ext2_Rewrite: +ext2_Write: +ext2_SetFileEnd: +ext2_SetFileInfo: +ext2_Delete: +ext2_CreateFolder: xor ebx, ebx mov eax, ERROR_UNSUPPORTED_FS ret diff --git a/kernel/trunk/fs/fat32.inc b/kernel/trunk/fs/fat32.inc index 90609fc9e5..6632ed5b6d 100644 --- a/kernel/trunk/fs/fat32.inc +++ b/kernel/trunk/fs/fat32.inc @@ -1,6 +1,6 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; -;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;; +;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;; ;; Distributed under terms of the GNU General Public License ;; ;; ;; ;; FAT32.INC ;; @@ -58,16 +58,15 @@ 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 +struct FAT PARTITION 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 + ; 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 @@ -121,6 +120,7 @@ endg iglobal align 4 fat_user_functions: + dd free dd (fat_user_functions_end - fat_user_functions - 4) / 4 dd fat_Read dd fat_ReadFolder @@ -138,17 +138,15 @@ 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 + cmp dword [esp+4], 0 jnz .return0 ; bootsector signature must be correct cmp word [ebx+0x1fe], 0xaa55 @@ -170,16 +168,17 @@ fat_create_partition: call malloc 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 + mov ecx, dword [ebp+PARTITION.FirstSector] + mov dword [eax+FAT.FirstSector], ecx + mov ecx, dword [ebp+PARTITION.FirstSector+4] + mov dword [eax+FAT.FirstSector+4], ecx + mov ecx, dword [ebp+PARTITION.Length] + mov dword [eax+FAT.Length], ecx + mov ecx, dword [ebp+PARTITION.Length+4] + mov dword [eax+FAT.Length+4], ecx + mov ecx, [ebp+PARTITION.Disk] + mov [eax+FAT.Disk], ecx + mov [eax+FAT.FSUserFunctions], fat_user_functions or [eax+FAT.fat_in_cache], -1 mov [eax+FAT.fat_change], 0 push ebp @@ -226,8 +225,8 @@ fat_create_partition: jnz @f mov eax, [ebx+0x20] ; total sector count @@: - mov dword [ebp+FAT.p.Length], eax - and dword [ebp+FAT.p.Length+4], 0 + mov dword [ebp+FAT.Length], eax + and dword [ebp+FAT.Length+4], 0 sub eax, [ebp+FAT.DATA_START] ; eax = count of data sectors xor edx, edx div [ebp+FAT.SECTORS_PER_CLUSTER] @@ -262,7 +261,6 @@ fat_create_partition: 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 @@ -274,7 +272,6 @@ fat_create_partition: 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 @@ -768,42 +765,6 @@ hd_find_lfn: 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 -; -; ret ebx = bytes read or 0xffffffff file not found -; eax = 0 ok read or other = errormsg -; -;-------------------------------------------------------------- -fs_HdRead: - cmp [fs_type], 16 - jz @f - cmp [fs_type], 32 - jz @f - cmp [fs_type], 1 - jz ntfs_HdRead - cmp [fs_type], 2 - jz ext2_HdRead - or ebx, -1 - 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 @@ -943,43 +904,6 @@ fat_Read: sub ebx, edx jmp .reteof -;---------------------------------------------------------------- -; -; 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], 16 - jz @f - cmp [fs_type], 32 - jz @f - cmp [fs_type], 1 - jz ntfs_HdReadFolder - cmp [fs_type], 2 - jz ext2_HdReadFolder - movi eax, ERROR_UNSUPPORTED_FS - 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 @@ -1377,52 +1301,6 @@ fat_get_sector: pop ecx ret -;---------------------------------------------------------------- -; -; 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 -; -;-------------------------------------------------------------- -fs_HdCreateFolder: - mov al, 1 - jmp fs_HdRewrite.common - -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 @@ -1441,7 +1319,7 @@ fat_CreateFolder: jmp fat_Rewrite.common ;---------------------------------------------------------------- -; fat_HdRewrite - FAT16/32 implementation of creating a new file +; fat_Rewrite - 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 @@ -1988,51 +1866,16 @@ fat_Rewrite: mov [edi-32+20], cx jmp .writedircont -;---------------------------------------------------------------- -; -; 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 -; -;-------------------------------------------------------------- fat_Write.access_denied: push ERROR_ACCESS_DENIED -fs_HdWrite.ret0: +fat_Write.ret0: pop eax xor ebx, ebx ret -fs_HdWrite.ret11: +fat_Write.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 + jmp fat_Write.ret0 ;---------------------------------------------------------------- ; fat_Write - FAT16/32 implementation of writing to file @@ -2051,7 +1894,7 @@ fat_Write: pop edi push eax call fat_unlock - jmp fs_HdWrite.ret0 + jmp .ret0 .found: ; FAT does not support files larger than 4GB cmp dword [ebx+8], 0 @@ -2060,7 +1903,7 @@ fat_Write: pop edi push ERROR_END_OF_FILE call fat_unlock - jmp fs_HdWrite.ret0 + jmp .ret0 @@: mov ecx, [ebx+12] mov edx, [ebx+16] @@ -2361,39 +2204,6 @@ hd_extend_file: stc ret -;---------------------------------------------------------------- -; -; 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], 16 - jz @f - cmp [fs_type], 32 - jz @f - cmp [fs_type], 1 - jz ntfs_HdSetFileEnd - cmp [fs_type], 2 - jz ext2_HdSetFileEnd - movi eax, ERROR_UNKNOWN_FS - 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 @@ -2634,25 +2444,6 @@ fat_SetFileEnd: movi eax, ERROR_FAT_TABLE 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 @@ -2687,25 +2478,6 @@ fat_GetFileInfo: 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 @@ -2741,36 +2513,6 @@ fat_SetFileInfo: 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 - movi eax, ERROR_UNKNOWN_FS - 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 diff --git a/kernel/trunk/fs/fs.inc b/kernel/trunk/fs/fs.inc index 0a88cb7fe8..fced955dcd 100644 --- a/kernel/trunk/fs/fs.inc +++ b/kernel/trunk/fs/fs.inc @@ -318,86 +318,6 @@ endg fs_noflpdisk: ;***************************************************************** - mov eax, [edi+1] - cmp eax, 'HD0 ' - je fs_yesharddisk_IDE0 - cmp eax, 'HD1 ' - je fs_yesharddisk_IDE1 - cmp eax, 'HD2 ' - je fs_yesharddisk_IDE2 - cmp eax, 'HD3 ' - je fs_yesharddisk_IDE3 - jmp old_path_harddisk -fs_yesharddisk_IDE0: - call reserve_hd1 - mov [hdbase], 0x1f0 - mov [hdid], 0x0 - mov [hdpos], 1 - jmp fs_yesharddisk_partition -fs_yesharddisk_IDE1: - call reserve_hd1 - mov [hdbase], 0x1f0 - mov [hdid], 0x10 - mov [hdpos], 2 - jmp fs_yesharddisk_partition -fs_yesharddisk_IDE2: - call reserve_hd1 - mov [hdbase], 0x170 - mov [hdid], 0x0 - mov [hdpos], 3 - jmp fs_yesharddisk_partition -fs_yesharddisk_IDE3: - call reserve_hd1 - mov [hdbase], 0x170 - mov [hdid], 0x10 - mov [hdpos], 4 -fs_yesharddisk_partition: - call reserve_hd_channel -; call choice_necessity_partition -; jmp fs_yesharddisk_all - jmp fs_for_new_semantic - -choice_necessity_partition: - mov eax, [edi+1+12] - call StringToNumber - mov [fat32part], eax -choice_necessity_partition_1: - mov ecx, [hdpos] - xor eax, eax - mov [hd_entries], eax; entries in hd cache - mov edx, DRIVE_DATA+2 - cmp ecx, 0x80 - jb search_partition_array - mov ecx, 4 - search_partition_array: - mov bl, [edx] - movzx ebx, bl - add eax, ebx - inc edx - loop search_partition_array - mov ecx, [hdpos] - mov edx, BiosDiskPartitions - sub ecx, 0x80 - jb .s - je .f - @@: - mov ebx, [edx] - add edx, 4 - add eax, ebx - loop @b - jmp .f - .s: - sub eax, ebx - .f: - add eax, [known_part]; add eax,[fat32part] - dec eax - xor edx, edx - imul eax, 100 - add eax, DRIVE_DATA+0xa - mov [transfer_adress], eax - call partition_data_transfer_1 - ret - old_path_harddisk: mov eax, [edi+1] cmp eax, 'HD ' @@ -416,27 +336,7 @@ choice_necessity_partition_1: fs_no_LBA_read: - cmp byte [edi+1+11], 0; directory read - je fs_give_dir1 - call reserve_hd1 - fs_for_new_semantic: - call choice_necessity_partition - - fs_yesharddisk_all: - mov eax, 1 - mov ebx, [esp+24+24] - cmp [hdpos], 0 ; is hd base set? - jz hd_err_return - cmp [fat32part], 0 ; is partition set? - jnz @f hd_err_return: - call free_hd_channel - and [hd1_status], 0 - jmp file_system_return -@@: - - call free_hd_channel - and [hd1_status], 0 fs_noharddisk: ; \begin{diamond}[18.03.2006] @@ -542,7 +442,10 @@ LBA_read: lbarl1: - call reserve_hd1 + pushad + mov ecx, ide_mutex + call mutex_lock + popad push eax push ecx @@ -633,6 +536,10 @@ LBA_read: mov [hd_error], 0 mov [hd1_status], 0 add esp, 2*4 + pushad + mov ecx, ide_mutex + call mutex_unlock + popad ret diff --git a/kernel/trunk/fs/fs_lfn.inc b/kernel/trunk/fs/fs_lfn.inc index ea90b0e3e2..155371e8a6 100644 --- a/kernel/trunk/fs/fs_lfn.inc +++ b/kernel/trunk/fs/fs_lfn.inc @@ -42,18 +42,6 @@ rootdirs: db 10,'floppydisk' dd fs_OnFloppy dd fs_NextFloppy - db 3,'hd0' - dd fs_OnHd0 - dd fs_NextHd0 - db 3,'hd1' - dd fs_OnHd1 - dd fs_NextHd1 - db 3,'hd2' - dd fs_OnHd2 - dd fs_NextHd2 - db 3,'hd3' - dd fs_OnHd3 - dd fs_NextHd3 ;********************************************** db 3,'cd0' dd fs_OnCd0 @@ -76,14 +64,6 @@ virtual_root_query: db 'rd',0 dd fs_HasFloppy db 'fd',0 - dd fs_HasHd0 - db 'hd0',0 - dd fs_HasHd1 - db 'hd1',0 - dd fs_HasHd2 - db 'hd2',0 - dd fs_HasHd3 - db 'hd3',0 ;********************************************** dd fs_HasCd0 db 'cd0',0 @@ -97,7 +77,6 @@ virtual_root_query: dd 0 fs_additional_handlers: - dd biosdisk_handler, biosdisk_enum_root dd dyndisk_handler, dyndisk_enum_root ; add new handlers here dd 0 @@ -523,84 +502,6 @@ fs_FloppyServices: dd fs_FloppyCreateFolder fs_NumFloppyServices = ($ - fs_FloppyServices)/4 -fs_OnHd0: - call reserve_hd1 - mov eax, [hd_address_table] - mov [hdbase], eax ;0x1F0 - mov [hdid], 0 - push 1 - jmp fs_OnHd -fs_OnHd1: - call reserve_hd1 - mov eax, [hd_address_table] - mov [hdbase], eax ;0x1F0 - mov [hdid], 0x10 - push 2 - jmp fs_OnHd -fs_OnHd2: - call reserve_hd1 - mov eax, [hd_address_table+16] - mov [hdbase], eax ;0x170 - mov [hdid], 0 - push 3 - jmp fs_OnHd -fs_OnHd3: - call reserve_hd1 - mov eax, [hd_address_table+16] - mov [hdbase], eax ;0x170 - mov [hdid], 0x10 - push 4 -fs_OnHd: - call reserve_hd_channel - pop eax - mov [hdpos], eax - cmp ecx, 0x100 - jae fs_OnHdAndBd.nf - cmp cl, [DRIVE_DATA+1+eax] -fs_OnHdAndBd: - jbe @f -.nf: - call free_hd_channel - and [hd1_status], 0 - mov dword [image_of_eax], 5 ; not found - ret -@@: - mov [known_part], ecx ; mov [fat32part], ecx - push ebx esi - call choice_necessity_partition_1 - pop esi ebx - mov ecx, [ebx+12] - mov edx, [ebx+16] - ; add edx, std_application_base_address - mov eax, [ebx] - cmp eax, fs_NumHdServices - jae .not_impl - add ebx, 4 - call dword [fs_HdServices + eax*4] - call free_hd_channel - and [hd1_status], 0 - mov [image_of_eax], eax - mov [image_of_ebx], ebx - ret -.not_impl: - call free_hd_channel - and [hd1_status], 0 - mov dword [image_of_eax], 2 ; not implemented - ret - -fs_HdServices: - dd fs_HdRead - dd fs_HdReadFolder - dd fs_HdRewrite - dd fs_HdWrite - dd fs_HdSetFileEnd - dd fs_HdGetFileInfo - dd fs_HdSetFileInfo - dd 0 - dd fs_HdDelete - dd fs_HdCreateFolder -fs_NumHdServices = ($ - fs_HdServices)/4 - ;******************************************************* fs_OnCd0: call reserve_cd @@ -691,22 +592,6 @@ fs_HasFloppy: cmp byte [DRIVE_DATA], 0 setnz al ret -fs_HasHd0: - test byte [DRIVE_DATA+1], 01000000b - setnz al - ret -fs_HasHd1: - test byte [DRIVE_DATA+1], 00010000b - setnz al - ret -fs_HasHd2: - test byte [DRIVE_DATA+1], 00000100b - setnz al - ret -fs_HasHd3: - test byte [DRIVE_DATA+1], 00000001b - setnz al - ret ;******************************************************* fs_HasCd0: @@ -762,27 +647,6 @@ fs_NextFloppy: stc ret -; on hdx, we have partitions from 1 to [0x40002+x] -fs_NextHd0: - push 0 - jmp fs_NextHd -fs_NextHd1: - push 1 - jmp fs_NextHd -fs_NextHd2: - push 2 - jmp fs_NextHd -fs_NextHd3: - push 3 -fs_NextHd: - pop ecx - movzx ecx, byte [DRIVE_DATA+2+ecx] - cmp eax, ecx - jae fs_NextFloppy.no2 - inc eax - clc - ret - ;******************************************************* fs_NextCd: ; we always have /cdX/1 @@ -795,147 +659,6 @@ fs_NextCd: ret ;******************************************************* -; Additional FS handlers. -; This handler gets the control each time when fn 70 is called -; with unknown item of root subdirectory. -; in: esi -> name -; ebp = 0 or rest of name relative to esi -; out: if the handler processes path, he must not return in file_system_lfn, -; but instead pop return address and return directly to the caller -; otherwise simply return - -; here we test for /bd/... - BIOS disks -biosdisk_handler: - cmp [NumBiosDisks], 0 - jz .ret - mov al, [esi] - or al, 20h - cmp al, 'b' - jnz .ret - mov al, [esi+1] - or al, 20h - cmp al, 'd' - jnz .ret - push esi - inc esi - inc esi - cmp byte [esi], '0' - jb .ret2 - cmp byte [esi], '9' - ja .ret2 - xor edx, edx -@@: - lodsb - test al, al - jz .ok - cmp al, '/' - jz .ok - sub al, '0' - cmp al, 9 - ja .ret2 - lea edx, [edx*5] - lea edx, [edx*2+eax] - jmp @b -.ret2: - pop esi -.ret: - ret -.ok: - cmp al, '/' - jz @f - dec esi -@@: - add dl, 80h - xor ecx, ecx -@@: - cmp dl, [BiosDisksData+ecx*4] - jz .ok2 - inc ecx - cmp ecx, [NumBiosDisks] - jb @b - jmp .ret2 -.ok2: - add esp, 8 - test al, al - jnz @f - mov esi, fs_BdNext - jmp file_system_lfn.maindir_noesi -@@: - push ecx - push ecx - push biosdisk_cleanup - push fs_OnBd - mov edi, esp - jmp file_system_lfn.found2 - -fs_BdNext: - cmp eax, [BiosDiskPartitions+ecx*4] - inc eax - cmc -biosdisk_cleanup: - ret - -fs_OnBd: - pop edx edx edx edx -; edx = disk number, ecx = partition number -; esi+ebp = name - call reserve_hd1 - add edx, 0x80 - mov [hdpos], edx - cmp ecx, [BiosDiskPartitions+(edx-0x80)*4] - jmp fs_OnHdAndBd - -; This handler is called when virtual root is enumerated -; and must return all items which can be handled by this. -; It is called several times, first time with eax=0 -; in: eax = 0 for first call, previously returned value for subsequent calls -; out: eax = 0 => no more items -; eax != 0 => buffer pointed to by edi contains name of item - -; here we enumerate existing BIOS disks /bd -biosdisk_enum_root: - cmp eax, [NumBiosDisks] - jae .end - push eax - movzx eax, byte [BiosDisksData+eax*4] - sub al, 80h - push eax - mov al, 'b' - stosb - mov al, 'd' - stosb - pop eax - cmp al, 10 - jae .big - add al, '0' - stosb - mov byte [edi], 0 - pop eax - inc eax - ret -.end: - xor eax, eax - ret -.big: - push ecx edx - push -'0' - mov ecx, 10 -@@: - xor edx, edx - div ecx - push edx - test eax, eax - jnz @b - xchg eax, edx -@@: - pop eax - add al, '0' - stosb - jnz @b - pop edx ecx - pop eax - inc eax - ret ;----------------------------------------------------------------------------- process_replace_file_name: ; in diff --git a/kernel/trunk/fs/iso9660.inc b/kernel/trunk/fs/iso9660.inc index eed566e280..ff3bd6f8bd 100644 --- a/kernel/trunk/fs/iso9660.inc +++ b/kernel/trunk/fs/iso9660.inc @@ -42,26 +42,18 @@ reserve_cd_channel: cmp [ChannelNumber], 1 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: + pushad + mov ecx, ide_channel1_mutex + call mutex_lock mov [IDE_Channel_1], 1 - sti + popad ret -.reserve_ok_2: +.IDE_Channel_2: + pushad + mov ecx, ide_channel2_mutex + call mutex_lock mov [IDE_Channel_2], 1 - sti + popad ret free_cd_channel: @@ -69,11 +61,17 @@ free_cd_channel: jne .IDE_Channel_2 .IDE_Channel_1: mov [IDE_Channel_1], 0 - sti + pushad + mov ecx, ide_channel1_mutex + call mutex_unlock + popad ret .IDE_Channel_2: mov [IDE_Channel_2], 0 - sti + pushad + mov ecx, ide_channel2_mutex + call mutex_unlock + popad ret uglobal diff --git a/kernel/trunk/fs/ntfs.inc b/kernel/trunk/fs/ntfs.inc index 6c0f3f726b..346bf6cf63 100644 --- a/kernel/trunk/fs/ntfs.inc +++ b/kernel/trunk/fs/ntfs.inc @@ -1,12 +1,70 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; -;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;; +;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;; ;; Distributed under terms of the GNU General Public License ;; ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; $Revision$ +struct NTFS PARTITION +Lock MUTEX ? ; currently operations with one partition + ; can not be executed in parallel since the + ; legacy code is not ready; this mutex guards + ; all operations +sectors_per_cluster dd ? +mft_cluster dd ? +mftmirr_cluster dd ? +frs_size dd ? ; FRS size in bytes +iab_size dd ? ; IndexAllocationBuffer size in bytes +frs_buffer dd ? +iab_buffer dd ? +mft_retrieval dd ? +mft_retrieval_size dd ? +mft_retrieval_alloc dd ? +mft_retrieval_end dd ? +cur_index_size dd ? +cur_index_buf dd ? + +ntfs_cur_attr dd ? +ntfs_cur_iRecord dd ? +ntfs_cur_offs dd ? ; in sectors +ntfs_cur_size dd ? ; in sectors +ntfs_cur_buf dd ? +ntfs_cur_read dd ? ; [output] +ntfs_bCanContinue db ? + rb 3 + +cur_subnode_size dd ? +ntfs_attr_iRecord dd ? +ntfs_attr_iBaseRecord dd ? +ntfs_attr_offs dd ? +ntfs_attr_list dd ? +ntfs_attr_size dq ? +ntfs_cur_tail dd ? + +ntfs_attrlist_buf rb 0x400 +ntfs_attrlist_mft_buf rb 0x400 +ntfs_bitmap_buf rb 0x400 +ends + +iglobal +align 4 +ntfs_user_functions: + dd ntfs_free + dd (ntfs_user_functions_end - ntfs_user_functions - 4) / 4 + dd ntfs_Read + dd ntfs_ReadFolder + dd ntfs_Rewrite + dd ntfs_Write + dd ntfs_SetFileEnd + dd ntfs_GetFileInfo + dd ntfs_SetFileInfo + dd 0 + dd ntfs_Delete + dd ntfs_CreateFolder +ntfs_user_functions_end: +endg ntfs_test_bootsec: ; in: ebx->buffer, edx=size of partition @@ -93,25 +151,66 @@ ntfs_test_bootsec: stc ret -ntfs_setup: ; CODE XREF: part_set.inc +proc ntfs_create_partition + mov edx, dword [ebp+PARTITION.Length] + cmp dword [esp+4], 0 + jz .boot_read_ok + add ebx, 512 + lea eax, [edx-1] + call fs_read32_sys + test eax, eax + jnz @f + call ntfs_test_bootsec + jnc .ntfs_setup +@@: + mov eax, edx + shr eax, 1 + call fs_read32_sys + test eax, eax + jnz .nope ; no chance... +.boot_read_ok: + call ntfs_test_bootsec + jnc .ntfs_setup +.nope: + xor eax, eax + jmp .exit + +.ntfs_setup: ; By given bootsector, initialize some NTFS variables -; call ntfs_test_bootsec ; checking boot sector was already -; jc problem_fat_dec_count + movi eax, sizeof.NTFS + call malloc + test eax, eax + jz .exit + mov ecx, dword [ebp+PARTITION.FirstSector] + mov dword [eax+NTFS.FirstSector], ecx + mov ecx, dword [ebp+PARTITION.FirstSector+4] + mov dword [eax+NTFS.FirstSector+4], ecx + mov ecx, dword [ebp+PARTITION.Length] + mov dword [eax+NTFS.Length], ecx + mov ecx, dword [ebp+PARTITION.Length+4] + mov dword [eax+NTFS.Length+4], ecx + mov ecx, [ebp+PARTITION.Disk] + mov [eax+NTFS.Disk], ecx + mov [eax+NTFS.FSUserFunctions], ntfs_user_functions + push ebx ebp esi + mov ebp, eax + + lea ecx, [ebp+NTFS.Lock] + call mutex_init + movzx eax, byte [ebx+13] - mov [ntfs_data.sectors_per_cluster], eax + mov [ebp+NTFS.sectors_per_cluster], eax mov eax, [ebx+0x28] - add eax, [PARTITION_START] - dec eax - mov [PARTITION_END], eax - mov [fs_type], 1 + mov dword [ebp+NTFS.Length], eax + and dword [ebp+NTFS.Length+4], 0 mov eax, [ebx+0x30] - mov [ntfs_data.mft_cluster], eax + mov [ebp+NTFS.mft_cluster], eax mov eax, [ebx+0x38] - mov [ntfs_data.mftmirr_cluster], eax + mov [ebp+NTFS.mftmirr_cluster], eax movsx eax, byte [ebx+0x40] test eax, eax js .1 - mul [ntfs_data.sectors_per_cluster] + mul [ebp+NTFS.sectors_per_cluster] shl eax, 9 jmp .2 .1: @@ -120,11 +219,11 @@ ntfs_setup: ; CODE XREF: part_set.inc mov eax, 1 shl eax, cl .2: - mov [ntfs_data.frs_size], eax + mov [ebp+NTFS.frs_size], eax movsx eax, byte [ebx+0x44] test eax, eax js .3 - mul [ntfs_data.sectors_per_cluster] + mul [ebp+NTFS.sectors_per_cluster] shl eax, 9 jmp .4 .3: @@ -133,32 +232,31 @@ ntfs_setup: ; CODE XREF: part_set.inc mov eax, 1 shl eax, cl .4: - mov [ntfs_data.iab_size], eax + mov [ebp+NTFS.iab_size], eax ; allocate space for buffers - add eax, [ntfs_data.frs_size] + add eax, [ebp+NTFS.frs_size] push eax call kernel_alloc test eax, eax - jz problem_fat_dec_count - mov [ntfs_data.frs_buffer], eax - add eax, [ntfs_data.frs_size] - mov [ntfs_data.iab_buffer], eax + jz .fail_free + mov [ebp+NTFS.frs_buffer], eax + add eax, [ebp+NTFS.frs_size] + mov [ebp+NTFS.iab_buffer], eax ; read $MFT disposition - mov eax, [ntfs_data.mft_cluster] - mul [ntfs_data.sectors_per_cluster] + mov eax, [ebp+NTFS.mft_cluster] + mul [ebp+NTFS.sectors_per_cluster] call ntfs_read_frs_sector - cmp [hd_error], 0 + test eax, eax jnz .usemirr cmp dword [ebx], 'FILE' jnz .usemirr call ntfs_restore_usa_frs jnc .mftok .usemirr: - and [hd_error], 0 - mov eax, [ntfs_data.mftmirr_cluster] - mul [ntfs_data.sectors_per_cluster] + mov eax, [ebp+NTFS.mftmirr_cluster] + mul [ebp+NTFS.sectors_per_cluster] call ntfs_read_frs_sector - cmp [hd_error], 0 + test eax, eax jnz @f cmp dword [ebx], 'FILE' jnz @f @@ -167,11 +265,22 @@ ntfs_setup: ; CODE XREF: part_set.inc @@: ; $MFT and $MFTMirr invalid! .fail_free_frs: - push [ntfs_data.frs_buffer] + push [ebp+NTFS.frs_buffer] call kernel_free - jmp problem_fat_dec_count +.fail_free: + mov eax, ebp + call free + xor eax, eax +.pop_exit: + pop esi ebp ebx +.exit: + cmp dword [esp+4], 0 + jz @f + sub ebx, 512 +@@: + ret .fail_free_mft: - push [ntfs_data.mft_retrieval] + push [ebp+NTFS.mft_retrieval] call kernel_free jmp .fail_free_frs .mftok: @@ -183,9 +292,9 @@ ntfs_setup: ; CODE XREF: part_set.inc pop ebx test eax, eax jz .fail_free_frs - mov [ntfs_data.mft_retrieval], eax - and [ntfs_data.mft_retrieval_size], 0 - mov [ntfs_data.mft_retrieval_alloc], 0x1000/8 + mov [ebp+NTFS.mft_retrieval], eax + and [ebp+NTFS.mft_retrieval_size], 0 + mov [ebp+NTFS.mft_retrieval_alloc], 0x1000/8 ; $MFT base record must contain unnamed non-resident $DATA attribute movzx eax, word [ebx+14h] add eax, ebx @@ -204,7 +313,7 @@ ntfs_setup: ; CODE XREF: part_set.inc jz .fail_free_mft ; load first portion of $DATA attribute retrieval information mov edx, [eax+0x18] - mov [ntfs_data.mft_retrieval_end], edx + mov [ebp+NTFS.mft_retrieval_end], edx mov esi, eax movzx eax, word [eax+0x20] add esi, eax @@ -217,32 +326,31 @@ ntfs_setup: ; CODE XREF: part_set.inc mov [eax], edx mov edx, [esp+8] ; block addr (relative) mov [eax+4], edx - inc [ntfs_data.mft_retrieval_size] + inc [ebp+NTFS.mft_retrieval_size] jmp .scanmcb .scanmcbend: add esp, 10h ; there may be other portions of $DATA attribute in auxiliary records; ; if they will be needed, they will be loaded later - mov [ntfs_data.cur_index_size], 0x1000/0x200 + mov [ebp+NTFS.cur_index_size], 0x1000/0x200 push 0x1000 call kernel_alloc test eax, eax jz .fail_free_mft - mov [ntfs_data.cur_index_buf], eax + mov [ebp+NTFS.cur_index_buf], eax - popad - call free_hd_channel - and [hd1_status], 0 - ret + mov eax, ebp + jmp .pop_exit +endp .get_mft_retrieval_ptr: pushad - mov eax, [ntfs_data.mft_retrieval_size] - cmp eax, [ntfs_data.mft_retrieval_alloc] + mov eax, [ebp+NTFS.mft_retrieval_size] + cmp eax, [ebp+NTFS.mft_retrieval_alloc] jnz .ok add eax, 0x1000/8 - mov [ntfs_data.mft_retrieval_alloc], eax + mov [ebp+NTFS.mft_retrieval_alloc], eax shl eax, 3 push eax call kernel_alloc @@ -252,83 +360,88 @@ ntfs_setup: ; CODE XREF: part_set.inc add esp, 14h jmp .fail_free_mft @@: - mov esi, [ntfs_data.mft_retrieval] + mov esi, [ebp+NTFS.mft_retrieval] mov edi, eax - mov ecx, [ntfs_data.mft_retrieval_size] + mov ecx, [ebp+NTFS.mft_retrieval_size] add ecx, ecx rep movsd - push [ntfs_data.mft_retrieval] - mov [ntfs_data.mft_retrieval], eax + push [ebp+NTFS.mft_retrieval] + mov [ebp+NTFS.mft_retrieval], eax call kernel_free - mov eax, [ntfs_data.mft_retrieval_size] + mov eax, [ebp+NTFS.mft_retrieval_size] .ok: shl eax, 3 - add eax, [ntfs_data.mft_retrieval] + add eax, [ebp+NTFS.mft_retrieval] mov [esp+28], eax popad ret -ntfs_read_frs_sector: - push eax ecx - add eax, [PARTITION_START] - mov ecx, [ntfs_data.frs_size] - shr ecx, 9 - mov ebx, [ntfs_data.frs_buffer] +proc ntfs_free push ebx + xchg ebx, eax + stdcall kernel_free, [ebx+NTFS.frs_buffer] + stdcall kernel_free, [ebx+NTFS.mft_retrieval] + stdcall kernel_free, [ebx+NTFS.cur_index_buf] + xchg ebx, eax + call free + pop ebx + ret +endp + +proc ntfs_lock + lea ecx, [ebp+NTFS.Lock] + jmp mutex_lock +endp + +proc ntfs_unlock + lea ecx, [ebp+NTFS.Lock] + jmp mutex_unlock +endp + +ntfs_read_frs_sector: + push ecx + mov ebx, [ebp+NTFS.frs_buffer] + push ebx + mov ecx, [ebp+NTFS.frs_size] + shr ecx, 9 + push ecx + mov ecx, eax @@: - call hd_read - cmp [hd_error], 0 + mov eax, ecx + call fs_read32_sys + test eax, eax jnz .fail add ebx, 0x200 - inc eax - loop @b + inc ecx + dec dword [esp] + jnz @b + pop eax .fail: pop ebx - pop ecx eax + pop ecx ret -uglobal -align 4 -ntfs_cur_attr dd ? -ntfs_cur_iRecord dd ? -ntfs_cur_offs dd ? ; in sectors -ntfs_cur_size dd ? ; in sectors -ntfs_cur_buf dd ? -ntfs_cur_read dd ? ; [output] -ntfs_bCanContinue db ? - rb 3 - -ntfs_attrlist_buf rb 0x400 -ntfs_attrlist_mft_buf rb 0x400 -ntfs_bitmap_buf rb 0x400 - -ntfs_attr_iRecord dd ? -ntfs_attr_iBaseRecord dd ? -ntfs_attr_offs dd ? -ntfs_attr_list dd ? -ntfs_attr_size dq ? -ntfs_cur_tail dd ? -endg - ntfs_read_attr: -; in: global variables -; out: [ntfs_cur_read] +; in: variables in ebp+NTFS.* +; out: [ebp+NTFS.ntfs_cur_read] +; out: CF=1 => notfound, in this case eax=0 => disk ok, otherwise eax=disk error code + xor eax, eax pushad - and [ntfs_cur_read], 0 - cmp [ntfs_cur_iRecord], 0 + and [ebp+NTFS.ntfs_cur_read], 0 + cmp [ebp+NTFS.ntfs_cur_iRecord], 0 jnz .nomft - cmp [ntfs_cur_attr], 0x80 + cmp [ebp+NTFS.ntfs_cur_attr], 0x80 jnz .nomft - mov eax, [ntfs_data.mft_retrieval_end] + mov eax, [ebp+NTFS.mft_retrieval_end] inc eax - mul [ntfs_data.sectors_per_cluster] - cmp eax, [ntfs_cur_offs] + mul [ebp+NTFS.sectors_per_cluster] + cmp eax, [ebp+NTFS.ntfs_cur_offs] jbe .nomft ; precalculated part of $Mft $DATA - mov esi, [ntfs_data.mft_retrieval] - mov eax, [ntfs_cur_offs] + mov esi, [ebp+NTFS.mft_retrieval] + mov eax, [ebp+NTFS.ntfs_cur_offs] xor edx, edx - div [ntfs_data.sectors_per_cluster] + div [ebp+NTFS.sectors_per_cluster] ; eax = VCN, edx = offset in sectors from beginning of cluster xor ecx, ecx ; ecx will contain LCN .mftscan: @@ -337,9 +450,9 @@ ntfs_read_attr: jb @f add esi, 8 push eax - mov eax, [ntfs_data.mft_retrieval_end] + mov eax, [ebp+NTFS.mft_retrieval_end] shl eax, 3 - add eax, [ntfs_data.mft_retrieval] + add eax, [ebp+NTFS.mft_retrieval] cmp eax, esi pop eax jnz .mftscan @@ -350,42 +463,43 @@ ntfs_read_attr: add ecx, [esi] push eax push edx - mov eax, [ntfs_data.sectors_per_cluster] + mov eax, [ebp+NTFS.sectors_per_cluster] mul ecx ; eax = sector on partition - add eax, [PARTITION_START] pop edx add eax, edx - mov ebx, [ntfs_cur_buf] + mov ebx, [ebp+NTFS.ntfs_cur_buf] pop ecx neg ecx - imul ecx, [ntfs_data.sectors_per_cluster] + imul ecx, [ebp+NTFS.sectors_per_cluster] sub ecx, edx - cmp ecx, [ntfs_cur_size] + cmp ecx, [ebp+NTFS.ntfs_cur_size] jb @f - mov ecx, [ntfs_cur_size] + mov ecx, [ebp+NTFS.ntfs_cur_size] @@: ; ecx = number of sequential sectors to read - call hd_read - cmp [hd_error], 0 + push eax + call fs_read32_sys + pop edx + test eax, eax jnz .errread - add [ntfs_cur_read], 0x200 - dec [ntfs_cur_size] - inc [ntfs_cur_offs] + add [ebp+NTFS.ntfs_cur_read], 0x200 + dec [ebp+NTFS.ntfs_cur_size] + inc [ebp+NTFS.ntfs_cur_offs] add ebx, 0x200 - mov [ntfs_cur_buf], ebx - inc eax + mov [ebp+NTFS.ntfs_cur_buf], ebx + lea eax, [edx+1] loop @b pop ecx xor eax, eax xor edx, edx - cmp [ntfs_cur_size], eax + cmp [ebp+NTFS.ntfs_cur_size], eax jz @f add esi, 8 push eax - mov eax, [ntfs_data.mft_retrieval_end] + mov eax, [ebp+NTFS.mft_retrieval_end] shl eax, 3 - add eax, [ntfs_data.mft_retrieval] + add eax, [ebp+NTFS.mft_retrieval] cmp eax, esi pop eax jz .nomft @@ -396,23 +510,23 @@ ntfs_read_attr: .errread: pop ecx .errret: + mov [esp+28], eax stc popad ret .nomft: ; 1. Read file record. ; N.B. This will do recursive call of read_attr for $MFT::$Data. - mov eax, [ntfs_cur_iRecord] - mov [ntfs_attr_iRecord], eax - and [ntfs_attr_list], 0 - or dword [ntfs_attr_size], -1 - or dword [ntfs_attr_size+4], -1 - or [ntfs_attr_iBaseRecord], -1 + mov eax, [ebp+NTFS.ntfs_cur_iRecord] + mov [ebp+NTFS.ntfs_attr_iRecord], eax + and [ebp+NTFS.ntfs_attr_list], 0 + or dword [ebp+NTFS.ntfs_attr_size], -1 + or dword [ebp+NTFS.ntfs_attr_size+4], -1 + or [ebp+NTFS.ntfs_attr_iBaseRecord], -1 call ntfs_read_file_record - test eax, eax - jz .errret + jc .errret ; 2. Find required attribute. - mov eax, [ntfs_data.frs_buffer] + mov eax, [ebp+NTFS.frs_buffer] ; a) For auxiliary records, read base record ; N.B. If base record is present, ; base iRecord may be 0 (for $Mft), but SequenceNumber is nonzero @@ -422,27 +536,26 @@ ntfs_read_attr: ; test eax, eax ; jz @f .beginfindattr: - mov [ntfs_attr_iRecord], eax + mov [ebp+NTFS.ntfs_attr_iRecord], eax call ntfs_read_file_record - test eax, eax - jz .errret + jc .errret @@: ; b) Scan for required attribute and for $ATTR_LIST - mov eax, [ntfs_data.frs_buffer] + mov eax, [ebp+NTFS.frs_buffer] movzx ecx, word [eax+14h] add eax, ecx - mov ecx, [ntfs_cur_attr] - and [ntfs_attr_offs], 0 + mov ecx, [ebp+NTFS.ntfs_cur_attr] + and [ebp+NTFS.ntfs_attr_offs], 0 .scanattr: cmp dword [eax], -1 jz .scandone cmp dword [eax], ecx jz .okattr - cmp [ntfs_attr_iBaseRecord], -1 + cmp [ebp+NTFS.ntfs_attr_iBaseRecord], -1 jnz .scancont cmp dword [eax], 0x20 ; $ATTR_LIST jnz .scancont - mov [ntfs_attr_list], eax + mov [ebp+NTFS.ntfs_attr_list], eax jmp .scancont .okattr: ; ignore named $DATA attributes (aka NTFS streams) @@ -451,92 +564,93 @@ ntfs_read_attr: cmp byte [eax+9], 0 jnz .scancont @@: - mov [ntfs_attr_offs], eax + mov [ebp+NTFS.ntfs_attr_offs], eax .scancont: add eax, [eax+4] jmp .scanattr .continue: pushad - and [ntfs_cur_read], 0 + and [ebp+NTFS.ntfs_cur_read], 0 .scandone: ; c) Check for required offset and length - mov ecx, [ntfs_attr_offs] + mov ecx, [ebp+NTFS.ntfs_attr_offs] jecxz .noattr - push [ntfs_cur_size] - push [ntfs_cur_read] + push [ebp+NTFS.ntfs_cur_size] + push [ebp+NTFS.ntfs_cur_read] call .doreadattr pop edx - pop eax + pop ecx jc @f - cmp [ntfs_bCanContinue], 0 + cmp [ebp+NTFS.ntfs_bCanContinue], 0 jz @f - sub edx, [ntfs_cur_read] + sub edx, [ebp+NTFS.ntfs_cur_read] neg edx shr edx, 9 - sub eax, edx - mov [ntfs_cur_size], eax + sub ecx, edx + mov [ebp+NTFS.ntfs_cur_size], ecx jnz .not_in_cur @@: popad ret .noattr: .not_in_cur: - cmp [ntfs_cur_attr], 0x20 + cmp [ebp+NTFS.ntfs_cur_attr], 0x20 jz @f - mov ecx, [ntfs_attr_list] + mov ecx, [ebp+NTFS.ntfs_attr_list] test ecx, ecx jnz .lookattr .ret_is_attr: - cmp [ntfs_attr_offs], 1 ; CF set <=> ntfs_attr_offs == 0 + and dword [esp+28], 0 + cmp [ebp+NTFS.ntfs_attr_offs], 1 ; CF set <=> ntfs_attr_offs == 0 popad ret .lookattr: ; required attribute or required offset was not found in base record; ; it may be present in auxiliary records; ; scan $ATTR_LIST - mov eax, [ntfs_attr_iBaseRecord] + mov eax, [ebp+NTFS.ntfs_attr_iBaseRecord] cmp eax, -1 jz @f call ntfs_read_file_record - test eax, eax - jz .errret - or [ntfs_attr_iBaseRecord], -1 + jc .errret + or [ebp+NTFS.ntfs_attr_iBaseRecord], -1 @@: - push [ntfs_cur_offs] - push [ntfs_cur_size] - push [ntfs_cur_read] - push [ntfs_cur_buf] - push dword [ntfs_attr_size] - push dword [ntfs_attr_size+4] - or dword [ntfs_attr_size], -1 - or dword [ntfs_attr_size+4], -1 - and [ntfs_cur_offs], 0 - mov [ntfs_cur_size], 2 - and [ntfs_cur_read], 0 - mov eax, ntfs_attrlist_buf - cmp [ntfs_cur_iRecord], 0 + push [ebp+NTFS.ntfs_cur_offs] + push [ebp+NTFS.ntfs_cur_size] + push [ebp+NTFS.ntfs_cur_read] + push [ebp+NTFS.ntfs_cur_buf] + push dword [ebp+NTFS.ntfs_attr_size] + push dword [ebp+NTFS.ntfs_attr_size+4] + or dword [ebp+NTFS.ntfs_attr_size], -1 + or dword [ebp+NTFS.ntfs_attr_size+4], -1 + and [ebp+NTFS.ntfs_cur_offs], 0 + mov [ebp+NTFS.ntfs_cur_size], 2 + and [ebp+NTFS.ntfs_cur_read], 0 + lea eax, [ebp+NTFS.ntfs_attrlist_buf] + cmp [ebp+NTFS.ntfs_cur_iRecord], 0 jnz @f - mov eax, ntfs_attrlist_mft_buf + lea eax, [ebp+NTFS.ntfs_attrlist_mft_buf] @@: - mov [ntfs_cur_buf], eax + mov [ebp+NTFS.ntfs_cur_buf], eax push eax call .doreadattr pop esi mov edx, 1 - pop dword [ntfs_attr_size+4] - pop dword [ntfs_attr_size] - mov ebp, [ntfs_cur_read] - pop [ntfs_cur_buf] - pop [ntfs_cur_read] - pop [ntfs_cur_size] - pop [ntfs_cur_offs] + pop dword [ebp+NTFS.ntfs_attr_size+4] + pop dword [ebp+NTFS.ntfs_attr_size] + mov ecx, [ebp+NTFS.ntfs_cur_read] + pop [ebp+NTFS.ntfs_cur_buf] + pop [ebp+NTFS.ntfs_cur_read] + pop [ebp+NTFS.ntfs_cur_size] + pop [ebp+NTFS.ntfs_cur_offs] jc .errret or edi, -1 - lea ebp, [ebp+esi-1Ah] + lea ecx, [ecx+esi-1Ah] .scanliststart: - mov eax, [ntfs_cur_attr] + push ecx + mov eax, [ebp+NTFS.ntfs_cur_attr] .scanlist: - cmp esi, ebp + cmp esi, [esp] jae .scanlistdone cmp eax, [esi] jz @f @@ -555,26 +669,28 @@ ntfs_read_attr: mov eax, [esi+8] test eax, eax jnz .testf - mov eax, dword [ntfs_attr_size] - and eax, dword [ntfs_attr_size+4] + mov eax, dword [ebp+NTFS.ntfs_attr_size] + and eax, dword [ebp+NTFS.ntfs_attr_size+4] cmp eax, -1 jnz .testfz ; if attribute is in auxiliary records, its size is defined only in first mov eax, [esi+10h] call ntfs_read_file_record - test eax, eax - jnz @f + jnc @f .errret_pop: - pop eax + pop ecx ecx jmp .errret +.errret2_pop: + xor eax, eax + jmp .errret_pop @@: - mov eax, [ntfs_data.frs_buffer] + mov eax, [ebp+NTFS.frs_buffer] movzx ecx, word [eax+14h] add eax, ecx - mov ecx, [ntfs_cur_attr] + mov ecx, [ebp+NTFS.ntfs_cur_attr] @@: cmp dword [eax], -1 - jz .errret_pop + jz .errret2_pop cmp dword [eax], ecx jz @f .l1: @@ -589,97 +705,96 @@ ntfs_read_attr: cmp byte [eax+8], 0 jnz .sdnores mov eax, [eax+10h] - mov dword [ntfs_attr_size], eax - and dword [ntfs_attr_size+4], 0 + mov dword [ebp+NTFS.ntfs_attr_size], eax + and dword [ebp+NTFS.ntfs_attr_size+4], 0 jmp .testfz .sdnores: mov ecx, [eax+30h] - mov dword [ntfs_attr_size], ecx + mov dword [ebp+NTFS.ntfs_attr_size], ecx mov ecx, [eax+34h] - mov dword [ntfs_attr_size+4], ecx + mov dword [ebp+NTFS.ntfs_attr_size+4], ecx .testfz: xor eax, eax .testf: - imul eax, [ntfs_data.sectors_per_cluster] - cmp eax, [ntfs_cur_offs] + imul eax, [ebp+NTFS.sectors_per_cluster] + cmp eax, [ebp+NTFS.ntfs_cur_offs] pop eax ja @f mov edi, [esi+10h] ; keep previous iRecord jmp .scanlistcont @@: + pop ecx .scanlistfound: cmp edi, -1 jnz @f popad ret @@: - mov eax, [ntfs_cur_iRecord] - mov [ntfs_attr_iBaseRecord], eax + mov eax, [ebp+NTFS.ntfs_cur_iRecord] + mov [ebp+NTFS.ntfs_attr_iBaseRecord], eax mov eax, edi jmp .beginfindattr -.sde: - popad - stc - ret .scanlistdone: - sub ebp, ntfs_attrlist_buf-1Ah - cmp [ntfs_cur_iRecord], 0 + pop ecx + sub ecx, ebp + sub ecx, NTFS.ntfs_attrlist_buf-1Ah + cmp [ebp+NTFS.ntfs_cur_iRecord], 0 jnz @f - sub ebp, ntfs_attrlist_mft_buf-ntfs_attrlist_buf + sub ecx, NTFS.ntfs_attrlist_mft_buf-NTFS.ntfs_attrlist_buf @@: - cmp ebp, 0x400 + cmp ecx, 0x400 jnz .scanlistfound inc edx push esi edi - mov esi, ntfs_attrlist_buf+0x200 - mov edi, ntfs_attrlist_buf - cmp [ntfs_cur_iRecord], 0 + lea esi, [ebp+NTFS.ntfs_attrlist_buf+0x200] + lea edi, [ebp+NTFS.ntfs_attrlist_buf] + cmp [ebp+NTFS.ntfs_cur_iRecord], 0 jnz @f - mov esi, ntfs_attrlist_mft_buf+0x200 - mov edi, ntfs_attrlist_mft_buf + lea esi, [ebp+NTFS.ntfs_attrlist_mft_buf+0x200] + lea edi, [ebp+NTFS.ntfs_attrlist_mft_buf] @@: mov ecx, 0x200/4 rep movsd mov eax, edi pop edi esi sub esi, 0x200 - push [ntfs_cur_offs] - push [ntfs_cur_size] - push [ntfs_cur_read] - push [ntfs_cur_buf] - push dword [ntfs_attr_size] - push dword [ntfs_attr_size+4] - or dword [ntfs_attr_size], -1 - or dword [ntfs_attr_size+4], -1 - mov [ntfs_cur_offs], edx - mov [ntfs_cur_size], 1 - and [ntfs_cur_read], 0 - mov [ntfs_cur_buf], eax - mov ecx, [ntfs_attr_list] - push esi edx + push [ebp+NTFS.ntfs_cur_offs] + push [ebp+NTFS.ntfs_cur_size] + push [ebp+NTFS.ntfs_cur_read] + push [ebp+NTFS.ntfs_cur_buf] + push dword [ebp+NTFS.ntfs_attr_size] + push dword [ebp+NTFS.ntfs_attr_size+4] + or dword [ebp+NTFS.ntfs_attr_size], -1 + or dword [ebp+NTFS.ntfs_attr_size+4], -1 + mov [ebp+NTFS.ntfs_cur_offs], edx + mov [ebp+NTFS.ntfs_cur_size], 1 + and [ebp+NTFS.ntfs_cur_read], 0 + mov [ebp+NTFS.ntfs_cur_buf], eax + mov ecx, [ebp+NTFS.ntfs_attr_list] + push esi edx edi call .doreadattr - pop edx esi - mov ebp, [ntfs_cur_read] - pop dword [ntfs_attr_size+4] - pop dword [ntfs_attr_size] - pop [ntfs_cur_buf] - pop [ntfs_cur_read] - pop [ntfs_cur_size] - pop [ntfs_cur_offs] + pop edi edx esi + mov ecx, [ebp+NTFS.ntfs_cur_read] + pop dword [ebp+NTFS.ntfs_attr_size+4] + pop dword [ebp+NTFS.ntfs_attr_size] + pop [ebp+NTFS.ntfs_cur_buf] + pop [ebp+NTFS.ntfs_cur_read] + pop [ebp+NTFS.ntfs_cur_size] + pop [ebp+NTFS.ntfs_cur_offs] jc .errret - add ebp, ntfs_attrlist_buf+0x200-0x1A - cmp [ntfs_cur_iRecord], 0 + lea ecx, [ecx+ebp+NTFS.ntfs_attrlist_buf+0x200-0x1A] + cmp [ebp+NTFS.ntfs_cur_iRecord], 0 jnz .scanliststart - add ebp, ntfs_attrlist_mft_buf-ntfs_attrlist_buf + add ecx, NTFS.ntfs_attrlist_mft_buf-NTFS.ntfs_attrlist_buf jmp .scanliststart .doreadattr: - mov [ntfs_bCanContinue], 0 + mov [ebp+NTFS.ntfs_bCanContinue], 0 cmp byte [ecx+8], 0 jnz .nonresident mov eax, [ecx+10h] ; length mov esi, eax - mov edx, [ntfs_cur_offs] + mov edx, [ebp+NTFS.ntfs_cur_offs] shr eax, 9 cmp eax, edx jb .okret @@ -688,7 +803,7 @@ ntfs_read_attr: movzx eax, word [ecx+14h] add edx, eax add edx, ecx ; edx -> data - mov eax, [ntfs_cur_size] + mov eax, [ebp+NTFS.ntfs_cur_size] cmp eax, (0xFFFFFFFF shr 9)+1 jbe @f mov eax, (0xFFFFFFFF shr 9)+1 @@ -699,17 +814,17 @@ ntfs_read_attr: mov eax, esi @@: ; eax = length, edx -> data - mov [ntfs_cur_read], eax + mov [ebp+NTFS.ntfs_cur_read], eax mov ecx, eax mov eax, edx - mov ebx, [ntfs_cur_buf] + mov ebx, [ebp+NTFS.ntfs_cur_buf] call memmove - and [ntfs_cur_size], 0 ; CF=0 + and [ebp+NTFS.ntfs_cur_size], 0 ; CF=0 ret .nonresident: ; Not all auxiliary records contain correct FileSize info - mov eax, dword [ntfs_attr_size] - mov edx, dword [ntfs_attr_size+4] + mov eax, dword [ebp+NTFS.ntfs_attr_size] + mov edx, dword [ebp+NTFS.ntfs_attr_size+4] push eax and eax, edx cmp eax, -1 @@ -717,85 +832,94 @@ ntfs_read_attr: jnz @f mov eax, [ecx+30h] ; FileSize mov edx, [ecx+34h] - mov dword [ntfs_attr_size], eax - mov dword [ntfs_attr_size+4], edx + mov dword [ebp+NTFS.ntfs_attr_size], eax + mov dword [ebp+NTFS.ntfs_attr_size+4], edx @@: add eax, 0x1FF adc edx, 0 shrd eax, edx, 9 - sub eax, [ntfs_cur_offs] + sub eax, [ebp+NTFS.ntfs_cur_offs] ja @f ; return with nothing read - and [ntfs_cur_size], 0 + and [ebp+NTFS.ntfs_cur_size], 0 .okret: clc ret @@: ; reduce read length - and [ntfs_cur_tail], 0 - cmp [ntfs_cur_size], eax + and [ebp+NTFS.ntfs_cur_tail], 0 + cmp [ebp+NTFS.ntfs_cur_size], eax jb @f - mov [ntfs_cur_size], eax - mov eax, dword [ntfs_attr_size] + mov [ebp+NTFS.ntfs_cur_size], eax + mov eax, dword [ebp+NTFS.ntfs_attr_size] and eax, 0x1FF - mov [ntfs_cur_tail], eax + mov [ebp+NTFS.ntfs_cur_tail], eax @@: - cmp [ntfs_cur_size], 0 + cmp [ebp+NTFS.ntfs_cur_size], 0 jz .okret - mov eax, [ntfs_cur_offs] + mov eax, [ebp+NTFS.ntfs_cur_offs] xor edx, edx - div [ntfs_data.sectors_per_cluster] + div [ebp+NTFS.sectors_per_cluster] sub eax, [ecx+10h] ; first_vbo jb .okret ; eax = cluster, edx = starting sector sub esp, 10h movzx esi, word [ecx+20h] ; mcb_info_ofs add esi, ecx - xor ebp, ebp + xor edi, edi .readloop: call ntfs_decode_mcb_entry jnc .break - add ebp, [esp+8] + add edi, [esp+8] sub eax, [esp] jae .readloop push ecx push eax add eax, [esp+8] - add eax, ebp - imul eax, [ntfs_data.sectors_per_cluster] + add eax, edi + imul eax, [ebp+NTFS.sectors_per_cluster] add eax, edx - add eax, [PARTITION_START] pop ecx neg ecx - imul ecx, [ntfs_data.sectors_per_cluster] + imul ecx, [ebp+NTFS.sectors_per_cluster] sub ecx, edx - cmp ecx, [ntfs_cur_size] + cmp ecx, [ebp+NTFS.ntfs_cur_size] jb @f - mov ecx, [ntfs_cur_size] + mov ecx, [ebp+NTFS.ntfs_cur_size] @@: - mov ebx, [ntfs_cur_buf] + mov ebx, [ebp+NTFS.ntfs_cur_buf] @@: - call hd_read - cmp [hd_error], 0 + push eax + cmp [ebp+NTFS.ntfs_cur_attr], 0x80 + jnz .sys + cmp [ebp+NTFS.ntfs_cur_iRecord], 0 + jz .sys + call fs_read32_app + jmp .appsys +.sys: + call fs_read32_sys +.appsys: + pop edx + test eax, eax jnz .errread2 add ebx, 0x200 - mov [ntfs_cur_buf], ebx - inc eax - add [ntfs_cur_read], 0x200 - dec [ntfs_cur_size] - inc [ntfs_cur_offs] + mov [ebp+NTFS.ntfs_cur_buf], ebx + lea eax, [edx+1] + add [ebp+NTFS.ntfs_cur_read], 0x200 + dec [ebp+NTFS.ntfs_cur_size] + inc [ebp+NTFS.ntfs_cur_offs] loop @b pop ecx xor eax, eax xor edx, edx - cmp [ntfs_cur_size], 0 + cmp [ebp+NTFS.ntfs_cur_size], 0 jnz .readloop add esp, 10h - mov eax, [ntfs_cur_tail] + mov eax, [ebp+NTFS.ntfs_cur_tail] test eax, eax jz @f sub eax, 0x200 - add [ntfs_cur_read], eax + add [ebp+NTFS.ntfs_cur_read], eax @@: clc ret @@ -806,76 +930,75 @@ ntfs_read_attr: ret .break: add esp, 10h ; CF=0 - mov [ntfs_bCanContinue], 1 + mov [ebp+NTFS.ntfs_bCanContinue], 1 ret ntfs_read_file_record: ; in: eax=iRecord -; out: [ntfs_data.frs_buffer] contains information -; eax=0 - failed, eax=1 - success -; Read attr $DATA of $Mft, starting from eax*[ntfs_data.frs_size] +; out: [ebp+NTFS.frs_buffer] contains information +; CF=1 - failed, in this case eax=0 => something with FS, eax nonzero => disk error +; Read attr $DATA of $Mft, starting from eax*[ebp+NTFS.frs_size] push ecx edx - mov ecx, [ntfs_data.frs_size] + mov ecx, [ebp+NTFS.frs_size] mul ecx shrd eax, edx, 9 shr edx, 9 - jnz .err - push [ntfs_attr_iRecord] - push [ntfs_attr_iBaseRecord] - push [ntfs_attr_offs] - push [ntfs_attr_list] - push dword [ntfs_attr_size+4] - push dword [ntfs_attr_size] - push [ntfs_cur_iRecord] - push [ntfs_cur_attr] - push [ntfs_cur_offs] - push [ntfs_cur_size] - push [ntfs_cur_buf] - push [ntfs_cur_read] - mov [ntfs_cur_attr], 0x80 ; $DATA - and [ntfs_cur_iRecord], 0 ; $Mft - mov [ntfs_cur_offs], eax - shr ecx, 9 - mov [ntfs_cur_size], ecx - mov eax, [ntfs_data.frs_buffer] - mov [ntfs_cur_buf], eax - call ntfs_read_attr - mov eax, [ntfs_cur_read] - pop [ntfs_cur_read] - pop [ntfs_cur_buf] - pop [ntfs_cur_size] - pop [ntfs_cur_offs] - pop [ntfs_cur_attr] - pop [ntfs_cur_iRecord] - pop dword [ntfs_attr_size] - pop dword [ntfs_attr_size+4] - pop [ntfs_attr_list] - pop [ntfs_attr_offs] - pop [ntfs_attr_iBaseRecord] - pop [ntfs_attr_iRecord] - pop edx ecx - jc .errret - cmp eax, [ntfs_data.frs_size] jnz .errret - mov eax, [ntfs_data.frs_buffer] + push [ebp+NTFS.ntfs_attr_iRecord] + push [ebp+NTFS.ntfs_attr_iBaseRecord] + push [ebp+NTFS.ntfs_attr_offs] + push [ebp+NTFS.ntfs_attr_list] + push dword [ebp+NTFS.ntfs_attr_size+4] + push dword [ebp+NTFS.ntfs_attr_size] + push [ebp+NTFS.ntfs_cur_iRecord] + push [ebp+NTFS.ntfs_cur_attr] + push [ebp+NTFS.ntfs_cur_offs] + push [ebp+NTFS.ntfs_cur_size] + push [ebp+NTFS.ntfs_cur_buf] + push [ebp+NTFS.ntfs_cur_read] + mov [ebp+NTFS.ntfs_cur_attr], 0x80 ; $DATA + and [ebp+NTFS.ntfs_cur_iRecord], 0 ; $Mft + mov [ebp+NTFS.ntfs_cur_offs], eax + shr ecx, 9 + mov [ebp+NTFS.ntfs_cur_size], ecx + mov eax, [ebp+NTFS.frs_buffer] + mov [ebp+NTFS.ntfs_cur_buf], eax + call ntfs_read_attr + mov edx, [ebp+NTFS.ntfs_cur_read] + pop [ebp+NTFS.ntfs_cur_read] + pop [ebp+NTFS.ntfs_cur_buf] + pop [ebp+NTFS.ntfs_cur_size] + pop [ebp+NTFS.ntfs_cur_offs] + pop [ebp+NTFS.ntfs_cur_attr] + pop [ebp+NTFS.ntfs_cur_iRecord] + pop dword [ebp+NTFS.ntfs_attr_size] + pop dword [ebp+NTFS.ntfs_attr_size+4] + pop [ebp+NTFS.ntfs_attr_list] + pop [ebp+NTFS.ntfs_attr_offs] + pop [ebp+NTFS.ntfs_attr_iBaseRecord] + pop [ebp+NTFS.ntfs_attr_iRecord] + jc .ret + cmp edx, [ebp+NTFS.frs_size] + jnz .errret + mov eax, [ebp+NTFS.frs_buffer] cmp dword [eax], 'FILE' jnz .errret push ebx mov ebx, eax call ntfs_restore_usa_frs pop ebx - setnc al - movzx eax, al + jc .errret .ret: - ret -.err: pop edx ecx + ret .errret: + pop edx ecx xor eax, eax + stc ret ntfs_restore_usa_frs: - mov eax, [ntfs_data.frs_size] + mov eax, [ebp+NTFS.frs_size] ntfs_restore_usa: pushad shr eax, 9 @@ -955,82 +1078,83 @@ unichar_toupper: ret ntfs_find_lfn: -; in: esi+ebp -> name +; in: esi+[esp+4] -> name ; out: CF=1 - file not found -; else CF=0, [ntfs_cur_iRecord] valid, eax->record in parent directory - mov [ntfs_cur_iRecord], 5 ; start parse from root cluster +; else CF=0, [ebp+NTFS.ntfs_cur_iRecord] valid, eax->record in parent directory + mov [ebp+NTFS.ntfs_cur_iRecord], 5 ; start parse from root cluster .doit2: - mov [ntfs_cur_attr], 0x90 ; $INDEX_ROOT - and [ntfs_cur_offs], 0 - mov eax, [ntfs_data.cur_index_size] - mov [ntfs_cur_size], eax - mov eax, [ntfs_data.cur_index_buf] - mov [ntfs_cur_buf], eax + mov [ebp+NTFS.ntfs_cur_attr], 0x90 ; $INDEX_ROOT + and [ebp+NTFS.ntfs_cur_offs], 0 + mov eax, [ebp+NTFS.cur_index_size] + mov [ebp+NTFS.ntfs_cur_size], eax + mov eax, [ebp+NTFS.cur_index_buf] + mov [ebp+NTFS.ntfs_cur_buf], eax call ntfs_read_attr jnc @f .ret: - ret + ret 4 @@: - cmp [ntfs_cur_read], 0x20 + xor eax, eax + cmp [ebp+NTFS.ntfs_cur_read], 0x20 jc .ret pushad - mov esi, [ntfs_data.cur_index_buf] + mov esi, [ebp+NTFS.cur_index_buf] mov eax, [esi+14h] add eax, 10h - cmp [ntfs_cur_read], eax + cmp [ebp+NTFS.ntfs_cur_read], eax jae .readok1 add eax, 1FFh shr eax, 9 - cmp eax, [ntfs_data.cur_index_size] + cmp eax, [ebp+NTFS.cur_index_size] ja @f .stc_ret: popad stc - ret + ret 4 @@: ; reallocate push eax - push [ntfs_data.cur_index_buf] + push [ebp+NTFS.cur_index_buf] call kernel_free pop eax - mov [ntfs_data.cur_index_size], eax + mov [ebp+NTFS.cur_index_size], eax push eax call kernel_alloc test eax, eax jnz @f - and [ntfs_data.cur_index_size], 0 - and [ntfs_data.cur_index_buf], 0 + and [ebp+NTFS.cur_index_size], 0 + and [ebp+NTFS.cur_index_buf], 0 jmp .stc_ret @@: - mov [ntfs_data.cur_index_buf], eax + mov [ebp+NTFS.cur_index_buf], eax popad jmp .doit2 .readok1: - mov ebp, [esi+8] ; subnode_size - shr ebp, 9 - cmp ebp, [ntfs_data.cur_index_size] + mov edx, [esi+8] ; subnode_size + shr edx, 9 + cmp edx, [ebp+NTFS.cur_index_size] jbe .ok2 - push esi ebp - push ebp + push esi edx + push edx call kernel_alloc - pop ebp esi + pop edx esi test eax, eax jz .stc_ret mov edi, eax - mov ecx, [ntfs_data.cur_index_size] + mov ecx, [ebp+NTFS.cur_index_size] shl ecx, 9-2 rep movsd mov esi, eax - mov [ntfs_data.cur_index_size], ebp - push esi ebp - push [ntfs_data.cur_index_buf] + mov [ebp+NTFS.cur_index_size], edx + push esi edx + push [ebp+NTFS.cur_index_buf] call kernel_free - pop ebp esi - mov [ntfs_data.cur_index_buf], esi + pop edx esi + mov [ebp+NTFS.cur_index_buf], esi .ok2: add esi, 10h mov edi, [esp+4] -; edi -> name, esi -> current index data, ebp = subnode size +; edi -> name, esi -> current index data, edx = subnode size .scanloop: add esi, [esi] .scanloopint: @@ -1070,17 +1194,19 @@ ntfs_find_lfn: jz .notfound movzx eax, word [esi+8] mov eax, [esi+eax-8] - mul [ntfs_data.sectors_per_cluster] - mov [ntfs_cur_offs], eax - mov [ntfs_cur_attr], 0xA0 ; $INDEX_ALLOCATION - mov [ntfs_cur_size], ebp - mov eax, [ntfs_data.cur_index_buf] + imul eax, [ebp+NTFS.sectors_per_cluster] + mov [ebp+NTFS.ntfs_cur_offs], eax + mov [ebp+NTFS.ntfs_cur_attr], 0xA0 ; $INDEX_ALLOCATION + mov [ebp+NTFS.ntfs_cur_size], edx + mov eax, [ebp+NTFS.cur_index_buf] mov esi, eax - mov [ntfs_cur_buf], eax + mov [ebp+NTFS.ntfs_cur_buf], eax + push edx call ntfs_read_attr - mov eax, ebp + pop edx + mov eax, edx shl eax, 9 - cmp [ntfs_cur_read], eax + cmp [ebp+NTFS.ntfs_cur_read], eax jnz .notfound cmp dword [esi], 'INDX' jnz .notfound @@ -1092,7 +1218,7 @@ ntfs_find_lfn: .notfound: popad stc - ret + ret 4 .found: cmp byte [edi], 0 jz .done @@ -1106,53 +1232,49 @@ ntfs_find_lfn: pop esi pop esi mov eax, [esi] - mov [ntfs_cur_iRecord], eax + mov [ebp+NTFS.ntfs_cur_iRecord], eax mov [esp+1Ch], esi mov [esp+4], edi popad inc esi cmp byte [esi-1], 0 jnz .doit2 - test ebp, ebp + cmp dword [esp+4], 0 jz @f - mov esi, ebp - xor ebp, ebp + mov esi, [esp+4] + mov dword [esp+4], 0 jmp .doit2 @@: - ret + ret 4 ;---------------------------------------------------------------- -; -; ntfs_HdRead - read NTFS hard disk -; -; 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 -; -; ret ebx = bytes read or 0xffffffff file not found -; eax = 0 ok read or other = errormsg -; -;-------------------------------------------------------------- -ntfs_HdRead: +; ntfs_Read - NTFS implementation of reading a file +; in: ebp = pointer to NTFS structure +; in: esi+[esp+4] = name +; in: ebx = pointer to parameters from sysfunc 70 +; out: eax, ebx = return values for sysfunc 70 +;---------------------------------------------------------------- +ntfs_Read: cmp byte [esi], 0 jnz @f or ebx, -1 movi eax, ERROR_ACCESS_DENIED ret @@: - call ntfs_find_lfn + call ntfs_lock + stdcall ntfs_find_lfn, [esp+4] jnc .found + call ntfs_unlock or ebx, -1 movi eax, ERROR_FILE_NOT_FOUND ret .found: - mov [ntfs_cur_attr], 0x80 ; $DATA - and [ntfs_cur_offs], 0 - and [ntfs_cur_size], 0 + mov [ebp+NTFS.ntfs_cur_attr], 0x80 ; $DATA + and [ebp+NTFS.ntfs_cur_offs], 0 + and [ebp+NTFS.ntfs_cur_size], 0 call ntfs_read_attr jnc @f + call ntfs_unlock or ebx, -1 movi eax, ERROR_ACCESS_DENIED ret @@ -1160,32 +1282,36 @@ ntfs_HdRead: pushad and dword [esp+10h], 0 xor eax, eax - test ebx, ebx - jz .zero1 - cmp dword [ebx+4], 0x200 + cmp dword [ebx+8], 0x200 jb @f .eof0: popad xor ebx, ebx .eof: movi eax, ERROR_END_OF_FILE + push eax + call ntfs_unlock + pop eax ret @@: - mov eax, [ebx] + mov ecx, [ebx+12] + mov edx, [ebx+16] + mov eax, [ebx+4] test eax, 0x1FF jz .alignedstart push edx - mov edx, [ebx+4] + mov edx, [ebx+8] shrd eax, edx, 9 pop edx - mov [ntfs_cur_offs], eax - mov [ntfs_cur_size], 1 - mov [ntfs_cur_buf], ntfs_bitmap_buf + mov [ebp+NTFS.ntfs_cur_offs], eax + mov [ebp+NTFS.ntfs_cur_size], 1 + lea eax, [ebp+NTFS.ntfs_bitmap_buf] + mov [ebp+NTFS.ntfs_cur_buf], eax call ntfs_read_attr.continue - mov eax, [ebx] + mov eax, [ebx+4] and eax, 0x1FF - lea esi, [ntfs_bitmap_buf+eax] - sub eax, [ntfs_cur_read] + lea esi, [ebp+NTFS.ntfs_bitmap_buf+eax] + sub eax, [ebp+NTFS.ntfs_cur_read] jae .eof0 neg eax push ecx @@ -1202,115 +1328,113 @@ ntfs_HdRead: jnz @f .retok: popad + call ntfs_unlock xor eax, eax ret @@: - cmp [ntfs_cur_read], 0x200 + cmp [ebp+NTFS.ntfs_cur_read], 0x200 jz .alignedstart .eof_ebx: popad jmp .eof .alignedstart: - mov eax, [ebx] + mov eax, [ebx+4] push edx - mov edx, [ebx+4] + mov edx, [ebx+8] add eax, 511 adc edx, 0 shrd eax, edx, 9 pop edx .zero1: - mov [ntfs_cur_offs], eax - mov [ntfs_cur_buf], edx + mov [ebp+NTFS.ntfs_cur_offs], eax + mov [ebp+NTFS.ntfs_cur_buf], edx mov eax, ecx shr eax, 9 - mov [ntfs_cur_size], eax - add eax, [ntfs_cur_offs] + mov [ebp+NTFS.ntfs_cur_size], eax + add eax, [ebp+NTFS.ntfs_cur_offs] push eax call ntfs_read_attr.continue - pop [ntfs_cur_offs] - mov eax, [ntfs_cur_read] + pop [ebp+NTFS.ntfs_cur_offs] + mov eax, [ebp+NTFS.ntfs_cur_read] add [esp+10h], eax mov eax, ecx and eax, not 0x1FF - cmp [ntfs_cur_read], eax + cmp [ebp+NTFS.ntfs_cur_read], eax jnz .eof_ebx and ecx, 0x1FF jz .retok - add edx, [ntfs_cur_read] - mov [ntfs_cur_size], 1 - mov [ntfs_cur_buf], ntfs_bitmap_buf + add edx, [ebp+NTFS.ntfs_cur_read] + mov [ebp+NTFS.ntfs_cur_size], 1 + lea eax, [ebp+NTFS.ntfs_bitmap_buf] + mov [ebp+NTFS.ntfs_cur_buf], eax call ntfs_read_attr.continue - cmp [ntfs_cur_read], ecx + cmp [ebp+NTFS.ntfs_cur_read], ecx jb @f - mov [ntfs_cur_read], ecx + mov [ebp+NTFS.ntfs_cur_read], ecx @@: - xchg ecx, [ntfs_cur_read] + xchg ecx, [ebp+NTFS.ntfs_cur_read] push ecx mov edi, edx - mov esi, ntfs_bitmap_buf + lea esi, [ebp+NTFS.ntfs_bitmap_buf] add [esp+10h+4], ecx rep movsb pop ecx xor eax, eax - cmp ecx, [ntfs_cur_read] + cmp ecx, [ebp+NTFS.ntfs_cur_read] jz @f mov al, ERROR_END_OF_FILE @@: mov [esp+1Ch], eax + call ntfs_unlock popad ret ;---------------------------------------------------------------- -; -; ntfs_HdReadFolder - read NTFS hard disk folder -; -; 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 -; -;-------------------------------------------------------------- -ntfs_HdReadFolder: +; ntfs_ReadFolder - NTFS implementation of reading a folder +; in: ebp = pointer to NTFS structure +; in: esi+[esp+4] = name +; in: ebx = pointer to parameters from sysfunc 70 +; out: eax, ebx = return values for sysfunc 70 +;---------------------------------------------------------------- +ntfs_ReadFolder: + call ntfs_lock mov eax, 5 ; root cluster cmp byte [esi], 0 jz .doit - call ntfs_find_lfn + stdcall ntfs_find_lfn, [esp+4] jnc .doit2 .notfound: or ebx, -1 push ERROR_FILE_NOT_FOUND .pop_ret: + call ntfs_unlock pop eax ret .doit: - mov [ntfs_cur_iRecord], eax + mov [ebp+NTFS.ntfs_cur_iRecord], eax .doit2: - mov [ntfs_cur_attr], 0x10 ; $STANDARD_INFORMATION - and [ntfs_cur_offs], 0 - mov [ntfs_cur_size], 1 - mov [ntfs_cur_buf], ntfs_bitmap_buf + mov [ebp+NTFS.ntfs_cur_attr], 0x10 ; $STANDARD_INFORMATION + and [ebp+NTFS.ntfs_cur_offs], 0 + mov [ebp+NTFS.ntfs_cur_size], 1 + lea eax, [ebp+NTFS.ntfs_bitmap_buf] + mov [ebp+NTFS.ntfs_cur_buf], eax call ntfs_read_attr jc .notfound - mov [ntfs_cur_attr], 0x90 ; $INDEX_ROOT - and [ntfs_cur_offs], 0 - mov eax, [ntfs_data.cur_index_size] - mov [ntfs_cur_size], eax - mov eax, [ntfs_data.cur_index_buf] - mov [ntfs_cur_buf], eax + mov [ebp+NTFS.ntfs_cur_attr], 0x90 ; $INDEX_ROOT + and [ebp+NTFS.ntfs_cur_offs], 0 + mov eax, [ebp+NTFS.cur_index_size] + mov [ebp+NTFS.ntfs_cur_size], eax + mov eax, [ebp+NTFS.cur_index_buf] + mov [ebp+NTFS.ntfs_cur_buf], eax call ntfs_read_attr jnc .ok - cmp [hd_error], 0 + test eax, eax jz .notfound or ebx, -1 push 11 jmp .pop_ret .ok: - cmp [ntfs_cur_read], 0x20 + cmp [ebp+NTFS.ntfs_cur_read], 0x20 jae @f or ebx, -1 .fserr: @@ -1318,80 +1442,79 @@ ntfs_HdReadFolder: jmp .pop_ret @@: pushad - mov esi, [ntfs_data.cur_index_buf] + mov esi, [ebp+NTFS.cur_index_buf] mov eax, [esi+14h] add eax, 10h - cmp [ntfs_cur_read], eax + cmp [ebp+NTFS.ntfs_cur_read], eax jae .readok1 add eax, 1FFh shr eax, 9 - cmp eax, [ntfs_data.cur_index_size] + cmp eax, [ebp+NTFS.cur_index_size] ja @f popad jmp .fserr @@: ; reallocate push eax - push [ntfs_data.cur_index_buf] + push [ebp+NTFS.cur_index_buf] call kernel_free pop eax - mov [ntfs_data.cur_index_size], eax + mov [ebp+NTFS.cur_index_size], eax push eax call kernel_alloc test eax, eax jnz @f - and [ntfs_data.cur_index_size], 0 - and [ntfs_data.cur_index_buf], 0 + and [ebp+NTFS.cur_index_size], 0 + and [ebp+NTFS.cur_index_buf], 0 .nomem: + call ntfs_unlock popad or ebx, -1 movi eax, 12 ret @@: - mov [ntfs_data.cur_index_buf], eax + mov [ebp+NTFS.cur_index_buf], eax popad jmp .doit2 .readok1: - mov ebp, [esi+8] ; subnode_size - shr ebp, 9 - cmp ebp, [ntfs_data.cur_index_size] + mov edx, [esi+8] ; subnode_size + shr edx, 9 + mov [ebp+NTFS.cur_subnode_size], edx + cmp edx, [ebp+NTFS.cur_index_size] jbe .ok2 - push esi ebp - push ebp + push esi edx + push edx call kernel_alloc - pop ebp esi + pop edx esi test eax, eax jz .nomem mov edi, eax - mov ecx, [ntfs_data.cur_index_size] + mov ecx, [ebp+NTFS.cur_index_size] shl ecx, 9-2 rep movsd mov esi, eax - mov [ntfs_data.cur_index_size], ebp - push esi ebp - push [ntfs_data.cur_index_buf] + mov [ebp+NTFS.cur_index_size], edx + push [ebp+NTFS.cur_index_buf] call kernel_free - pop ebp esi - mov [ntfs_data.cur_index_buf], esi + mov [ebp+NTFS.cur_index_buf], esi .ok2: add esi, 10h - mov ebx, [esp+10h] - mov edx, [esp+14h] - push dword [ebx+4] ; read ANSI/UNICODE name - mov ebx, [ebx] + mov edx, [ebx+16] + push dword [ebx+8] ; read ANSI/UNICODE name ; init header mov edi, edx mov ecx, 32/4 xor eax, eax rep stosd mov byte [edx], 1 ; version - mov ecx, [esp+4+18h] + mov ecx, [ebx+12] + mov ebx, [ebx+4] push edx mov edx, esp -; edi -> BDFE, esi -> current index data, ebp = subnode size, ebx = first wanted block, +; edi -> BDFE, esi -> current index data, ebx = first wanted block, ; ecx = number of blocks to read ; edx -> parameters block: dd , dd - cmp [ntfs_cur_iRecord], 5 + cmp [ebp+NTFS.ntfs_cur_iRecord], 5 jz .skip_specials ; dot and dotdot entries push esi @@ -1413,38 +1536,39 @@ ntfs_HdReadFolder: .dump_root_done: ; now dump all subnodes push ecx edi - mov edi, ntfs_bitmap_buf - mov [ntfs_cur_buf], edi + lea edi, [ebp+NTFS.ntfs_bitmap_buf] + mov [ebp+NTFS.ntfs_cur_buf], edi mov ecx, 0x400/4 xor eax, eax rep stosd - mov [ntfs_cur_attr], 0xB0 ; $BITMAP - and [ntfs_cur_offs], 0 - mov [ntfs_cur_size], 2 + mov [ebp+NTFS.ntfs_cur_attr], 0xB0 ; $BITMAP + and [ebp+NTFS.ntfs_cur_offs], 0 + mov [ebp+NTFS.ntfs_cur_size], 2 call ntfs_read_attr pop edi ecx push 0 ; save offset in $BITMAP attribute - and [ntfs_cur_offs], 0 + and [ebp+NTFS.ntfs_cur_offs], 0 .dumploop: - mov [ntfs_cur_attr], 0xA0 - mov [ntfs_cur_size], ebp - mov eax, [ntfs_data.cur_index_buf] + mov [ebp+NTFS.ntfs_cur_attr], 0xA0 + mov eax, [ebp+NTFS.cur_subnode_size] + mov [ebp+NTFS.ntfs_cur_size], eax + mov eax, [ebp+NTFS.cur_index_buf] mov esi, eax - mov [ntfs_cur_buf], eax - push [ntfs_cur_offs] - mov eax, [ntfs_cur_offs] - imul eax, ebp - mov [ntfs_cur_offs], eax + mov [ebp+NTFS.ntfs_cur_buf], eax + push [ebp+NTFS.ntfs_cur_offs] + mov eax, [ebp+NTFS.ntfs_cur_offs] + imul eax, [ebp+NTFS.cur_subnode_size] + mov [ebp+NTFS.ntfs_cur_offs], eax call ntfs_read_attr - pop [ntfs_cur_offs] - mov eax, ebp + pop [ebp+NTFS.ntfs_cur_offs] + mov eax, [ebp+NTFS.cur_subnode_size] shl eax, 9 - cmp [ntfs_cur_read], eax + cmp [ebp+NTFS.ntfs_cur_read], eax jnz .done push eax - mov eax, [ntfs_cur_offs] + mov eax, [ebp+NTFS.ntfs_cur_offs] and eax, 0x400*8-1 - bt dword [ntfs_bitmap_buf], eax + bt dword [ebp+NTFS.ntfs_bitmap_buf], eax pop eax jnc .dump_subnode_done cmp dword [esi], 'INDX' @@ -1464,26 +1588,26 @@ ntfs_HdReadFolder: add esi, eax jmp .dump_subnode .dump_subnode_done: - inc [ntfs_cur_offs] - test [ntfs_cur_offs], 0x400*8-1 + inc [ebp+NTFS.ntfs_cur_offs] + test [ebp+NTFS.ntfs_cur_offs], 0x400*8-1 jnz .dumploop - mov [ntfs_cur_attr], 0xB0 + mov [ebp+NTFS.ntfs_cur_attr], 0xB0 push ecx edi - mov edi, ntfs_bitmap_buf - mov [ntfs_cur_buf], edi + lea edi, [ebp+NTFS.ntfs_bitmap_buf] + mov [ebp+NTFS.ntfs_cur_buf], edi mov ecx, 0x400/4 xor eax, eax rep stosd pop edi ecx pop eax - push [ntfs_cur_offs] + push [ebp+NTFS.ntfs_cur_offs] inc eax - mov [ntfs_cur_offs], eax - mov [ntfs_cur_size], 2 + mov [ebp+NTFS.ntfs_cur_offs], eax + mov [ebp+NTFS.ntfs_cur_size], 2 push eax call ntfs_read_attr pop eax - pop [ntfs_cur_offs] + pop [ebp+NTFS.ntfs_cur_offs] push eax jmp .dumploop .done: @@ -1498,6 +1622,7 @@ ntfs_HdReadFolder: @@: mov [esp+1Ch], eax mov [esp+10h], ebx + call ntfs_unlock popad ret @@ -1517,14 +1642,14 @@ ntfs_HdReadFolder: stosd scasd push edx - mov eax, dword [ntfs_bitmap_buf] - mov edx, dword [ntfs_bitmap_buf+4] + mov eax, dword [ebp+NTFS.ntfs_bitmap_buf] + mov edx, dword [ebp+NTFS.ntfs_bitmap_buf+4] call ntfs_datetime_to_bdfe - mov eax, dword [ntfs_bitmap_buf+0x18] - mov edx, dword [ntfs_bitmap_buf+0x1C] + mov eax, dword [ebp+NTFS.ntfs_bitmap_buf+0x18] + mov edx, dword [ebp+NTFS.ntfs_bitmap_buf+0x1C] call ntfs_datetime_to_bdfe - mov eax, dword [ntfs_bitmap_buf+8] - mov edx, dword [ntfs_bitmap_buf+0xC] + mov eax, dword [ebp+NTFS.ntfs_bitmap_buf+8] + mov edx, dword [ebp+NTFS.ntfs_bitmap_buf+0xC] call ntfs_datetime_to_bdfe pop edx xor eax, eax @@ -1733,90 +1858,69 @@ ntfs_datetime_to_bdfe: ret ;---------------------------------------------------------------- -; -; ntfs_HdRewrite - write to NTFS hard disk -; -; 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 -; -;-------------------------------------------------------------- -ntfs_HdRewrite: +; ntfs_Rewrite - NTFS implementation of creating a new file +; in: ebp = pointer to NTFS structure +; in: esi+[esp+4] = name +; in: ebx = pointer to parameters from sysfunc 70 +; out: eax, ebx = return values for sysfunc 70 +;---------------------------------------------------------------- +ntfs_Rewrite: +ntfs_CreateFolder: xor ebx, ebx mov eax, ERROR_UNSUPPORTED_FS ret ;---------------------------------------------------------------- -; -; ntfs_HdWrite - write to NTFS hard disk -; -; 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 -; -;-------------------------------------------------------------- -ntfs_HdWrite: +; ntfs_Write - NTFS implementation of writing to file +; in: ebp = pointer to NTFS structure +; in: esi+[esp+4] = name +; in: ebx = pointer to parameters from sysfunc 70 +; out: eax, ebx = return values for sysfunc 70 +;---------------------------------------------------------------- +ntfs_Write: xor ebx, ebx mov eax, ERROR_UNSUPPORTED_FS ret -;---------------------------------------------------------------- -; -; ntfs_HdSetFileEnd - set end of file on NTFS hard disk -; -; 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 -; -;-------------------------------------------------------------- -ntfs_HdSetFileEnd: -ntfs_HdSetFileInfo: -;---------------------------------------------------------------- -; -; ntfs_HdDelete - delete file or empty folder from NTFS hard disk -; -; esi points to filename -; -; ret eax = 0 ok or other = errormsg -; -;-------------------------------------------------------------- -ntfs_HdDelete: +ntfs_SetFileEnd: +ntfs_SetFileInfo: +ntfs_Delete: mov eax, ERROR_UNSUPPORTED_FS ret -ntfs_HdGetFileInfo: +;---------------------------------------------------------------- +; ntfs_GetFileInfo - NTFS implementation of getting file info +; in: ebp = pointer to NTFS structure +; in: esi+[esp+4] = name +; in: ebx = pointer to parameters from sysfunc 70 +; out: eax, ebx = return values for sysfunc 70 +;---------------------------------------------------------------- +ntfs_GetFileInfo: cmp byte [esi], 0 jnz @f movi eax, 2 ret @@: - call ntfs_find_lfn + call ntfs_lock + stdcall ntfs_find_lfn, [esp+4] jnc .doit + test eax, eax movi eax, ERROR_FILE_NOT_FOUND - cmp [hd_error], 0 jz @f mov al, 11 @@: + push eax + call ntfs_unlock + pop eax ret .doit: push esi edi mov esi, eax - mov edi, edx + mov edi, [ebx+16] xor eax, eax call ntfs_direntry_to_bdfe pop edi esi + call ntfs_unlock xor eax, eax ret diff --git a/kernel/trunk/fs/part_set.inc b/kernel/trunk/fs/part_set.inc deleted file mode 100644 index 61a17efda5..0000000000 --- a/kernel/trunk/fs/part_set.inc +++ /dev/null @@ -1,436 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - - -;************************************************************* -;* 13.02.2010 Find all partition and check supported FS -;* 12.07.2007 Check all 4 entry of MBR and EMBR -;* 29.04.2006 Elimination of hangup after the -;* expiration hd_wait_timeout - Mario79 -;* 28.01.2006 find all Fat16/32 partition in all input point -;* to MBR - Mario79 -;************************************************************* - -uglobal -align 4 - -;****************************************************** -; Please do not change this place - variables in text -; Mario79 -; START place -;****************************************************** -PARTITION_START dd 0x3f -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 - -.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 - -virtual at fs_dependent_data_start -; NTFS data -ntfs_data: -.sectors_per_cluster dd ? -.mft_cluster dd ? -.mftmirr_cluster dd ? -.frs_size dd ? ; FRS size in bytes -.iab_size dd ? ; IndexAllocationBuffer size in bytes -.frs_buffer dd ? -.iab_buffer dd ? -.mft_retrieval dd ? -.mft_retrieval_size dd ? -.mft_retrieval_alloc dd ? -.mft_retrieval_end dd ? -.cur_index_size dd ? -.cur_index_buf dd ? -if $ > fs_dependent_data_end -ERROR: - increase sizeof(fs_dependent_data)! -end if -end virtual - -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 ? - .global_desc_table dd ? - .root_inode dd ? ; pointer to root inode in memory - .inode_size dd ? - .count_pointer_in_block dd ? ; block_size / 4 - .count_pointer_in_block_square dd ? ; (block_size / 4)**2 - .ext2_save_block dd ? ;RUS: блок на глобальную 1 процедуру ;ENG: block for 1 global procedure - .ext2_temp_block dd ? ;RUS: блок для мелких процедур ;ENG: block for small procedures - .ext2_save_inode dd ? ;RUS: inode на глобальную процедуру ;ENG: inode for global procedure - .ext2_temp_inode dd ? ;RUS: inode для мелких процедур ;ENG: inode for small procedures - .sb dd ? ; superblock - .groups_count dd ? -if $ > fs_dependent_data_end -ERROR: - increase sizeof(fs_dependent_data)! -end if -end virtual - -;*************************************************************************** -; End place -; Mario79 -;*************************************************************************** -endg -iglobal - - partition_types: ; list of fat16/32 partitions - db 0x04 ; DOS: fat16 <32M - db 0x06 ; DOS: fat16 >32M - db 0x0b ; WIN95: fat32 - db 0x0c ; WIN95: fat32, LBA-mapped - db 0x0e ; WIN95: fat16, LBA-mapped - db 0x14 ; Hidden DOS: fat16 <32M - db 0x16 ; Hidden DOS: fat16 >32M - db 0x1b ; Hidden WIN95: fat32 - db 0x1c ; Hidden WIN95: fat32, LBA-mapped - db 0x1e ; Hidden WIN95: fat16, LBA-mapped - db 0xc4 ; DRDOS/secured: fat16 <32M - db 0xc6 ; DRDOS/secured: fat16 >32M - db 0xcb ; DRDOS/secured: fat32 - db 0xcc ; DRDOS/secured: fat32, LBA-mapped - db 0xce ; DRDOS/secured: fat16, LBA-mapped - db 0xd4 ; Old Multiuser DOS secured: fat16 <32M - db 0xd6 ; Old Multiuser DOS secured: fat16 >32M - db 0x07 ; NTFS - db 0x27 ; NTFS, hidden - db 0x83 ; Linux native file system (ext2fs) - partition_types_end: - - - extended_types: ; list of extended partitions - db 0x05 ; DOS: extended partition - db 0x0f ; WIN95: extended partition, LBA-mapped - db 0xc5 ; DRDOS/secured: extended partition - db 0xd5 ; Old Multiuser DOS secured: extended partition - extended_types_end: - -endg - -; Partition chain used: -; MBR <--------------------- -; | | -; |-> PARTITION1 | -; |-> EXTENDED PARTITION - ;not need be second partition -; |-> PARTITION3 -; |-> PARTITION4 - -set_PARTITION_variables: -set_FAT32_variables: ;deprecated - and [problem_partition], 0 - call reserve_hd1 - call reserve_hd_channel - - pushad - - cmp dword [hdpos], 0 - je problem_hd - - xor ecx, ecx ; partition count - ;or edx,-1 ; flag for partition - xor eax, eax ; address MBR - xor ebp, ebp ; extended partition start - -new_mbr: - test ebp, ebp ; is there extended partition? (MBR or EMBR) - jnz extended_already_set; yes - xchg ebp, eax ; no. set it now - -extended_already_set: - add eax, ebp ; mbr=mbr+0, ext_part=ext_start+relat_start - mov ebx, buffer - call hd_read - cmp [hd_error], 0 - jne problem_hd - - cmp word [ebx+0x1fe], 0xaa55; is it valid boot sector? - jnz end_partition_chain - push eax ; push only one time - cmp dword [ebx+0x1be+0xc], 0; skip over empty partition - jnz test_primary_partition_0 - cmp dword [ebx+0x1be+0xc+16], 0 - jnz test_primary_partition_1 - cmp dword [ebx+0x1be+0xc+16+16], 0 - jnz test_primary_partition_2 - cmp dword [ebx+0x1be+0xc+16+16+16], 0 - jnz test_primary_partition_3 - pop eax - jmp end_partition_chain - -test_primary_partition_0: - mov al, [ebx+0x1be+4]; get primary partition type - call scan_partition_types - jnz test_primary_partition_1; no. skip over - - inc ecx - cmp ecx, [known_part]; is it wanted partition? - jnz test_primary_partition_1; no - - pop eax - ;mov edx, eax ; start sector - add eax, [ebx+0x1be+8] ; add relative start - ;mov [PARTITON_START],edx - ;push edx - mov edx, [ebx+0x1be+12] ; length - ;add edx, eax ; add length - ;dec edx ; PARTITION_END is inclusive - ;mov [PARTITION_END], edx ; note that this can be changed - ; when file system data will be available - mov cl, [ebx+0x1be+4] ; fs_type - ;mov [fs_type], dl ; save for FS recognizer (separate FAT vs NTFS) - ;pop edx - jmp hd_and_partition_ok - -test_primary_partition_1: - mov al, [ebx+0x1be+4+16]; get primary partition type - call scan_partition_types - jnz test_primary_partition_2 ; no. skip over - - inc ecx - cmp ecx, [known_part]; is it wanted partition? - jnz test_primary_partition_2 ; no - - pop eax - add eax, [ebx+0x1be+8+16] - mov edx, [ebx+0x1be+12+16] - mov cl, [ebx+0x1be+4+16] - jmp hd_and_partition_ok - - ;mov edx, eax - ;add edx, [ebx+0x1be+8+16] - ;push edx - ;add edx, [ebx+0x1be+12+16] - ;dec edx - ;mov [PARTITION_END], edx - ;mov al, [ebx+0x1be+4+16] - ;mov [fs_type], dl - ;pop edx - -test_primary_partition_2: - mov al, [ebx+0x1be+4+16+16]; get primary partition type - call scan_partition_types - jnz test_primary_partition_3 ; no. skip over - - inc ecx - cmp ecx, [known_part]; is it wanted partition? - jnz test_primary_partition_3 ; no - - pop eax - add eax, [ebx+0x1be+8+16+16] - mov edx, [ebx+0x1be+12+16+16] - mov cl, [ebx+0x1be+4+16+16] - jmp hd_and_partition_ok - ;mov edx, eax - ;add edx, [ebx+0x1be+8+16+16] - ;push edx - ;add edx, [ebx+0x1be+12+16+16] - ;dec edx - ;mov [PARTITION_END], edx - ;mov al, [ebx+0x1be+4+16+16] - ;mov [fs_type], dl - ;pop edx - -test_primary_partition_3: - mov al, [ebx+0x1be+4+16+16+16]; get primary partition type - call scan_partition_types - jnz test_ext_partition_0 ; no. skip over - - inc ecx - cmp ecx, [known_part]; is it wanted partition? - jnz test_ext_partition_0; no - - pop eax - add eax, [ebx+0x1be+8+16+16+16] - mov edx, [ebx+0x1be+12+16+16+16] - mov cl, [ebx+0x1be+4+16+16+16] - jmp hd_and_partition_ok - - ;mov edx, eax - ;add edx, [ebx+0x1be+8+16+16+16] - ;push edx - ;add edx, [ebx+0x1be+12+16+16+16] - ;dec edx - ;mov [PARTITION_END], edx - ;mov al, [ebx+0x1be+4+16+16+16] - ;mov [fs_type], dl - ;pop edx - -test_ext_partition_0: - pop eax ; просто выкидываем из стека - mov al, [ebx+0x1be+4]; get extended partition type - call scan_extended_types - jnz test_ext_partition_1 - - mov eax, [ebx+0x1be+8]; add relative start - test eax, eax ; is there extended partition? - jnz new_mbr ; yes. read it - -test_ext_partition_1: - mov al, [ebx+0x1be+4+16]; get extended partition type - call scan_extended_types - jnz test_ext_partition_2 - - mov eax, [ebx+0x1be+8+16]; add relative start - test eax, eax ; is there extended partition? - jnz new_mbr ; yes. read it - -test_ext_partition_2: - mov al, [ebx+0x1be+4+16+16]; get extended partition type - call scan_extended_types - jnz test_ext_partition_3 - - mov eax, [ebx+0x1be+8+16+16]; add relative start - test eax, eax ; is there extended partition? - jnz new_mbr ; yes. read it - -test_ext_partition_3: - mov al, [ebx+0x1be+4+16+16+16]; get extended partition type - call scan_extended_types - jnz end_partition_chain; no. end chain - - mov eax, [ebx+0x1be+8+16+16+16]; get start of extended partition - test eax, eax ; is there extended partition? - jnz new_mbr ; yes. read it - -end_partition_chain: - ;mov [partition_count],ecx - - ;cmp edx,-1 ; found wanted partition? - ;jnz hd_and_partition_ok ; yes. install it - ;jmp problem_partition_or_fat -problem_hd: - or [problem_partition], 2 - jmp return_from_part_set - - -scan_partition_types: - push ecx - mov edi, partition_types - mov ecx, partition_types_end-partition_types - cld - repne scasb ; is partition type ok? - pop ecx - ret - -scan_extended_types: - push ecx - mov edi, extended_types - mov ecx, extended_types_end-extended_types - cld - repne scasb ; is it extended partition? - pop ecx - ret - -problem_fat_dec_count: ; bootsector is missing or another problem -; dec [partition_count] ; remove it from partition_count - -problem_partition_or_fat: - or [problem_partition], 1 - -return_from_part_set: - popad - ;mov [fs_type],0 - call free_hd_channel - mov [hd1_status], 0 ; free - ret - -hd_and_partition_ok: - -;eax = PARTITION_START edx=PARTITION_LENGTH cl=fs_type - mov [fs_type], cl - ;mov eax,edx - mov [PARTITION_START], eax - add edx, eax - dec edx - mov [PARTITION_END], edx - - ; mov edx, [PARTITION_END] - ; sub edx, eax - ; inc edx ; edx = length of partition зачем оно нам?? - -; mov [hd_setup],1 - mov ebx, buffer - call hd_read ; read boot sector of partition - cmp [hd_error], 0 - jz boot_read_ok - cmp [fs_type], 7 - jnz problem_fat_dec_count -; NTFS duplicates bootsector: -; NT4/2k/XP+ saves bootsector copy in the end of disk -; NT 3.51 saves bootsector copy in the middle of disk - and [hd_error], 0 - mov eax, [PARTITION_END] - call hd_read - cmp [hd_error], 0 - jnz @f - call ntfs_test_bootsec - jnc boot_read_ok -@@: - and [hd_error], 0 - mov eax, edx - shr eax, 1 - add eax, [PARTITION_START] - call hd_read - cmp [hd_error], 0 - jnz problem_fat_dec_count ; no chance... -boot_read_ok: - -; if we are running on NTFS, check bootsector - - call ntfs_test_bootsec ; test ntfs - jnc ntfs_setup - - call ext2_test_superblock ; test ext2fs - jnc ext2_setup - - mov eax, [PARTITION_START] ;ext2 test changes [buffer] - call hd_read - 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/trunk/kernel.asm b/kernel/trunk/kernel.asm index 6cdaa5ff78..d24d1dbba8 100644 --- a/kernel/trunk/kernel.asm +++ b/kernel/trunk/kernel.asm @@ -1,6 +1,6 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; -;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. +;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;; PROGRAMMING: ;; Ivan Poddubny ;; Marat Zakiyanov (Mario79) @@ -356,6 +356,13 @@ high_code: mov ecx, application_table_mutex call mutex_init + mov ecx, ide_mutex + call mutex_init + mov ecx, ide_channel1_mutex + call mutex_init + mov ecx, ide_channel2_mutex + call mutex_init + ; SAVE REAL MODE VARIABLES xor eax, eax mov ax, [BOOT_VARS + BOOT_IDE_PI_16] @@ -1656,76 +1663,17 @@ endg ret nsyse5: - sub ebx, 2 ; HD BASE + sub ebx, 2 ; HD BASE - obsolete jnz nsyse7 - test ecx, ecx - jz nosethd - - cmp ecx, 4 - ja nosethd - mov [hd_base], cl - - cmp ecx, 1 - jnz noprmahd - mov eax, [hd_address_table] - mov [hdbase], eax ;0x1f0 - and dword [hdid], 0x0 - mov dword [hdpos], ecx -; call set_FAT32_variables - noprmahd: - - cmp ecx, 2 - jnz noprslhd - mov eax, [hd_address_table] - mov [hdbase], eax ;0x1f0 - mov [hdid], 0x10 - mov dword [hdpos], ecx -; call set_FAT32_variables - noprslhd: - - cmp ecx, 3 - jnz nosemahd - mov eax, [hd_address_table+16] - mov [hdbase], eax ;0x170 - and dword [hdid], 0x0 - mov dword [hdpos], ecx -; call set_FAT32_variables - nosemahd: - - cmp ecx, 4 - jnz noseslhd - mov eax, [hd_address_table+16] - mov [hdbase], eax ;0x170 - mov [hdid], 0x10 - mov dword [hdpos], ecx -; call set_FAT32_variables - noseslhd: - call reserve_hd1 - call reserve_hd_channel - call free_hd_channel - and dword [hd1_status], 0 ; free nosethd: ret -iglobal -hd_base db 0 -endg - nsyse7: -; cmp eax,8 ; HD PARTITION +; cmp eax,8 ; HD PARTITION - obsolete dec ebx jnz nsyse8 - mov [fat32part], ecx -; call set_FAT32_variables - call reserve_hd1 - call reserve_hd_channel - call free_hd_channel -; pusha - call choice_necessity_partition_1 -; popa - and dword [hd1_status], 0 ; free ret nsyse8: @@ -1826,7 +1774,7 @@ ngsyse5: ; cmp eax,7 sub ebx, 2 jnz ngsyse7 - movzx eax, [hd_base] + xor eax, eax mov [esp+32], eax ret ngsyse7: