Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 3741 → Rev 3742

/kernel/trunk/blkdev/cd_drv.inc
768,6 → 768,8
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
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
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
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
/kernel/trunk/blkdev/disk.inc
186,9 → 186,9
; 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
jz .nofree
.freeloop:
lodsd
call free
mov ecx, [eax+PARTITION.FSUserFunctions]
call dword [ecx]
dec edi
jnz .freeloop
.nofree:
727,7 → 728,7
; 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
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
; 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,27 → 978,34
virtual at ebp+8
.start dq ?
.length dq ?
.disk dd ?
end virtual
; 1. Read the bootsector to the buffer.
; When disk_add_partition is called, ebx contains a pointer to
; a two-sectors-sized buffer. This function saves ebx in the stack
; a three-sectors-sized buffer. This function saves ebx in the stack
; immediately before ebp.
virtual at ebp-4
.buffer dd ?
end virtual
; 1. Read the bootsector to the buffer.
mov al, DISKFUNC.read
mov ebx, [.buffer]
add ebx, 512
push 1
stdcall disk_call_driver, ebx, dword [.start], dword [.start+4], esp
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
1001,22 → 1012,30
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
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
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:
/kernel/trunk/blkdev/disk_cache.inc
14,19 → 14,7
; 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
; 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
; 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
; 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
; 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
/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
; 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
;-----------------------------------------------------------
and [hd_error], 0
push ecx esi edi ; scan cache
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:
 
call calculate_cache
add esi, 8
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:
 
mov edi, 1
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
 
hdreadcache:
cmp dword [esi+4], 0 ; empty
je nohdcache
uglobal
ide_mutex MUTEX
ide_channel1_mutex MUTEX
ide_channel2_mutex MUTEX
endg
 
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
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
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
jmp @f
.nodma:
call hd_read_pio
jmp @f
.bios:
call bd_read
@@:
cmp [hd_error], 0
jne return_01
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
 
call calculate_cache_1
lea esi, [edi*8+esi]
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
 
mov [esi], eax ; sector number
mov dword [esi+4], 1 ; hd read - mark as same as in hd
; 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
 
yeshdcache:
mov esi, edi
shl esi, 9
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
 
push eax
call calculate_cache_2
add esi, eax
pop eax
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
 
mov edi, ebx
mov ecx, 512/4
cld
rep movsd ; move data
; 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
 
return_01:
pop edi esi ecx
ret
;-----------------------------------------------------------------------------
align 4
; input: eax = sector, edi -> buffer
; output: edi = edi + 512
hd_read_pio:
push eax edx
 
184,19 → 473,11
 
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
203,61 → 484,7
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
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
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
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
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
 
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
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
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
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
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
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
@@:
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
;-----------------------------------------------------------------------------
/kernel/trunk/blkdev/ide_cache.inc
23,546 → 23,7
 
$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:
;-----------------------------------------------------------
; find empty or read slot, flush cache if next 10% is used by write
/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,86 → 8,69
$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
jmp yes_sys_on_hd
 
search_and_read_image:
call set_FAT32_variables
mov edx, bootpath
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 image_present
mov edx, bootpath2
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 image_present
ret
image_present:
mov [image_retrieved], 1
ret
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
 
iglobal
align 4
96,8 → 79,16
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
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
/kernel/trunk/core/sys32.inc
578,11 → 578,6
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
/kernel/trunk/data32.inc
164,8 → 164,6
ud_user_message db 'Error: unsupported processor instruction',0
end if
 
bootpath db '/KOLIBRI '
bootpath2 db 0
vmode db '/sys/drivers/VMODE.MDR',0
;vrr_m db 'VRR_M',0
kernel_file db 'KERNEL MNT'
/kernel/trunk/detect/getcache.inc
37,64 → 37,26
mov [hdd_appl_data], 1;al
mov [cd_appl_data], 1
mov ch, [DRIVE_DATA+1]
mov cl, ch
and cl, 11b
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
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
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
/kernel/trunk/detect/sear_par.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 ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7,159 → 7,133
 
$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
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
@@:
inc [known_part]
jmp search_partitions_ide0_1
 
search_partitions_ide1:
; 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
jz @f
push 'hd1'
mov eax, esp
mov edx, hd1_data
call ide_disk_add
mov [DRIVE_DATA+3], al
pop ecx
@@:
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
; 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
@@:
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
; 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
@@:
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
; 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'
@@:
inc [known_part]
jmp search_partitions_bd
end_search_partitions_bd:
pop ecx
inc [hdpos]
loop start_search_partitions_bd
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
; 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
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
ret
endp
 
end_search_partitions:
 
/kernel/trunk/fs/part_set.inc
File deleted
Property changes:
Deleted: svn:eol-style
-native
\ No newline at end of property
Deleted: svn:keywords
-Rev
\ No newline at end of property
/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,14 → 177,50
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
cmp [ebx + EXT2_SB_STRUC.magic], 0xEF53
198,27 → 234,41
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
 
push 512
call kernel_alloc ; mem for superblock
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
 
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
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
;===================================================================
;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
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
;===================================================================
;получает адрес 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,19 → 481,19
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
417,7 → 500,7
 
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
.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
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
 
.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
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
;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
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
;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
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
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,14 → 677,14
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)
 
615,26 → 691,26
.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
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
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
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
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,15 → 809,15
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 ; дошли
747,6 → 824,7
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
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
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
;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
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
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
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
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
 
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
pop ecx ;счетчик блоков, который хранился в стеке
@@:
pop ebx ;количество считанных байт
call ext2_unlock
pop eax ; 1 или 0 - достигли ли конца файла
test eax, eax
jz @F
1035,17 → 1105,21
.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
 
;========================
;Ищет 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
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
 
.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
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
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
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
/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,8 → 58,7
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
121,6 → 120,7
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,10 → 138,8
; 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
148,7 → 146,7
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
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
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
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
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
769,42 → 766,6
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
; in: esi+[esp+4] = name
944,43 → 905,6
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
; in: esi+[esp+4] = name
1377,52 → 1301,6
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
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,52 → 1866,17
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
jmp fat_Write.ret0
 
fs_HdWrite:
cmp [fs_type], 16
jz @f
cmp [fs_type], 32
jz @f
cmp [fs_type], 1
jz ntfs_HdWrite
cmp [fs_type], 2
jz ext2_HdWrite
push ERROR_UNKNOWN_FS
jmp .ret0
@@:
sub ebx, 4
push ebp
mov ebp, [fs_dependent_data_start.partition]
call fat_Write
pop ebp
ret
 
;----------------------------------------------------------------
; fat_Write - FAT16/32 implementation of writing to file
; in: ebp = pointer to FAT structure
2051,7 → 1894,7
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
pop edi
push ERROR_END_OF_FILE
call fat_unlock
jmp fs_HdWrite.ret0
jmp .ret0
@@:
mov ecx, [ebx+12]
mov edx, [ebx+16]
2362,39 → 2205,6
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
; in: esi+[esp+4] = name
2634,25 → 2444,6
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
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
2742,36 → 2514,6
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
; in: esi+[esp+4] = name
/kernel/trunk/fs/fs.inc
318,86 → 318,6
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,28 → 336,8
 
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]
mov eax, 5 ; file not found
542,7 → 442,10
 
lbarl1:
 
call reserve_hd1
pushad
mov ecx, ide_mutex
call mutex_lock
popad
 
push eax
push ecx
633,6 → 536,10
mov [hd_error], 0
mov [hd1_status], 0
add esp, 2*4
pushad
mov ecx, ide_mutex
call mutex_unlock
popad
 
ret
 
/kernel/trunk/fs/fs_lfn.inc
42,18 → 42,6
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
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
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
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
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
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
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<N>/... - 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<N>
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
/kernel/trunk/fs/iso9660.inc
42,26 → 42,18
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
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
/kernel/trunk/fs/ntfs.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 ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7,7 → 7,65
 
$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
; out: CF set <=> invalid
93,25 → 151,66
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
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,21 → 232,21
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
154,11 → 253,10
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
@@:
; $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
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
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,7 → 326,7
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
224,25 → 333,24
; 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
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
 
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 eax ecx
add eax, [PARTITION_START]
mov ecx, [ntfs_data.frs_size]
push ecx
mov ebx, [ebp+NTFS.frs_buffer]
push ebx
mov ecx, [ebp+NTFS.frs_size]
shr ecx, 9
mov ebx, [ntfs_data.frs_buffer]
push ebx
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
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
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,6 → 510,7
.errread:
pop ecx
.errret:
mov [esp+28], eax
stc
popad
ret
402,17 → 517,16
.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
; 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,30 → 564,30
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
481,13 → 594,14
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:
494,49 → 608,49
; 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
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,24 → 705,25
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
613,30 → 730,28
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
643,43 → 758,43
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
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
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,34 → 832,34
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
751,51 → 866,60
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,58 → 930,57
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
jnz .errret
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 [ntfs_cur_size], ecx
mov eax, [ntfs_data.frs_buffer]
mov [ntfs_cur_buf], eax
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 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]
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, [ntfs_data.frs_buffer]
mov eax, [ebp+NTFS.frs_buffer]
cmp dword [eax], 'FILE'
jnz .errret
push ebx
864,18 → 987,18
mov ebx, eax
call ntfs_restore_usa_frs
pop ebx
setnc al
movzx eax, al
jc .errret
.ret:
pop edx ecx
ret
.err:
.errret:
pop edx ecx
.errret:
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
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
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
.notfound:
popad
stc
ret
ret 4
.found:
cmp byte [edi], 0
jz .done
1106,7 → 1232,7
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
1113,29 → 1239,22
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
1142,17 → 1261,20
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,9 → 1282,7
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
1169,23 → 1289,29
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
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,14 → 1442,14
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
1332,53 → 1456,51
@@:
; 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
1385,13 → 1507,14
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 <output>, dd <flags>
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
.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
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
@@:
mov [esp+1Ch], eax
mov [esp+10h], ebx
call ntfs_unlock
popad
ret
 
1517,14 → 1642,14
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
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
 
/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
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
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
; cmp eax,7
sub ebx, 2
jnz ngsyse7
movzx eax, [hd_base]
xor eax, eax
mov [esp+32], eax
ret
ngsyse7: