Subversion Repositories Kolibri OS

Compare Revisions

Ignore whitespace Rev 2381 → Rev 2382

/kernel/branches/net/fs/ext2.inc
0,0 → 1,1318
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2010. 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 ;;
;; ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision: 2381 $
 
EXT2_BAD_INO = 1
EXT2_ROOT_INO = 2
EXT2_ACL_IDX_INO = 3
EXT2_ACL_DATA_INO = 4
EXT2_BOOT_LOADER_INO= 5
EXT2_UNDEL_DIR_INO = 6
 
;type inode
EXT2_S_IFREG = 0x8000
EXT2_S_IFDIR = 0x4000
;user inode right's
EXT2_S_IRUSR = 0x0100
EXT2_S_IWUSR = 0x0080
EXT2_S_IXUSR = 0x0040
;group inode right's
EXT2_S_IRGRP = 0x0020
EXT2_S_IWGRP = 0x0010
EXT2_S_IXGRP = 0x0008
;other inode right's
EXT2_S_IROTH = 0x0004
EXT2_S_IWOTH = 0x0002
EXT2_S_IXOTH = 0x0001
EXT2_777_MODE = EXT2_S_IROTH or EXT2_S_IWOTH or EXT2_S_IXOTH or \
EXT2_S_IRGRP or EXT2_S_IWGRP or EXT2_S_IXGRP or \
EXT2_S_IRUSR or EXT2_S_IWUSR or EXT2_S_IXUSR
 
EXT2_FT_REG_FILE = 1 ;это файл, запись в родительском каталоге
EXT2_FT_DIR = 2 ;это папка
 
FS_FT_HIDDEN = 2
FS_FT_DIR = 0x10 ;это папка
FS_FT_ASCII = 0 ;имя в ascii
FS_FT_UNICODE = 1 ;имя в unicode
 
EXT2_FEATURE_INCOMPAT_FILETYPE = 0x0002
 
uglobal
EXT2_files_in_folder dd ? ;всего файлов в папке
EXT2_read_in_folder dd ? ;сколько файлов "считали"
EXT2_end_block dd ? ;конец очередного блока папки
EXT2_counter_blocks dd ?
EXT2_filename rb 256
EXT2_parent_name rb 256
EXT2_name_len dd ?
endg
 
struct EXT2_INODE_STRUC
i_mode dw ?
i_uid dw ?
i_size dd ?
i_atime dd ?
i_ctime dd ?
i_mtime dd ?
i_dtime dd ?
i_gid dw ?
i_links_count dw ?
i_blocks dd ?
i_flags dd ?
i_osd1 dd ?
i_block rd 15
i_generation dd ?
i_file_acl dd ?
i_dir_acl dd ?
i_faddr dd ?
i_osd2 dd ? ; 1..12
ends
 
struct EXT2_DIR_STRUC
inode dd ?
rec_len dw ?
name_len db ?
file_type db ?
name db ? ; 0..255
ends
 
struct EXT2_BLOCK_GROUP_DESC
block_bitmap dd ?
inode_bitmap dd ?
inode_table dd ?
free_blocks_count dw ?
free_inodes_count dw ?
used_dirs_count dw ?
ends
 
struct EXT2_SB_STRUC
inodes_count dd ? ;+0
blocks_count dd ? ;+4
r_block_count dd ? ;+8
free_block_count dd ? ;+12
free_inodes_count dd ? ;+16
first_data_block dd ? ;+20
log_block_size dd ? ;+24
log_frag_size dd ? ;+28
blocks_per_group dd ? ;+32
frags_per_group dd ? ;+36
inodes_per_group dd ? ;+40
mtime dd ? ;+44
wtime dd ? ;+48
mnt_count dw ? ;+52
max_mnt_count dw ? ;+54
magic dw ? ;+56
state dw ? ;+58
errors dw ? ;+60
minor_rev_level dw ? ;+62
lastcheck dd ? ;+64
check_intervals dd ? ;+68
creator_os dd ? ;+72
rev_level dd ? ;+76
def_resuid dw ? ;+80
def_resgid dw ? ;+82
first_ino dd ? ;+84
inode_size dw ? ;+88
block_group_nr dw ? ;+90
feature_compat dd ? ;+92
feature_incompat dd ? ;+96
feature_ro_compat dd ? ;+100
uuid rb 16 ;+104
volume_name rb 16 ;+120
last_mounted rb 64 ;+136
algo_bitmap dd ? ;+200
prealloc_blocks db ? ;+204
preallock_dir_blocks db ? ;+205
dw ? ;+206 alignment
journal_uuid rb 16 ;+208
journal_inum dd ? ;+224
journal_dev dd ? ;+228
last_orphan dd ? ;+232
hash_seed rd 4 ;+236
def_hash_version db ? ;+252
rb 3 ;+253 reserved
default_mount_options dd ? ;+256
first_meta_bg dd ? ;+260
ends
 
ext2_test_superblock:
cmp [fs_type], 0x83
jne .no
 
mov eax, [PARTITION_START]
add eax, 2 ;superblock start at 1024b
call hd_read
 
cmp dword [ebx+24], 3 ;s_block_size 0,1,2,3
ja .no
cmp word [ebx+56], 0xEF53 ;s_magic
jne .no
cmp word [ebx+58], 1 ;s_state (EXT_VALID_FS=1)
jne .no
mov eax, [ebx+96]
test eax, EXT2_FEATURE_INCOMPAT_FILETYPE
jz .no
test eax, not EXT2_FEATURE_INCOMPAT_FILETYPE
jnz .no
 
; OK, this is correct EXT2 superblock
clc
ret
.no:
; No, this superblock isn't EXT2
stc
ret
 
ext2_setup:
mov [fs_type], 2
 
push 512
call kernel_alloc ; mem for superblock
mov esi, ebx
mov edi, eax
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]
dec eax
xor edx, edx
div [ebx + EXT2_SB_STRUC.blocks_per_group]
inc eax
mov [ext2_data.groups_count], eax
 
mov ecx, [ebx+24]
inc ecx
mov [ext2_data.log_block_size], ecx ; 1, 2, 3, 4 equ 1kb, 2kb, 4kb, 8kb
 
mov eax, 1
shl eax, cl
mov [ext2_data.count_block_in_block], eax
 
shl eax, 7
mov [ext2_data.count_pointer_in_block], eax
mov edx, eax ; потом еще квадрат найдем
 
shl eax, 2
mov [ext2_data.block_size], eax
 
push eax eax ; 2 kernel_alloc
 
mov eax, edx
mul edx
mov [ext2_data.count_pointer_in_block_square], eax
 
call kernel_alloc
mov [ext2_data.ext2_save_block], eax ; and for temp block
call kernel_alloc
mov [ext2_data.ext2_temp_block], eax ; and for get_inode proc
 
movzx ebp, word [ebx+88]
mov ecx, [ebx+32]
mov edx, [ebx+40]
 
mov [ext2_data.inode_size], ebp
mov [ext2_data.blocks_per_group], ecx
mov [ext2_data.inodes_per_group], edx
 
push ebp ebp ebp ;3 kernel_alloc
call kernel_alloc
mov [ext2_data.ext2_save_inode], eax
call kernel_alloc
mov [ext2_data.ext2_temp_inode], eax
call kernel_alloc
mov [ext2_data.root_inode], eax
 
mov ebx, eax
mov eax, EXT2_ROOT_INO
call ext2_get_inode ; read root inode
 
jmp return_from_part_set
 
;==================================================================
;in: eax = i_block
; ebx = pointer to return memory
ext2_get_block:
push eax ebx ecx
mov ecx, [ext2_data.log_block_size]
shl eax, cl
add eax, [PARTITION_START]
mov ecx, [ext2_data.count_block_in_block]
@@:
call hd_read
inc eax
add ebx, 512
loop @B
pop ecx ebx eax
ret
;===================================================================
; in: ecx = номер блока в inode (0..)
; ebp = адрес inode
; out: ecx = адрес очередного блока
ext2_get_inode_block:
cmp ecx, 12 ; 0..11 - direct block address
jb .get_direct_block
 
sub ecx, 12
cmp ecx, [ext2_data.count_pointer_in_block] ; 12.. - indirect block
jb .get_indirect_block
 
sub ecx, [ext2_data.count_pointer_in_block]
cmp ecx, [ext2_data.count_pointer_in_block_square]
jb .get_double_indirect_block
 
sub ecx, [ext2_data.count_pointer_in_block_square]
;.get_triple_indirect_block:
push eax edx ebx
 
mov eax, [ebx + EXT2_INODE_STRUC.i_block + 14*4]
mov ebx, [ext2_data.ext2_temp_block]
call ext2_get_block
 
xor edx, edx
mov eax, ecx
div [ext2_data.count_pointer_in_block_square]
 
;eax - номер в полученном блоке edx - номер дальше
mov eax, [ebx + eax*4]
call ext2_get_block
 
mov eax, edx
jmp @F
 
.get_double_indirect_block:
push eax edx ebx
 
mov eax, [ebp + EXT2_INODE_STRUC.i_block + 13*4]
mov ebx, [ext2_data.ext2_temp_block]
call ext2_get_block
 
mov eax, ecx
@@:
xor edx, edx
div [ext2_data.count_pointer_in_block]
 
mov eax, [ebx + eax*4]
call ext2_get_block
mov ecx, [ebx + edx*4]
 
pop ebx edx eax
ret
 
.get_indirect_block:
push eax ebx
mov eax, [ebp + EXT2_INODE_STRUC.i_block + 12*4]
mov ebx, [ext2_data.ext2_temp_block]
call ext2_get_block
 
mov ecx, [ebx + ecx*4]
pop ebx eax
ret
 
.get_direct_block:
mov ecx, dword [ebp + EXT2_INODE_STRUC.i_block + ecx*4]
ret
 
;===================================================================
;get content inode by num
;in: eax = inode_num
; ebx = address of inode content
ext2_get_inode:
 
pushad
mov edi, ebx ;сохраним адрес inode
dec eax
xor edx, edx
div [ext2_data.inodes_per_group]
 
push edx ;locale num in group
 
mov edx, 32
mul edx ; address block_group in global_desc_table
 
; в eax - смещение группы с inode-ом относительно начала глобальной дескрипторной таблицы
; найдем блок в котором он находится
 
div [ext2_data.block_size]
mov ecx, [ext2_data.sb]
add eax, [ecx + EXT2_SB_STRUC.first_data_block]
inc eax
mov ebx, [ext2_data.ext2_temp_block]
call ext2_get_block
 
add ebx, edx ; локальный номер в блоке
mov eax, [ebx+8] ; номер блока - в терминах ext2
 
mov ecx, [ext2_data.log_block_size]
shl eax, cl
add eax, [PARTITION_START] ; а старт раздела - в терминах hdd (512)
 
;eax - указывает на таблицу inode-ов на hdd
mov esi, eax ;сохраним его пока в esi
 
; прибавим локальный адрес inode-а
pop eax ; index
mov ecx, [ext2_data.inode_size]
mul ecx ; (index * inode_size)
mov ebp, 512
div ebp ;поделим на размер блока
 
add eax, esi ;нашли адрес блока для чтения
mov ebx, [ext2_data.ext2_temp_block]
call hd_read
 
mov esi, edx ;добавим "остаток"
add esi, ebx ;к адресу
; mov ecx, [ext2_data.inode_size]
rep movsb ;копируем inode
popad
ret
 
;----------------------------------------------------------------
; in: esi -> children
; ebx -> pointer to dir block
; out: esi -> name without parent or not_changed
; ebx -> dir_rec of inode children or trash
ext2_test_block_by_name:
push eax ecx edx edi
 
mov edx, ebx
add edx, [ext2_data.block_size] ;запомним конец блока
 
.start_rec:
cmp [ebx + EXT2_DIR_STRUC.inode], 0
jz .next_rec
 
push esi
movzx ecx, [ebx + EXT2_DIR_STRUC.name_len]
mov edi, EXT2_filename
lea esi, [ebx + EXT2_DIR_STRUC.name]
 
call utf8toansi_str
mov ecx, edi
sub ecx, EXT2_filename ;кол-во байт в получившейся строке
 
mov edi, EXT2_filename
mov esi, [esp]
@@:
jecxz .test_find
dec ecx
 
lodsb
call char_toupper
 
mov ah, [edi]
inc edi
xchg al, ah
call char_toupper
cmp al, ah
je @B
@@: ;не подошло
pop esi
.next_rec:
movzx eax, [ebx + EXT2_DIR_STRUC.rec_len]
add ebx, eax ;к след. записи
cmp ebx, edx ;проверим конец ли
jb .start_rec
jmp .ret
 
.test_find:
cmp byte [esi], 0
je .find ;нашли конец
cmp byte [esi], '/'
jne @B
inc esi
.find:
pop eax ;удаляем из стека сохраненое значение
.ret:
pop edi edx ecx eax
ret
 
;----------------------------------------------------------------
;
; ext2_HdReadFolder - read disk folder
;
; 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:
cmp byte [esi], 0
jz .doit
 
push ecx ebx
call ext2_find_lfn
jnc .doit2
pop ebx
.not_found:
pop ecx
or ebx, -1
mov eax, ERROR_FILE_NOT_FOUND
ret
 
.doit:
mov ebp, [ext2_data.root_inode]
push ecx
jmp @F
.doit2:
pop ebx
test [ebp + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR
jz .not_found
@@:
xor eax, eax
mov edi, edx
mov ecx, 32/4
rep stosd ; fill header zero
pop edi ; edi = число блоков для чтения
push edx ebx
 
;--------------------------------------------- final step
and [EXT2_read_in_folder], 0
and [EXT2_files_in_folder], 0
 
mov eax, [ebp + EXT2_INODE_STRUC.i_blocks]
mov [EXT2_counter_blocks], eax
 
add edx, 32 ; (header pointer in stack) edx = current mem for return
xor esi, esi ; esi = номер блока по порядку
 
.new_block_folder: ;reserved label
mov ecx, esi ; получим номер блока
call ext2_get_inode_block
 
mov eax, ecx
mov ebx, [ext2_data.ext2_save_block]
call ext2_get_block ; и считываем блок с hdd
 
mov eax, ebx ; eax = current dir record
add ebx, [ext2_data.block_size]
mov [EXT2_end_block], ebx ; запомним конец очередного блока
 
pop ecx
mov ecx, [ecx] ; ecx = first wanted (flags ommited)
 
.find_wanted_start:
jecxz .find_wanted_end
.find_wanted_cycle:
cmp [eax + EXT2_DIR_STRUC.inode], 0 ; if (inode = 0) => not used
jz @F
inc [EXT2_files_in_folder]
dec ecx
@@:
movzx ebx, [eax+EXT2_DIR_STRUC.rec_len]
 
cmp ebx, 12 ; минимальная длина записи
jb .end_error
test ebx, 0x3 ; длина записи должна делиться на 4
jnz .end_error
 
add eax, ebx ; к следующей записи
cmp eax, [EXT2_end_block] ; проверяем "конец"
jb .find_wanted_start
 
push .find_wanted_start
.end_block: ;вылетили из цикла
mov ebx, [ext2_data.count_block_in_block]
sub [EXT2_counter_blocks], ebx
jbe .end_dir
 
inc esi ;получаем новый блок
push ecx
mov ecx, esi
call ext2_get_inode_block
mov eax, ecx
mov ebx, [ext2_data.ext2_save_block]
call ext2_get_block
pop ecx
mov eax, ebx
add ebx, [ext2_data.block_size]
mov [EXT2_end_block], ebx
ret ; опять в цикл
 
.wanted_end:
loop .find_wanted_cycle ; ecx = -1
 
.find_wanted_end:
mov ecx, edi
.wanted_start: ; ищем first_wanted+count
jecxz .wanted_end
cmp [eax + EXT2_DIR_STRUC.inode], 0 ; if (inode = 0) => not used
jz .empty_rec
inc [EXT2_files_in_folder]
inc [EXT2_read_in_folder]
 
mov edi, edx
push eax ecx
xor eax, eax
mov ecx, 40 / 4
rep stosd
pop ecx eax
 
push eax esi edx ;получим inode
mov eax, [eax + EXT2_DIR_STRUC.inode]
mov ebx, [ext2_data.ext2_temp_inode]
call ext2_get_inode
 
lea edi, [edx + 8]
 
mov eax, [ebx + EXT2_INODE_STRUC.i_ctime] ; переведем время в ntfs формат
xor edx, edx
add eax, 3054539008 ;(369 * 365 + 89) * 24 * 3600
adc edx, 2
call ntfs_datetime_to_bdfe.sec
 
mov eax, [ebx + EXT2_INODE_STRUC.i_atime]
xor edx, edx
add eax, 3054539008
adc edx, 2
call ntfs_datetime_to_bdfe.sec
 
mov eax, [ebx + EXT2_INODE_STRUC.i_mtime]
xor edx, edx
add eax, 3054539008
adc edx, 2
call ntfs_datetime_to_bdfe.sec
 
pop edx ; пока достаем только буфер
test [ebx + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR ; для папки размер
jnz @F ; не возвращаем
 
mov eax, [ebx + EXT2_INODE_STRUC.i_size] ;low size
stosd
mov eax, [ebx + EXT2_INODE_STRUC.i_dir_acl] ;high size
stosd
xor dword [edx], FS_FT_DIR
@@:
xor dword [edx], FS_FT_DIR
pop esi eax
 
or dword [edx+4], FS_FT_ASCII ; symbol type in name
 
;теперь скопируем имя, сконвертировав из UTF-8 в CP866
push eax ecx esi
movzx ecx, [eax + EXT2_DIR_STRUC.name_len]
lea edi, [edx + 40]
lea esi, [eax + EXT2_DIR_STRUC.name]
call utf8toansi_str
pop esi ecx eax
and byte [edi], 0
 
cmp byte [edx + 40], '.'
jne @F
or dword [edx], FS_FT_HIDDEN
@@:
 
add edx, 40 + 264 ; go to next record
dec ecx ; если запись пустая ecx не надо уменьшать
.empty_rec:
movzx ebx, [eax + EXT2_DIR_STRUC.rec_len]
cmp ebx, 12 ; минимальная длина записи
jb .end_error
test ebx, 0x3 ; длина записи должна делиться на 4
jnz .end_error
 
add eax, ebx
cmp eax, [EXT2_end_block]
jb .wanted_start
 
push .wanted_start ; дошли до конца очередного блока
jmp .end_block
 
.end_dir:
pop eax ; мусор (адрес возврата в цикл)
.end_error:
pop edx
mov ebx, [EXT2_read_in_folder]
mov ecx, [EXT2_files_in_folder]
mov dword [edx], 1 ;version
xor eax, eax
mov [edx+4], ebx
mov [edx+8], ecx
lea edi, [edx + 12]
mov ecx, 20 / 4
rep stosd
ret
;====================== end ext2_HdReadFolder
utf8toansi_str:
; convert UTF-8 string to ASCII-string (codepage 866)
; in: ecx=length source, esi->source, edi->buffer
; destroys: eax,esi,edi
jecxz .ret
.start:
lodsw
cmp al, 0x80
jb .ascii
 
xchg al, ah ; big-endian
cmp ax, 0xd080
jz .yo1
cmp ax, 0xd191
jz .yo2
cmp ax, 0xd090
jb .unk
cmp ax, 0xd180
jb .rus1
cmp ax, 0xd190
jb .rus2
.unk:
mov al, '_'
jmp .doit
.yo1:
mov al, 0xf0 ; Ё capital
jmp .doit
.yo2:
mov al, 0xf1 ; ё small
jmp .doit
.rus1:
sub ax, 0xd090 - 0x80
jmp .doit
.rus2:
sub ax, 0xd18f - 0xEF
.doit:
stosb
sub ecx, 2
ja .start
ret
 
.ascii:
stosb
dec esi
dec ecx
jnz .start
.ret:
ret
 
;----------------------------------------------------------------
;
; ext2_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:
cmp byte [esi], 0
jnz @F
 
.this_is_nofile:
or ebx, -1
mov eax, ERROR_ACCESS_DENIED
ret
 
@@:
push ecx ebx
call ext2_find_lfn
pop ebx ecx
jnc .doit
;.not_found:
or ebx, -1
mov eax, ERROR_FILE_NOT_FOUND
ret
 
.doit:
test [ebp + EXT2_INODE_STRUC.i_mode], EXT2_S_IFREG
jz .this_is_nofile
 
;-----------------------------------------------------------------------------final step
mov edi, edx ; edi = pointer to return mem
mov esi, ebx ; esi = pointer to first_wanted
 
;///// сравним хватит ли нам файла или нет
mov ebx, [esi+4]
mov eax, [esi] ; ebx : eax - стартовый номер байта
 
cmp [ebp + EXT2_INODE_STRUC.i_dir_acl], ebx
ja .size_great
jb .size_less
 
cmp [ebp + EXT2_INODE_STRUC.i_size], eax
ja .size_great
 
.size_less:
xor ebx, ebx
mov eax, ERROR_END_OF_FILE
ret
.size_great:
add eax, ecx ;add to first_wanted кол-во байт для чтения
adc ebx, 0
 
cmp [ebp + EXT2_INODE_STRUC.i_dir_acl], ebx
ja .size_great_great
jb .size_great_less
cmp [ebp + EXT2_INODE_STRUC.i_size], eax
jae .size_great_great ; а если равно, то не важно куда
 
.size_great_less:
or [EXT2_files_in_folder], 1 ;читаем по границе размера
mov ecx, [ebp + EXT2_INODE_STRUC.i_size]
sub ecx, [esi] ;(размер - старт)
jmp @F
 
.size_great_great:
and [EXT2_files_in_folder], 0 ;читаем столько сколько запросили
 
@@:
push ecx ;save for return
test esi, esi
jz .zero_start
 
;пока делаем п..ц криво =)
mov edx, [esi+4]
mov eax, [esi]
div [ext2_data.block_size]
 
mov [EXT2_counter_blocks], eax ;номер блока запоминаем
 
push ecx
mov ecx, eax
call ext2_get_inode_block
mov ebx, [ext2_data.ext2_save_block]
mov eax, ecx
call ext2_get_block
pop ecx
add ebx, edx
 
neg edx
add edx, [ext2_data.block_size] ;block_size - стартовый байт = сколько байт 1-го блока
cmp ecx, edx
jbe .only_one_block
 
mov eax, ecx
sub eax, edx
mov ecx, edx
 
mov esi, ebx
rep movsb ;кусок 1-го блока
jmp @F
 
.zero_start:
mov eax, ecx
;теперь в eax кол-во оставшихся байт для чтения
@@:
mov ebx, edi ;чтение блока прям в ->ebx
xor edx, edx
div [ext2_data.block_size] ;кол-во байт в последнем блоке (остаток) в edx
mov edi, eax ;кол-во целых блоков в edi
@@:
test edi, edi
jz .finish_block
inc [EXT2_counter_blocks]
mov ecx, [EXT2_counter_blocks]
call ext2_get_inode_block
 
mov eax, ecx ;а ebx уже забит нужным значением
call ext2_get_block
add ebx, [ext2_data.block_size]
 
dec edi
jmp @B
 
.finish_block: ;в edx - кол-во байт в последнем блоке
test edx, edx
jz .end_read
 
mov ecx, [EXT2_counter_blocks]
inc ecx
call ext2_get_inode_block
 
mov edi, ebx
mov eax, ecx
mov ebx, [ext2_data.ext2_save_block]
call ext2_get_block
 
mov ecx, edx
 
.only_one_block:
mov esi, ebx
rep movsb ;кусок last блока
.end_read:
pop ebx
cmp [EXT2_files_in_folder], 0
jz @F
 
mov eax, ERROR_END_OF_FILE
ret
@@:
xor eax, eax
ret
;========================
;in : esi -> name not save: eax ebx ecx
;out: ebp -> inode cf=0
; ebp -> trash cf=1
ext2_find_lfn:
mov ebp, [ext2_data.root_inode]
.next_folder:
or [EXT2_counter_blocks], -1 ;счетчик блоков папки cur block of inode
mov eax, [ebp + EXT2_INODE_STRUC.i_blocks] ;убывающий счетчик блоков
add eax, [ext2_data.count_block_in_block]
mov [EXT2_end_block], eax
.next_block_folder:
mov eax, [ext2_data.count_block_in_block]
sub [EXT2_end_block], eax
jz .not_found
inc [EXT2_counter_blocks]
mov ecx, [EXT2_counter_blocks]
call ext2_get_inode_block
 
mov eax, ecx
mov ebx, [ext2_data.ext2_save_block] ;ebx = cur dir record
call ext2_get_block
 
mov eax, esi
call ext2_test_block_by_name
cmp eax, esi ;нашли имя?
jz .next_block_folder
 
cmp byte [esi], 0
jz .get_inode_ret
 
cmp [ebx + EXT2_DIR_STRUC.file_type], EXT2_FT_DIR
jne .not_found ;нашли, но это не папка
mov eax, [ebx + EXT2_DIR_STRUC.inode]
mov ebx, [ext2_data.ext2_save_inode] ;все же папка.
call ext2_get_inode
mov ebp, ebx
jmp .next_folder
 
.not_found:
stc
ret
.get_inode_ret:
mov [EXT2_end_block], ebx ; сохраняем указатеть на dir_rec
mov eax, [ebx + EXT2_DIR_STRUC.inode]
mov ebx, [ext2_data.ext2_save_inode]
call ext2_get_inode
mov ebp, ebx
clc
ret
 
 
;========================
 
ext2_HdGetFileInfo:
cmp byte [esi], 0
jz .doit
 
call ext2_find_lfn
jnc .doit2
;.not_found:
mov eax, ERROR_FILE_NOT_FOUND
ret
 
.doit:
mov ebp, [ext2_data.root_inode]
mov ebx, .doit ;неважно что лишь бы этому адресу не '.'
jmp @F
.doit2:
mov ebx, [EXT2_end_block]
add ebx, EXT2_DIR_STRUC.name
@@:
xor eax, eax
mov edi, edx
mov ecx, 40/4
rep stosd ; fill zero
 
cmp byte [ebx], '.'
jnz @F
or dword [edx], FS_FT_HIDDEN
@@:
 
test [ebp + 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 dword [edx+32], eax
mov dword [edx+36], ebx
xor dword [edx], FS_FT_DIR
@@:
xor dword [edx], FS_FT_DIR
 
lea edi, [edx + 8]
mov eax, [ebx + EXT2_INODE_STRUC.i_ctime]
xor edx, edx
add eax, 3054539008
adc edx, 2
call ntfs_datetime_to_bdfe.sec
 
mov eax, [ebx + EXT2_INODE_STRUC.i_atime]
xor edx, edx
add eax, 3054539008
adc edx, 2
call ntfs_datetime_to_bdfe.sec
 
mov eax, [ebx + EXT2_INODE_STRUC.i_mtime]
xor edx, edx
add eax, 3054539008
adc edx, 2
call ntfs_datetime_to_bdfe.sec
 
xor eax, eax
ret
 
ext2_HdRewrite:
ext2_HdWrite:
ext2_HdSetFileEnd:
ext2_HdSetFileInfo:
ext2_HdDelete:
ext2_HdCreateFolder:
xor ebx, ebx
mov eax, ERROR_UNSUPPORTED_FS
ret
;----------------------------------------------------------------
;
; ext2_HdCreateFolder - create new folder
;
; esi points to filename
;
; ret eax = 0 ok read or other = errormsg
;
;--------------------------------------------------------------
cmp byte [esi], 0
jz .not_found
cmp byte [esi], '/'
jz .not_found
 
mov ebx, esi ; save source pointer
xor edi, edi ; slah pointer
@@:
lodsb
cmp al, 0
jz .zero
cmp al, '/'
jz .slash
jmp @B
 
.slash:
lodsb
cmp al, 0
jz .zero ; уберем слеш из имени
cmp al, '/'
jz .not_found
mov edi, esi ; edi -> next symbol after '/'
dec edi
jmp @B
 
.zero:
dec esi
test edi, edi
jz .doit
 
;слеш был
mov eax, esi
sub eax, edi
mov [EXT2_name_len], eax
 
mov ecx, edi
sub ecx, ebx
dec ecx ;выкинули '/' из имени ролителя
mov esi, ebx
mov edi, EXT2_parent_name
rep movsb
; esi - pointer to last slash
 
mov edx, esi
mov esi, EXT2_parent_name
call ext2_find_lfn
jnc .doit2
.not_found:
or ebx, -1
mov eax, ERROR_FILE_NOT_FOUND
ret
 
.doit:
mov ebp, [ext2_data.root_inode]
mov edx, ebx ; имя создаваемой папки
sub esi, ebx
mov [EXT2_name_len], esi
.doit2:
;ebp -> parent_inode ebx->name_new_folder [EXT2_name_len]=length of name
; стратегия выбора группы для нового inode: (так делает линукс)
; 1) Ищем группу в которой меньше всего папок и в есть свободное место
; 2) Если такая группа не нашлась, то берем группу в которой больше свободного места
 
 
 
 
call ext2_balloc
jmp ext2_HdDelete
 
push ebx
push ebp
 
mov ecx, [ext2_data.sb]
cmp [ecx + EXT2_SB_STRUC.free_inodes_count], 0 ; есть ли место для inode
jz .no_space
mov eax, [ecx + EXT2_SB_STRUC.free_block_count]
sub eax, [ecx + EXT2_SB_STRUC.r_block_count]
cmp eax, 2 ; и как минимум на 2 блока
jb .no_space
 
mov ecx, [ext2_data.groups_count]
mov esi, [ext2_data.global_desc_table]
mov edi, -1 ;указатель на лучшую группу
mov edx, 0
.find_group_dir:
jecxz .end_find_group_dir
movzx eax, [esi + EXT2_BLOCK_GROUP_DESC.free_inodes_count]
cmp eax, edx
jbe @F
cmp [esi + EXT2_BLOCK_GROUP_DESC.free_blocks_count], 0
jz @F
mov edi, esi
movzx edx, [esi + EXT2_BLOCK_GROUP_DESC.free_inodes_count]
@@:
dec ecx
add esi, 32 ;размер структуры
jmp .find_group_dir
.end_find_group_dir:
cmp edx, 0
jz .no_space
 
;нашли группу, получим битовую карту inode-ов (найдем locale number)
mov eax, [edi + EXT2_BLOCK_GROUP_DESC.inode_bitmap]
mov ebx, [ext2_data.ext2_save_block]
call ext2_get_block
 
;теперь цикл по всем битам
mov esi, ebx
mov ecx, [ext2_data.inodes_per_group]
shr ecx, 5 ;делим на 32
mov ebp, ecx ; всего сохраним в ebp
or eax, -1 ; ищем первый свободный inode (!= -1)
repne scasd
jnz .test_last_dword ;нашли или нет
mov eax, [esi-4]
 
sub ebp, ecx
dec ebp
shl ebp, 5 ; глобальный номер локального номера
 
mov ecx, 32
@@:
test eax, 1
jz @F
shr eax, 1
loop @B
@@:
mov eax, 32
sub eax, ecx
 
add ebp, eax ; locale num of inode
 
mov eax, [esi-4]
;устанавливаем в eax крайний справа нулевой бит в 1
mov ecx, eax
inc ecx
or eax, ecx ; x | (x+1)
mov [esi-4], eax
mov ebx, [ext2_data.ext2_save_block]
mov eax, [edi + EXT2_BLOCK_GROUP_DESC.inode_bitmap]
call ext2_set_block
;считаем таблицу inode
sub edi, [ext2_data.global_desc_table]
shr edi, 5
 
mov eax, edi
mul [ext2_data.inodes_per_group]
add eax, ebp
inc eax ; теперь в eax (ebp) номер inode-а
mov ebp, eax
;call ext2_get_inode_address
 
mov ebx, [ext2_data.ext2_save_block]
call hd_read
add edx, ebx ; в edx адрес нужного inode
 
;забьем 0 для начала
mov edi, edx
mov ecx, [ext2_data.inode_size]
shr ecx, 2
xor eax, eax
rep stosd
 
mov edi, edx
mov eax, EXT2_S_IFDIR or EXT2_777_MODE
stosd ; i_mode
xor eax, eax
stosd ; i_uid
mov eax, [ext2_data.block_size]
stosd ; i_size
xor eax, eax
stosd ; i_atime
stosd ; i_ctime
stosd ; i_mtime
stosd ; i_dtime
stosd ; i_gid
inc eax
stosd ; i_links_count
mov eax, [ext2_data.count_block_in_block]
stosd ; i_blocks
 
 
 
 
.test_last_dword:
 
xor ebx, ebx
mov eax, ERROR_UNSUPPORTED_FS
ret
 
 
 
.no_space:
or ebx, -1
mov eax, ERROR_DISK_FULL
ret
 
;выделяет новый блок, если это можно
;иначе возвращает eax=0
ext2_balloc:
mov ecx, [ext2_data.sb]
mov eax, [ecx + EXT2_SB_STRUC.free_block_count]
sub eax, [ecx + EXT2_SB_STRUC.r_block_count]
jbe .no_space
 
mov ecx, [ext2_data.groups_count]
mov edi, [ext2_data.global_desc_table]
;mov esi, -1 ;указатель на лучшую группу
mov edx, 0
.find_group:
jecxz .end_find_group
movzx eax, [edi + EXT2_BLOCK_GROUP_DESC.free_blocks_count]
cmp eax, edx
jbe @F
mov esi, edi
mov edx, eax
@@:
dec ecx
add edi, 32 ;размер структуры
jmp .find_group
.end_find_group:
cmp edx, 0
jz .no_space
 
;нашли группу, получим битовую карту block-ов
mov eax, [esi + EXT2_BLOCK_GROUP_DESC.block_bitmap]
mov ebx, [ext2_data.ext2_save_block]
call ext2_get_block
 
;теперь цикл по всем битам
mov edi, ebx
mov ecx, [ext2_data.blocks_per_group]
shr ecx, 5 ;делим на 32
mov ebp, ecx ;всего сохраним в ebp
or eax, -1 ;ищем первый свободный inode (!= -1)
repe scasd
jz .test_last_dword ;нашли или нет
 
mov eax, [edi-4]
sub ebp, ecx
dec ebp
shl ebp, 5 ; ebp = 32*(номер div 32). Теперь найдем (номер mod 32)
 
mov ecx, 32
@@:
test eax, 1
jz @F
shr eax, 1
loop @B
@@:
mov eax, 32
sub eax, ecx
 
add ebp, eax ; ebp = номер блока в группе
 
mov eax, [edi-4]
mov ecx, eax
inc ecx
or eax, ecx ; x | (x+1) - устанавливает в 1 крайний справа нулевой бит (block used)
mov [edi-4], eax
 
mov ebx, [ext2_data.ext2_save_block]
mov eax, [esi + EXT2_BLOCK_GROUP_DESC.inode_bitmap]
; call ext2_set_block ; и пишем на hdd новую битовую маску
 
;============== тут получаем номер блока
mov eax, [ext2_data.blocks_per_group]
sub esi, [ext2_data.global_desc_table]
shr esi, 5 ;esi - номер группы
mul esi
add ebp, eax ;(номер_группы) * (blocks_per_group) + локальный номер в группе
mov eax, [ext2_data.sb]
add ebp, [eax + EXT2_SB_STRUC.first_data_block]
 
;теперь поправим глобальную дескрипторную таблицу и суперблок
mov ebx, [ext2_data.sb]
dec [ebx + EXT2_SB_STRUC.free_block_count]
mov eax, 2
add eax, [PARTITION_START]
call hd_write
mov eax, [ebx + EXT2_SB_STRUC.first_data_block]
inc eax
dec [esi + EXT2_BLOCK_GROUP_DESC.free_blocks_count];edi все еще указывает на группу в которой мы выделил блок
call ext2_set_block
 
mov eax, ebx
ret
 
.test_last_dword:
lodsd
mov ecx, [ext2_data.blocks_per_group]
and ecx, not (32-1) ;обнуляем все кроме последних 5 бит
mov edx, ecx
mov ebx, 1
@@:
jecxz .no_space
mov edx, ebx
or edx, eax ; тестируем очередной бит
shl ebx, 1
jmp @B
@@:
sub edx, ecx
dec edx ;номер в последнем блоке
 
 
.no_space:
xor eax, eax
ret
 
;in: eax = i_block
; ebx = pointer to memory
ext2_set_block:
push eax ebx ecx
mov ecx, [ext2_data.log_block_size]
shl eax, cl
add eax, [PARTITION_START]
mov ecx, [ext2_data.count_block_in_block]
@@:
call hd_write
inc eax
add ebx, 512
loop @B
pop ecx ebx eax
ret
 
/kernel/branches/net/fs/fat12.inc
26,24 → 26,24
 
reserve_flp:
 
cli
cmp [flp_status],0
je reserve_flp_ok
cli
cmp [flp_status], 0
je reserve_flp_ok
 
sti
call change_task
jmp reserve_flp
sti
call change_task
jmp reserve_flp
 
reserve_flp_ok:
 
push eax
mov eax,[CURRENT_TASK]
shl eax,5
mov eax,[eax+CURRENT_TASK+TASKDATA.pid]
mov [flp_status],eax
pop eax
sti
ret
push eax
mov eax, [CURRENT_TASK]
shl eax, 5
mov eax, [eax+CURRENT_TASK+TASKDATA.pid]
mov [flp_status], eax
pop eax
sti
ret
 
 
floppy_fileread:
63,455 → 63,455
; 10 = access denied
;--------------------------------------------------------------
 
mov [save_flag],0
mov [path_pointer_flp],edi
test esi,esi ; return ramdisk root
jnz fr_noroot_1
cmp ebx,224/16
jbe fr_do_1
mov eax,5
xor ebx,ebx
mov [flp_status],ebx
ret
mov [save_flag], 0
mov [path_pointer_flp], edi
test esi, esi ; return ramdisk root
jnz fr_noroot_1
cmp ebx, 224/16
jbe fr_do_1
mov eax, 5
xor ebx, ebx
mov [flp_status], ebx
ret
 
fr_do_1:
push ebx ecx edx
call read_flp_root
pop edx ecx ebx
cmp [FDC_Status],0
jne fdc_status_error_1
mov edi,edx
dec ebx
shl ebx,9
mov esi,FLOPPY_BUFF
add esi,ebx
shl ecx,9
cld
rep movsb
xor eax,eax
xor ebx,ebx
push ebx ecx edx
call read_flp_root
pop edx ecx ebx
cmp [FDC_Status], 0
jne fdc_status_error_1
mov edi, edx
dec ebx
shl ebx, 9
mov esi, FLOPPY_BUFF
add esi, ebx
shl ecx, 9
cld
rep movsb
xor eax, eax
xor ebx, ebx
; mov eax,0 ; ok read
; mov ebx,0
mov [flp_status],eax
ret
mov [flp_status], eax
ret
fdc_status_error_1:
xor eax,eax
mov [flp_status],eax
mov eax,10
or ebx,-1
ret
xor eax, eax
mov [flp_status], eax
mov eax, 10
or ebx, -1
ret
 
fr_noroot_1:
sub esp,32
call expand_filename
sub esp, 32
call expand_filename
frfloppy_1:
test ebx,ebx
jnz frfl5_1
mov ebx,1
test ebx, ebx
jnz frfl5_1
mov ebx, 1
frfl5_1:
test ecx,ecx
jnz frfl6_1
mov ecx,1
test ecx, ecx
jnz frfl6_1
mov ecx, 1
frfl6_1:
dec ebx
push eax
push eax ebx ecx edx esi edi
call read_flp_fat
cmp [FDC_Status],0
jne fdc_status_error_3_1
mov [FDD_Track],0 ; Öèëèíäð
mov [FDD_Head],1 ; Ñòîðîíà
mov [FDD_Sector],2 ; Ñåêòîð
call SeekTrack
mov dh,14
dec ebx
push eax
push eax ebx ecx edx esi edi
call read_flp_fat
cmp [FDC_Status], 0
jne fdc_status_error_3_1
mov [FDD_Track], 0; Öèëèíäð
mov [FDD_Head], 1; Ñòîðîíà
mov [FDD_Sector], 2; Ñåêòîð
call SeekTrack
mov dh, 14
l.20_1:
call ReadSectWithRetr
cmp [FDC_Status],0
jne fdc_status_error_3_1
mov dl,16
mov edi,FDD_BUFF
inc [FDD_Sector]
call ReadSectWithRetr
cmp [FDC_Status], 0
jne fdc_status_error_3_1
mov dl, 16
mov edi, FDD_BUFF
inc [FDD_Sector]
l.21_1:
mov esi,eax ;Name of file we want
mov ecx,11
cld
rep cmpsb ;Found the file?
je fifound_1 ;Yes
add ecx,21
add edi, ecx ;Advance to next entry
dec dl
test dl,dl
jnz l.21_1
dec dh
test dh,dh
jnz l.20_1
mov esi, eax ;Name of file we want
mov ecx, 11
cld
rep cmpsb ;Found the file?
je fifound_1 ;Yes
add ecx, 21
add edi, ecx ;Advance to next entry
dec dl
test dl, dl
jnz l.21_1
dec dh
test dh, dh
jnz l.20_1
fdc_status_error_3:
mov eax,5 ; file not found ?
or ebx,-1
add esp,32+28
mov [flp_status],0
ret
mov eax, 5 ; file not found ?
or ebx, -1
add esp, 32+28
mov [flp_status], 0
ret
fdc_status_error_3_2:
cmp [FDC_Status],0
je fdc_status_error_3
cmp [FDC_Status], 0
je fdc_status_error_3
fdc_status_error_3_1:
add esp,32+28
jmp fdc_status_error_1
add esp, 32+28
jmp fdc_status_error_1
 
fifound_1:
mov eax,[path_pointer_flp]
cmp [eax+36],byte 0
je fifound_2
add edi,0xf
mov eax,[edi]
and eax,65535
mov ebx,[path_pointer_flp]
add ebx,36
call get_cluster_of_a_path_flp
jc fdc_status_error_3_2
mov ebx,[ebx-11+28] ;file size
mov [esp+20],ebx
mov [esp+24],ebx
jmp fifound_3
mov eax, [path_pointer_flp]
cmp [eax+36], byte 0
je fifound_2
add edi, 0xf
mov eax, [edi]
and eax, 65535
mov ebx, [path_pointer_flp]
add ebx, 36
call get_cluster_of_a_path_flp
jc fdc_status_error_3_2
mov ebx, [ebx-11+28] ;file size
mov [esp+20], ebx
mov [esp+24], ebx
jmp fifound_3
fifound_2:
mov ebx,[edi-11+28] ;file size
mov [esp+20],ebx
mov [esp+24],ebx
add edi,0xf
mov eax,[edi]
mov ebx, [edi-11+28] ;file size
mov [esp+20], ebx
mov [esp+24], ebx
add edi, 0xf
mov eax, [edi]
fifound_3:
and eax,65535
mov [n_sector],eax ;eax=cluster
and eax, 65535
mov [n_sector], eax ;eax=cluster
frnew_1:
add eax,31 ;bootsector+2*fat+filenames
cmp [esp+16],dword 0 ; wanted cluster ?
jne frfl7_1
call read_chs_sector
cmp [FDC_Status],0
jne fdc_status_error_5
mov edi,[esp+8]
call give_back_application_data_1
add [esp+8],dword 512
dec dword [esp+12] ; last wanted cluster ?
cmp [esp+12],dword 0
je frnoread_1
jmp frfl8_1
add eax, 31 ;bootsector+2*fat+filenames
cmp [esp+16], dword 0; wanted cluster ?
jne frfl7_1
call read_chs_sector
cmp [FDC_Status], 0
jne fdc_status_error_5
mov edi, [esp+8]
call give_back_application_data_1
add [esp+8], dword 512
dec dword [esp+12] ; last wanted cluster ?
cmp [esp+12], dword 0
je frnoread_1
jmp frfl8_1
frfl7_1:
dec dword [esp+16]
dec dword [esp+16]
frfl8_1:
mov edi,[n_sector]
shl edi,1 ;find next cluster from FAT
add edi,FLOPPY_FAT
mov eax,[edi]
and eax,4095
mov edi,eax
mov [n_sector],edi
cmp edi,4095 ;eof - cluster
jz frnoread2_1
cmp [esp+24],dword 512 ;eof - size
jb frnoread_1
sub [esp+24],dword 512
jmp frnew_1
mov edi, [n_sector]
shl edi, 1 ;find next cluster from FAT
add edi, FLOPPY_FAT
mov eax, [edi]
and eax, 4095
mov edi, eax
mov [n_sector], edi
cmp edi, 4095 ;eof - cluster
jz frnoread2_1
cmp [esp+24], dword 512;eof - size
jb frnoread_1
sub [esp+24], dword 512
jmp frnew_1
 
read_chs_sector:
call calculate_chs
call ReadSectWithRetr
ret
call calculate_chs
call ReadSectWithRetr
ret
 
frnoread2_1:
cmp [esp+16],dword 0 ; eof without read ?
je frnoread_1
mov [fdc_irq_func],fdc_null
pop edi esi edx ecx
add esp,4
pop ebx ; ebx <- eax : size of file
add esp,36
mov eax,6 ; end of file
mov [flp_status],0
ret
cmp [esp+16], dword 0; eof without read ?
je frnoread_1
mov [fdc_irq_func], fdc_null
pop edi esi edx ecx
add esp, 4
pop ebx; ebx <- eax : size of file
add esp, 36
mov eax, 6; end of file
mov [flp_status], 0
ret
 
frnoread_1:
pop edi esi edx ecx
add esp,4
pop ebx ; ebx <- eax : size of file
add esp,36
xor eax,eax
mov [flp_status],eax
ret
pop edi esi edx ecx
add esp, 4
pop ebx; ebx <- eax : size of file
add esp, 36
xor eax, eax
mov [flp_status], eax
ret
 
fdc_status_error_5:
pop edi esi edx ecx
add esp,4
pop ebx ; ebx <- eax : size of file
add esp,36
jmp fdc_status_error_1
pop edi esi edx ecx
add esp, 4
pop ebx; ebx <- eax : size of file
add esp, 36
jmp fdc_status_error_1
 
read_flp_root:
pusha
call check_label
cmp [FDC_Status],0
jne unnecessary_root_read
cmp [root_read],1
je unnecessary_root_read
mov [FDD_Track],0 ; Öèëèíäð
mov [FDD_Head],1 ; Ñòîðîíà
mov [FDD_Sector],2 ; Ñåêòîð
mov edi,FLOPPY_BUFF
call SeekTrack
pusha
call check_label
cmp [FDC_Status], 0
jne unnecessary_root_read
cmp [root_read], 1
je unnecessary_root_read
mov [FDD_Track], 0; Öèëèíäð
mov [FDD_Head], 1; Ñòîðîíà
mov [FDD_Sector], 2; Ñåêòîð
mov edi, FLOPPY_BUFF
call SeekTrack
read_flp_root_1:
call ReadSectWithRetr
cmp [FDC_Status],0
jne unnecessary_root_read
push edi
call give_back_application_data_1
pop edi
add edi,512
inc [FDD_Sector]
cmp [FDD_Sector],16
jne read_flp_root_1
mov [root_read],1
call ReadSectWithRetr
cmp [FDC_Status], 0
jne unnecessary_root_read
push edi
call give_back_application_data_1
pop edi
add edi, 512
inc [FDD_Sector]
cmp [FDD_Sector], 16
jne read_flp_root_1
mov [root_read], 1
unnecessary_root_read:
popa
ret
popa
ret
 
 
read_flp_fat:
pusha
call check_label
cmp [FDC_Status],0
jne unnecessary_flp_fat
cmp [flp_fat],1
je unnecessary_flp_fat
mov [FDD_Track],0 ; Öèëèíäð
mov [FDD_Head],0 ; Ñòîðîíà
mov [FDD_Sector],2 ; Ñåêòîð
mov edi,FLOPPY_BUFF
call SeekTrack
pusha
call check_label
cmp [FDC_Status], 0
jne unnecessary_flp_fat
cmp [flp_fat], 1
je unnecessary_flp_fat
mov [FDD_Track], 0; Öèëèíäð
mov [FDD_Head], 0; Ñòîðîíà
mov [FDD_Sector], 2; Ñåêòîð
mov edi, FLOPPY_BUFF
call SeekTrack
read_flp_fat_1:
call ReadSectWithRetr
cmp [FDC_Status],0
jne unnecessary_flp_fat
push edi
call give_back_application_data_1
pop edi
add edi,512
inc [FDD_Sector]
cmp [FDD_Sector],19
jne read_flp_fat_1
mov [FDD_Sector],1
mov [FDD_Head],1
call ReadSectWithRetr
cmp [FDC_Status],0
jne unnecessary_flp_fat
call give_back_application_data_1
call calculatefatchain_flp
mov [root_read],0
mov [flp_fat],1
call ReadSectWithRetr
cmp [FDC_Status], 0
jne unnecessary_flp_fat
push edi
call give_back_application_data_1
pop edi
add edi, 512
inc [FDD_Sector]
cmp [FDD_Sector], 19
jne read_flp_fat_1
mov [FDD_Sector], 1
mov [FDD_Head], 1
call ReadSectWithRetr
cmp [FDC_Status], 0
jne unnecessary_flp_fat
call give_back_application_data_1
call calculatefatchain_flp
mov [root_read], 0
mov [flp_fat], 1
unnecessary_flp_fat:
popa
ret
popa
ret
 
calculatefatchain_flp:
pushad
pushad
 
mov esi,FLOPPY_BUFF
mov edi,FLOPPY_FAT
mov esi, FLOPPY_BUFF
mov edi, FLOPPY_FAT
 
fcnew_1:
mov eax,dword [esi]
mov ebx,dword [esi+4]
mov ecx,dword [esi+8]
mov edx,ecx
shr edx,4 ;8 ok
shr dx,4 ;7 ok
xor ch,ch
shld ecx,ebx,20 ;6 ok
shr cx,4 ;5 ok
shld ebx,eax,12
and ebx,0x0fffffff ;4 ok
shr bx,4 ;3 ok
shl eax,4
and eax,0x0fffffff ;2 ok
shr ax,4 ;1 ok
mov dword [edi],eax
add edi,4
mov dword [edi],ebx
add edi,4
mov dword [edi],ecx
add edi,4
mov dword [edi],edx
add edi,4
add esi,12
mov eax, dword [esi]
mov ebx, dword [esi+4]
mov ecx, dword [esi+8]
mov edx, ecx
shr edx, 4;8 ok
shr dx, 4;7 ok
xor ch, ch
shld ecx, ebx, 20;6 ok
shr cx, 4;5 ok
shld ebx, eax, 12
and ebx, 0x0fffffff;4 ok
shr bx, 4;3 ok
shl eax, 4
and eax, 0x0fffffff;2 ok
shr ax, 4;1 ok
mov dword [edi], eax
add edi, 4
mov dword [edi], ebx
add edi, 4
mov dword [edi], ecx
add edi, 4
mov dword [edi], edx
add edi, 4
add esi, 12
 
cmp edi,FLOPPY_FAT+2856*2 ;2849 clusters
jnz fcnew_1
cmp edi, FLOPPY_FAT+2856*2;2849 clusters
jnz fcnew_1
 
popad
ret
popad
ret
 
check_label:
pushad
mov [FDD_Track],0 ; Öèëèíäð
mov [FDD_Head],0 ; Ñòîðîíà
mov [FDD_Sector],1 ; Ñåêòîð
call SetUserInterrupts
call FDDMotorON
call RecalibrateFDD
cmp [FDC_Status],0
jne fdc_status_error
call SeekTrack
cmp [FDC_Status],0
jne fdc_status_error
call ReadSectWithRetr
cmp [FDC_Status],0
jne fdc_status_error
mov esi,flp_label
mov edi,FDD_BUFF+39
mov ecx,15
cld
rep cmpsb
je same_label
mov [root_read],0
mov [flp_fat],0
pushad
mov [FDD_Track], 0; Öèëèíäð
mov [FDD_Head], 0; Ñòîðîíà
mov [FDD_Sector], 1; Ñåêòîð
call SetUserInterrupts
call FDDMotorON
call RecalibrateFDD
cmp [FDC_Status], 0
jne fdc_status_error
call SeekTrack
cmp [FDC_Status], 0
jne fdc_status_error
call ReadSectWithRetr
cmp [FDC_Status], 0
jne fdc_status_error
mov esi, flp_label
mov edi, FDD_BUFF+39
mov ecx, 15
cld
rep cmpsb
je same_label
mov [root_read], 0
mov [flp_fat], 0
same_label:
mov esi,FDD_BUFF+39
mov edi,flp_label
mov ecx,15
cld
rep movsb
popad
ret
mov esi, FDD_BUFF+39
mov edi, flp_label
mov ecx, 15
cld
rep movsb
popad
ret
fdc_status_error:
popad
ret
popad
ret
 
save_flp_root:
pusha
call check_label
cmp [FDC_Status],0
jne unnecessary_root_save
cmp [root_read],0
je unnecessary_root_save
mov [FDD_Track],0 ; Öèëèíäð
mov [FDD_Head],1 ; Ñòîðîíà
mov [FDD_Sector],2 ; Ñåêòîð
mov esi,FLOPPY_BUFF
call SeekTrack
pusha
call check_label
cmp [FDC_Status], 0
jne unnecessary_root_save
cmp [root_read], 0
je unnecessary_root_save
mov [FDD_Track], 0; Öèëèíäð
mov [FDD_Head], 1; Ñòîðîíà
mov [FDD_Sector], 2; Ñåêòîð
mov esi, FLOPPY_BUFF
call SeekTrack
save_flp_root_1:
push esi
call take_data_from_application_1
pop esi
add esi,512
call WriteSectWithRetr
cmp [FDC_Status],0
jne unnecessary_root_save
inc [FDD_Sector]
cmp [FDD_Sector],16
jne save_flp_root_1
push esi
call take_data_from_application_1
pop esi
add esi, 512
call WriteSectWithRetr
cmp [FDC_Status], 0
jne unnecessary_root_save
inc [FDD_Sector]
cmp [FDD_Sector], 16
jne save_flp_root_1
unnecessary_root_save:
mov [fdc_irq_func],fdc_null
popa
ret
mov [fdc_irq_func], fdc_null
popa
ret
 
save_flp_fat:
pusha
call check_label
cmp [FDC_Status],0
jne unnecessary_flp_fat_save
cmp [flp_fat],0
je unnecessary_flp_fat_save
call restorefatchain_flp
mov [FDD_Track],0 ; Öèëèíäð
mov [FDD_Head],0 ; Ñòîðîíà
mov [FDD_Sector],2 ; Ñåêòîð
mov esi,FLOPPY_BUFF
call SeekTrack
pusha
call check_label
cmp [FDC_Status], 0
jne unnecessary_flp_fat_save
cmp [flp_fat], 0
je unnecessary_flp_fat_save
call restorefatchain_flp
mov [FDD_Track], 0; Öèëèíäð
mov [FDD_Head], 0; Ñòîðîíà
mov [FDD_Sector], 2; Ñåêòîð
mov esi, FLOPPY_BUFF
call SeekTrack
save_flp_fat_1:
push esi
call take_data_from_application_1
pop esi
add esi,512
call WriteSectWithRetr
cmp [FDC_Status],0
jne unnecessary_flp_fat_save
inc [FDD_Sector]
cmp [FDD_Sector],19
jne save_flp_fat_1
mov [FDD_Sector],1
mov [FDD_Head],1
call take_data_from_application_1
call WriteSectWithRetr
cmp [FDC_Status],0
jne unnecessary_flp_fat_save
mov [root_read],0
push esi
call take_data_from_application_1
pop esi
add esi, 512
call WriteSectWithRetr
cmp [FDC_Status], 0
jne unnecessary_flp_fat_save
inc [FDD_Sector]
cmp [FDD_Sector], 19
jne save_flp_fat_1
mov [FDD_Sector], 1
mov [FDD_Head], 1
call take_data_from_application_1
call WriteSectWithRetr
cmp [FDC_Status], 0
jne unnecessary_flp_fat_save
mov [root_read], 0
unnecessary_flp_fat_save:
mov [fdc_irq_func],fdc_null
popa
ret
mov [fdc_irq_func], fdc_null
popa
ret
 
 
restorefatchain_flp: ; restore fat chain
pushad
pushad
 
mov esi,FLOPPY_FAT
mov edi,FLOPPY_BUFF
mov esi, FLOPPY_FAT
mov edi, FLOPPY_BUFF
 
fcnew2_1:
mov eax,dword [esi]
mov ebx,dword [esi+4]
shl ax,4
shl eax,4
shl bx,4
shr ebx,4
shrd eax,ebx,8
shr ebx,8
mov dword [edi],eax
add edi,4
mov word [edi],bx
add edi,2
add esi,8
mov eax, dword [esi]
mov ebx, dword [esi+4]
shl ax, 4
shl eax, 4
shl bx, 4
shr ebx, 4
shrd eax, ebx, 8
shr ebx, 8
mov dword [edi], eax
add edi, 4
mov word [edi], bx
add edi, 2
add esi, 8
 
cmp edi,FLOPPY_BUFF+0x1200 ;4274 bytes - all used FAT
jb fcnew2_1
cmp edi, FLOPPY_BUFF+0x1200;4274 bytes - all used FAT
jb fcnew2_1
 
mov esi,FLOPPY_BUFF ; duplicate fat chain
mov edi,FLOPPY_BUFF+0x1200
mov ecx,0x1200/4
cld
rep movsd
mov esi, FLOPPY_BUFF ; duplicate fat chain
mov edi, FLOPPY_BUFF+0x1200
mov ecx, 0x1200/4
cld
rep movsd
 
popad
ret
popad
ret
 
 
save_chs_sector:
call calculate_chs
call WriteSectWithRetr
ret
call calculate_chs
call WriteSectWithRetr
ret
 
calculate_chs:
mov bl,[FDD_Track]
mov [old_track],bl
mov ebx,18
xor edx,edx
div ebx
inc edx
mov [FDD_Sector],dl
xor edx,edx
mov ebx,2
div ebx
mov [FDD_Track],al
mov [FDD_Head],0
test edx,edx
jz no_head_2
inc [FDD_Head]
mov bl, [FDD_Track]
mov [old_track], bl
mov ebx, 18
xor edx, edx
div ebx
inc edx
mov [FDD_Sector], dl
xor edx, edx
mov ebx, 2
div ebx
mov [FDD_Track], al
mov [FDD_Head], 0
test edx, edx
jz no_head_2
inc [FDD_Head]
no_head_2:
mov dl,[old_track]
cmp dl,[FDD_Track]
je no_seek_track_1
call SeekTrack
mov dl, [old_track]
cmp dl, [FDD_Track]
je no_seek_track_1
call SeekTrack
no_seek_track_1:
ret
ret
 
 
get_cluster_of_a_path_flp:
525,40 → 525,40
; if (CARRY=0) -> EAX=cluster
;---------------------------------------------------------
 
push edx
mov edx,ebx
push edx
mov edx, ebx
 
search_end_of_path_flp:
cmp [save_flag],0
jne search_end_of_path_flp_1
cmp byte [edx],0
je found_end_of_path_flp
jmp search_end_of_path_flp_2
cmp [save_flag], 0
jne search_end_of_path_flp_1
cmp byte [edx], 0
je found_end_of_path_flp
jmp search_end_of_path_flp_2
search_end_of_path_flp_1:
cmp byte [edx+12],0
je found_end_of_path_flp
cmp byte [edx+12], 0
je found_end_of_path_flp
search_end_of_path_flp_2:
inc edx ; '/'
call analyze_directory_flp
jc directory_not_found_flp
inc edx; '/'
call analyze_directory_flp
jc directory_not_found_flp
 
mov eax,[ebx+20-2] ; read the HIGH 16bit cluster field
mov ax,[ebx+26] ; read the LOW 16bit cluster field
and eax,0xfff ;[fatMASK]
add edx,11 ; 8+3 (name+extension)
jmp search_end_of_path_flp
mov eax, [ebx+20-2] ; read the HIGH 16bit cluster field
mov ax, [ebx+26] ; read the LOW 16bit cluster field
and eax, 0xfff ;[fatMASK]
add edx, 11 ; 8+3 (name+extension)
jmp search_end_of_path_flp
 
found_end_of_path_flp:
inc edx
mov [pointer_file_name_flp],edx
pop edx
clc ; no errors
ret
inc edx
mov [pointer_file_name_flp], edx
pop edx
clc ; no errors
ret
 
directory_not_found_flp:
pop edx
stc ; errors occour
ret
pop edx
stc ; errors occour
ret
 
analyze_directory_flp:
;--------------------------------
570,62 → 570,62
; ECX,EDX,EDI,EDI not changed
; IF CARRY=1
;--------------------------------
push ebx ;[esp+16]
push ecx
push edx
push esi
push edi
push ebx;[esp+16]
push ecx
push edx
push esi
push edi
 
 
adr56_flp:
mov [clust_tmp_flp],eax
add eax,31
pusha
call read_chs_sector
popa
cmp [FDC_Status],0
jne not_found_file_analyze_flp
mov [clust_tmp_flp], eax
add eax, 31
pusha
call read_chs_sector
popa
cmp [FDC_Status], 0
jne not_found_file_analyze_flp
 
mov ecx,512/32
mov ebx,FDD_BUFF
mov ecx, 512/32
mov ebx, FDD_BUFF
 
adr1_analyze_flp:
mov esi,edx ;[esp+16]
mov edi,ebx
cld
push ecx
mov ecx,11
rep cmpsb
pop ecx
je found_file_analyze_flp
mov esi, edx;[esp+16]
mov edi, ebx
cld
push ecx
mov ecx, 11
rep cmpsb
pop ecx
je found_file_analyze_flp
 
add ebx,32
loop adr1_analyze_flp
add ebx, 32
loop adr1_analyze_flp
 
mov eax,[clust_tmp_flp]
shl eax,1 ;find next cluster from FAT
add eax,FLOPPY_FAT
mov eax,[eax]
and eax,4095
cmp eax,0x0ff8
jb adr56_flp
mov eax, [clust_tmp_flp]
shl eax, 1 ;find next cluster from FAT
add eax, FLOPPY_FAT
mov eax, [eax]
and eax, 4095
cmp eax, 0x0ff8
jb adr56_flp
not_found_file_analyze_flp:
pop edi
pop esi
pop edx
pop ecx
add esp,4
stc ;file not found
ret
pop edi
pop esi
pop edx
pop ecx
add esp, 4
stc ;file not found
ret
 
found_file_analyze_flp:
pop edi
pop esi
pop edx
pop ecx
add esp,4
clc ;file found
ret
pop edi
pop esi
pop edx
pop ecx
add esp, 4
clc ;file found
ret
 
 
; \begin{diamond}
789,7 → 789,7
xor eax, eax
mov edi, FLOPPY_FAT
mov ecx, 2849
repnz scasw
repnz scasw
jnz .notfound
mov word [edi-2], 0xFFF ; mark as last cluster
sub edi, FLOPPY_FAT
802,7 → 802,7
xor eax, eax
mov edi, FDD_BUFF
mov ecx, 128
rep stosd
rep stosd
popa
call flp_notroot_end_write
mov edi, FDD_BUFF
1007,7 → 1007,7
mov edi, edx
mov ecx, 32/4
xor eax, eax
rep stosd
rep stosd
pop ecx eax
mov byte [edx], 1 ; version
mov esi, edi ; esi points to BDFE
1282,7 → 1282,7
jz .test_short_name_cont
mov ecx, 11
push esi edi
repz cmpsb
repz cmpsb
pop edi esi
jz .short_name_found
.test_short_name_cont:
1307,7 → 1307,7
mov al, '~'
push ecx edi
mov ecx, 8
repnz scasb
repnz scasb
push 1
pop eax ; 1 entry
jnz .notilde
1433,7 → 1433,7
.nolfn:
xchg esi, [esp]
mov ecx, 11
rep movsb
rep movsb
mov word [edi], 20h ; attributes
sub edi, 11
pop esi ecx
1470,14 → 1470,14
.write_loop:
; allocate new cluster
xor eax, eax
repnz scasw
repnz scasw
mov al, ERROR_DISK_FULL
jnz .ret
dec edi
dec edi
 
mov eax, edi
sub eax, FLOPPY_FAT
mov eax, edi
sub eax, FLOPPY_FAT
 
shr eax, 1 ; eax = cluster
mov word [edi], 0xFFF ; mark as last cluster
1502,7 → 1502,7
cmp byte [esp+24+28+28], 0
jnz .writedir
push ecx
rep movsb
rep movsb
pop ecx
.writedircont:
push ecx
1510,7 → 1510,7
neg ecx
push eax
xor eax, eax
rep stosb
rep stosb
pop eax
add eax, 31
pusha
1561,7 → 1561,7
push ecx
mov ecx, 32/4
push ecx esi
rep movsd
rep movsd
pop esi ecx
mov dword [edi-32], '. '
mov dword [edi-32+4], ' '
1569,7 → 1569,7
mov byte [edi-32+11], 10h
mov word [edi-32+26], ax
push esi
rep movsd
rep movsd
pop esi
mov dword [edi-32], '.. '
mov dword [edi-32+4], ' '
1749,7 → 1749,7
jbe @f
mov edi, FDD_BUFF
add edi, [esp+4+12]
rep stosb
rep stosb
@@:
; zero uninitialized data in the last sector
mov ecx, 0x200
1757,7 → 1757,7
jbe @f
mov edi, FDD_BUFF
add edi, esi
rep stosb
rep stosb
@@:
pop edi ecx eax
; copy new data
1850,7 → 1850,7
jecxz .disk_full
push eax
xor eax, eax
repnz scasw
repnz scasw
pop eax
jnz .disk_full
mov word [edi-2], 0xFFF
2003,7 → 2003,7
add edi, [esp+8]
xor eax, eax
mov [esp+8], eax
rep stosb
rep stosb
pop edi
lea eax, [edi+31]
pusha
2083,7 → 2083,7
sub ecx, edi
push eax
xor eax, eax
rep stosb
rep stosb
pop eax
pusha
call save_chs_sector
/kernel/branches/net/fs/fat32.inc
60,6 → 60,7
ERROR_DISK_FULL = 8
ERROR_FAT_TABLE = 9
ERROR_ACCESS_DENIED = 10
ERROR_DEVICE = 11
 
PUSHAD_EAX equ [esp+28]
PUSHAD_ECX equ [esp+24]
93,10 → 94,13
 
uglobal
align 4
fat_cache: times 512 db 0
fat_cache:
times 512 db 0
Sector512: ; label for dev_hdcd.inc
buffer: times 512 db 0
fsinfo_buffer: times 512 db 0
buffer:
times 512 db 0
fsinfo_buffer:
times 512 db 0
endg
 
uglobal
106,24 → 110,24
 
reserve_hd1:
 
cli
cmp [hd1_status],0
je reserve_ok1
cli
cmp [hd1_status], 0
je reserve_ok1
 
sti
call change_task
jmp reserve_hd1
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
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
135,22 → 139,22
; This must be modified when hd1_status will not be valid!
cmp [hdpos], 0x80
jae .ret
cmp [hdbase], 0x1F0
jne .IDE_Channel_2
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
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
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
168,8 → 172,8
mov [hd_in_cache], al
call clear_hd_cache
@@:
pop eax
sti
pop eax
sti
.ret:
ret
 
177,15 → 181,15
; see comment at reserve_hd_channel
cmp [hdpos], 0x80
jae .ret
cmp [hdbase], 0x1F0
jne .IDE_Channel_2
cmp [hdbase], 0x1F0
jne .IDE_Channel_2
.IDE_Channel_1:
mov [IDE_Channel_1],0
mov [IDE_Channel_1], 0
.ret:
ret
ret
.IDE_Channel_2:
mov [IDE_Channel_2],0
ret
mov [IDE_Channel_2], 0
ret
;********************************************
problem_partition db 0 ; used for partitions search
 
197,67 → 201,67
; EDX = value to save
; output : EDX = old value
;--------------------------------
push eax ebx esi
push eax ebx esi
 
cmp eax,2
jb sfc_error
cmp eax,[LAST_CLUSTER]
ja sfc_error
cmp [fs_type],16
je sfc_1
add eax,eax
cmp eax, 2
jb sfc_error
cmp eax, [LAST_CLUSTER]
ja sfc_error
cmp [fs_type], 16
je sfc_1
add eax, eax
sfc_1:
add eax,eax
mov esi,511
and esi,eax ; esi = position in fat sector
shr eax,9 ; eax = fat sector
add eax,[FAT_START]
mov ebx,fat_cache
add eax, eax
mov esi, 511
and esi, eax ; esi = position in fat sector
shr eax, 9 ; eax = fat sector
add eax, [FAT_START]
mov ebx, fat_cache
 
cmp eax,[fat_in_cache] ; is fat sector already in memory?
je sfc_in_cache ; yes
cmp eax, [fat_in_cache]; is fat sector already in memory?
je sfc_in_cache ; yes
 
cmp [fat_change],0 ; is fat changed?
je sfc_no_change ; no
call write_fat_sector ; yes. write it into disk
cmp [hd_error],0
jne sfc_error
cmp [fat_change], 0 ; is fat changed?
je sfc_no_change ; no
call write_fat_sector; yes. write it into disk
cmp [hd_error], 0
jne sfc_error
 
sfc_no_change:
mov [fat_in_cache],eax ; save fat sector
call hd_read
cmp [hd_error],0
jne sfc_error
mov [fat_in_cache], eax; save fat sector
call hd_read
cmp [hd_error], 0
jne sfc_error
 
 
sfc_in_cache:
cmp [fs_type],16
jne sfc_test32
cmp [fs_type], 16
jne sfc_test32
 
sfc_set16:
xchg [ebx+esi],dx ; save new value and get old value
jmp sfc_write
xchg [ebx+esi], dx ; save new value and get old value
jmp sfc_write
 
sfc_test32:
mov eax,[fatMASK]
mov eax, [fatMASK]
 
sfc_set32:
and edx,eax
xor eax,-1 ; mask for high bits
and eax,[ebx+esi] ; get high 4 bits
or eax,edx
mov edx,[ebx+esi] ; get old value
mov [ebx+esi],eax ; save new value
and edx, eax
xor eax, -1 ; mask for high bits
and eax, [ebx+esi] ; get high 4 bits
or eax, edx
mov edx, [ebx+esi] ; get old value
mov [ebx+esi], eax ; save new value
 
sfc_write:
mov [fat_change],1 ; fat has changed
mov [fat_change], 1 ; fat has changed
 
sfc_nonzero:
and edx,[fatMASK]
and edx, [fatMASK]
 
sfc_error:
pop esi ebx eax
ret
pop esi ebx eax
ret
 
 
get_FAT:
265,40 → 269,40
; input : EAX = cluster
; output : EAX = next cluster
;--------------------------------
push ebx esi
push ebx esi
 
cmp [fs_type],16
je gfc_1
add eax,eax
cmp [fs_type], 16
je gfc_1
add eax, eax
gfc_1:
add eax,eax
mov esi,511
and esi,eax ; esi = position in fat sector
shr eax,9 ; eax = fat sector
add eax,[FAT_START]
mov ebx,fat_cache
add eax, eax
mov esi, 511
and esi, eax ; esi = position in fat sector
shr eax, 9 ; eax = fat sector
add eax, [FAT_START]
mov ebx, fat_cache
 
cmp eax,[fat_in_cache] ; is fat sector already in memory?
je gfc_in_cache
cmp eax, [fat_in_cache]; is fat sector already in memory?
je gfc_in_cache
 
cmp [fat_change],0 ; is fat changed?
je gfc_no_change ; no
call write_fat_sector ; yes. write it into disk
cmp [hd_error],0
jne hd_error_01
cmp [fat_change], 0 ; is fat changed?
je gfc_no_change ; no
call write_fat_sector; yes. write it into disk
cmp [hd_error], 0
jne hd_error_01
 
gfc_no_change:
mov [fat_in_cache],eax
call hd_read
cmp [hd_error],0
jne hd_error_01
mov [fat_in_cache], eax
call hd_read
cmp [hd_error], 0
jne hd_error_01
 
gfc_in_cache:
mov eax,[ebx+esi]
and eax,[fatMASK]
mov eax, [ebx+esi]
and eax, [fatMASK]
hd_error_01:
pop esi ebx
ret
pop esi ebx
ret
 
 
get_free_FAT:
307,45 → 311,45
; if CARRY=1 disk full
; Note : for more speed need to use fat_cache directly
;-----------------------------------------------------------
push ecx
mov ecx,[LAST_CLUSTER] ; counter for full disk
sub ecx,2
mov eax,[fatStartScan]
cmp eax,2
jb gff_reset
push ecx
mov ecx, [LAST_CLUSTER]; counter for full disk
sub ecx, 2
mov eax, [fatStartScan]
cmp eax, 2
jb gff_reset
 
gff_test:
cmp eax,[LAST_CLUSTER] ; if above last cluster start at cluster 2
jbe gff_in_range
cmp eax, [LAST_CLUSTER]; if above last cluster start at cluster 2
jbe gff_in_range
gff_reset:
mov eax,2
mov eax, 2
 
gff_in_range:
push eax
call get_FAT ; get cluster state
cmp [hd_error],0
jne gff_not_found_1
push eax
call get_FAT ; get cluster state
cmp [hd_error], 0
jne gff_not_found_1
 
test eax,eax ; is it free?
pop eax
je gff_found ; yes
inc eax ; next cluster
dec ecx ; is all checked?
jns gff_test ; no
test eax, eax ; is it free?
pop eax
je gff_found ; yes
inc eax ; next cluster
dec ecx ; is all checked?
jns gff_test ; no
 
gff_not_found_1:
add esp,4
add esp, 4
gff_not_found:
pop ecx ; yes. disk is full
stc
ret
pop ecx ; yes. disk is full
stc
ret
 
gff_found:
lea ecx,[eax+1]
mov [fatStartScan],ecx
pop ecx
clc
ret
lea ecx, [eax+1]
mov [fatStartScan], ecx
pop ecx
clc
ret
 
 
write_fat_sector:
352,27 → 356,27
;-----------------------------------------------------------
; write changed fat to disk
;-----------------------------------------------------------
push eax ebx ecx
push eax ebx ecx
 
mov [fat_change],0
mov eax,[fat_in_cache]
cmp eax,-1
jz write_fat_not_used
mov ebx,fat_cache
mov ecx,[NUMBER_OF_FATS]
mov [fat_change], 0
mov eax, [fat_in_cache]
cmp eax, -1
jz write_fat_not_used
mov ebx, fat_cache
mov ecx, [NUMBER_OF_FATS]
 
write_next_fat:
call hd_write
cmp [hd_error],0
jne write_fat_not_used
call hd_write
cmp [hd_error], 0
jne write_fat_not_used
 
add eax,[SECTORS_PER_FAT]
dec ecx
jnz write_next_fat
add eax, [SECTORS_PER_FAT]
dec ecx
jnz write_next_fat
 
write_fat_not_used:
pop ecx ebx eax
ret
pop ecx ebx eax
ret
 
 
analyze_directory:
387,91 → 391,91
; Note : if cluster=0 it's changed to read rootdir
; save 2 previous directory sectors in longname_sec
;-----------------------------------------------------------
push ecx edx esi edi ebx ; ebx = [esp+0]
mov [longname_sec1],0
mov [longname_sec2],0
push ecx edx esi edi ebx; ebx = [esp+0]
mov [longname_sec1], 0
mov [longname_sec2], 0
 
adr_new_cluster:
mov [cluster_tmp],eax
mov [fat16_root],0
cmp eax,[LAST_CLUSTER]
ja adr_not_found ; too big cluster number, something is wrong
cmp eax,2
jnb adr_data_cluster
mov [cluster_tmp], eax
mov [fat16_root], 0
cmp eax, [LAST_CLUSTER]
ja adr_not_found ; too big cluster number, something is wrong
cmp eax, 2
jnb adr_data_cluster
 
mov eax,[ROOT_CLUSTER] ; if cluster < 2 then read rootdir
cmp [fs_type],16
jne adr_data_cluster
mov eax,[ROOT_START]
mov edx,[ROOT_SECTORS]
mov [fat16_root],1 ; flag for fat16 rootdir
jmp adr_new_sector
mov eax, [ROOT_CLUSTER]; if cluster < 2 then read rootdir
cmp [fs_type], 16
jne adr_data_cluster
mov eax, [ROOT_START]
mov edx, [ROOT_SECTORS]
mov [fat16_root], 1 ; flag for fat16 rootdir
jmp adr_new_sector
 
adr_data_cluster:
sub eax,2
mov edx,[SECTORS_PER_CLUSTER]
imul eax,edx
add eax,[DATA_START]
sub eax, 2
mov edx, [SECTORS_PER_CLUSTER]
imul eax, edx
add eax, [DATA_START]
 
adr_new_sector:
mov ebx,buffer
call hd_read
cmp [hd_error],0
jne adr_not_found
mov ebx, buffer
call hd_read
cmp [hd_error], 0
jne adr_not_found
 
mov ecx,512/32 ; count of dir entrys per sector = 16
mov ecx, 512/32 ; count of dir entrys per sector = 16
 
adr_analyze:
mov edi,[ebx+11] ; file attribute
and edi,0xf
cmp edi,0xf
je adr_long_filename
test edi,0x8 ; skip over volume label
jne adr_long_filename ; Note: label can be same name as file/dir
mov edi, [ebx+11] ; file attribute
and edi, 0xf
cmp edi, 0xf
je adr_long_filename
test edi, 0x8 ; skip over volume label
jne adr_long_filename; Note: label can be same name as file/dir
 
mov esi,[esp+0] ; filename need to be uppercase
mov edi,ebx
push ecx
mov ecx,11
cld
rep cmpsb ; compare 8+3 filename
pop ecx
je adr_found
mov esi, [esp+0] ; filename need to be uppercase
mov edi, ebx
push ecx
mov ecx, 11
cld
rep cmpsb ; compare 8+3 filename
pop ecx
je adr_found
 
adr_long_filename:
add ebx,32 ; position of next dir entry
dec ecx
jnz adr_analyze
add ebx, 32 ; position of next dir entry
dec ecx
jnz adr_analyze
 
mov ecx,[longname_sec1] ; save 2 previous directory sectors
mov [longname_sec1],eax ; for delete long filename
mov [longname_sec2],ecx
inc eax ; next sector
dec edx
jne adr_new_sector
cmp [fat16_root],1 ; end of fat16 rootdir
je adr_not_found
mov ecx, [longname_sec1]; save 2 previous directory sectors
mov [longname_sec1], eax; for delete long filename
mov [longname_sec2], ecx
inc eax ; next sector
dec edx
jne adr_new_sector
cmp [fat16_root], 1 ; end of fat16 rootdir
je adr_not_found
 
adr_next_cluster:
mov eax,[cluster_tmp]
call get_FAT ; get next cluster
cmp [hd_error],0
jne adr_not_found
mov eax, [cluster_tmp]
call get_FAT ; get next cluster
cmp [hd_error], 0
jne adr_not_found
 
cmp eax,2 ; incorrect fat chain?
jb adr_not_found ; yes
cmp eax,[fatRESERVED] ; is it end of directory?
jb adr_new_cluster ; no. analyse it
cmp eax, 2 ; incorrect fat chain?
jb adr_not_found ; yes
cmp eax, [fatRESERVED]; is it end of directory?
jb adr_new_cluster ; no. analyse it
 
adr_not_found:
pop edi edi esi edx ecx ; first edi will remove ebx
stc ; file not found
ret
pop edi edi esi edx ecx; first edi will remove ebx
stc ; file not found
ret
 
adr_found:
pop edi edi esi edx ecx ; first edi will remove ebx
clc ; file found
ret
pop edi edi esi edx ecx; first edi will remove ebx
clc ; file found
ret
 
 
get_data_cluster:
484,59 → 488,59
; if CARRY=1 cluster out of range
; Note : if cluster=0 it's changed to read rootdir
;-----------------------------------------------------------
push eax ecx
push eax ecx
 
mov [fat16_root],0
cmp eax,[LAST_CLUSTER]
ja gdc_error ; too big cluster number, something is wrong
cmp eax,2
jnb gdc_cluster
mov [fat16_root], 0
cmp eax, [LAST_CLUSTER]
ja gdc_error ; too big cluster number, something is wrong
cmp eax, 2
jnb gdc_cluster
 
mov eax,[ROOT_CLUSTER] ; if cluster < 2 then read rootdir
cmp [fs_type],16
jne gdc_cluster
mov eax,[ROOT_START]
mov ecx,[ROOT_SECTORS] ; Note: not cluster size
mov [fat16_root],1 ; flag for fat16 rootdir
jmp gdc_read
mov eax, [ROOT_CLUSTER]; if cluster < 2 then read rootdir
cmp [fs_type], 16
jne gdc_cluster
mov eax, [ROOT_START]
mov ecx, [ROOT_SECTORS]; Note: not cluster size
mov [fat16_root], 1 ; flag for fat16 rootdir
jmp gdc_read
 
gdc_cluster:
sub eax,2
mov ecx,[SECTORS_PER_CLUSTER]
imul eax,ecx
add eax,[DATA_START]
sub eax, 2
mov ecx, [SECTORS_PER_CLUSTER]
imul eax, ecx
add eax, [DATA_START]
 
gdc_read:
test esi,esi ; first wanted block
je gdcl1 ; yes, skip count is 0
dec esi
jmp gdcl2
test esi, esi ; first wanted block
je gdcl1 ; yes, skip count is 0
dec esi
jmp gdcl2
 
gdcl1:
call hd_read
cmp [hd_error],0
jne gdc_error
call hd_read
cmp [hd_error], 0
jne gdc_error
 
add ebx,512 ; update pointer
dec edx
add ebx, 512 ; update pointer
dec edx
 
gdcl2:
test edx,edx ; is all read?
je out_of_read
test edx, edx ; is all read?
je out_of_read
 
inc eax ; next sector
dec ecx
jnz gdc_read
inc eax ; next sector
dec ecx
jnz gdc_read
 
out_of_read:
pop ecx eax
clc
ret
pop ecx eax
clc
ret
 
gdc_error:
pop ecx eax
stc
ret
pop ecx eax
stc
ret
 
 
get_cluster_of_a_path:
549,35 → 553,35
; output : if (CARRY=1) -> ERROR in the PATH
; if (CARRY=0) -> EAX=cluster
;---------------------------------------------------------
push ebx edx
push ebx edx
 
mov eax,[ROOT_CLUSTER]
mov edx,ebx
mov eax, [ROOT_CLUSTER]
mov edx, ebx
 
search_end_of_path:
cmp byte [edx],0
je found_end_of_path
cmp byte [edx], 0
je found_end_of_path
 
inc edx ; '/'
mov ebx,edx
call analyze_directory
jc directory_not_found
inc edx; '/'
mov ebx, edx
call analyze_directory
jc directory_not_found
 
mov eax,[ebx+20-2] ; read the HIGH 16bit cluster field
mov ax,[ebx+26] ; read the LOW 16bit cluster field
and eax,[fatMASK]
add edx,11 ; 8+3 (name+extension)
jmp search_end_of_path
mov eax, [ebx+20-2] ; read the HIGH 16bit cluster field
mov ax, [ebx+26] ; read the LOW 16bit cluster field
and eax, [fatMASK]
add edx, 11 ; 8+3 (name+extension)
jmp search_end_of_path
 
found_end_of_path:
pop edx ebx
clc ; no errors
ret
pop edx ebx
clc ; no errors
ret
 
directory_not_found:
pop edx ebx
stc ; errors occour
ret
pop edx ebx
stc ; errors occour
ret
 
 
bcd2bin:
586,11 → 590,11
; output : AH=0
; AL=decimal number (eg. 11)
;----------------------------------
xor ah,ah
shl ax,4
shr al,4
aad
ret
xor ah, ah
shl ax, 4
shr al, 4
aad
ret
 
 
get_date_for_file:
600,26 → 604,26
; 5..8 : month of year 1..12
; 9..15 : count of years from 1980
;-----------------------------------------------------
mov al,0x7 ;day
out 0x70,al
in al,0x71
call bcd2bin
ror eax,5
mov al, 0x7 ;day
out 0x70, al
in al, 0x71
call bcd2bin
ror eax, 5
 
mov al,0x8 ;month
out 0x70,al
in al,0x71
call bcd2bin
ror eax,4
mov al, 0x8 ;month
out 0x70, al
in al, 0x71
call bcd2bin
ror eax, 4
 
mov al,0x9 ;year
out 0x70,al
in al,0x71
call bcd2bin
add ax,20 ;because CMOS return only the two last
mov al, 0x9 ;year
out 0x70, al
in al, 0x71
call bcd2bin
add ax, 20 ;because CMOS return only the two last
;digit (eg. 2000 -> 00 , 2001 -> 01) and we
rol eax,9 ;need the difference with 1980 (eg. 2001-1980)
ret
rol eax, 9 ;need the difference with 1980 (eg. 2001-1980)
ret
 
 
get_time_for_file:
629,24 → 633,24
; 5..10 : minute 0..59
; 11..15 : hour 0..23
;-----------------------------------------------------
mov al,0x0 ;second
out 0x70,al
in al,0x71
call bcd2bin
ror eax,6
mov al, 0x0 ;second
out 0x70, al
in al, 0x71
call bcd2bin
ror eax, 6
 
mov al,0x2 ;minute
out 0x70,al
in al,0x71
call bcd2bin
ror eax,6
mov al, 0x2 ;minute
out 0x70, al
in al, 0x71
call bcd2bin
ror eax, 6
 
mov al,0x4 ;hour
out 0x70,al
in al,0x71
call bcd2bin
rol eax,11
ret
mov al, 0x4 ;hour
out 0x70, al
in al, 0x71
call bcd2bin
rol eax, 11
ret
 
 
set_current_time_for_entry:
654,13 → 658,13
; Set current time/date for file entry
; input : ebx = file entry pointer
;-----------------------------------------------------
push eax
call get_time_for_file ; update files date/time
mov [ebx+22],ax
call get_date_for_file
mov [ebx+24],ax
pop eax
ret
push eax
call get_time_for_file; update files date/time
mov [ebx+22], ax
call get_date_for_file
mov [ebx+24], ax
pop eax
ret
 
 
 
670,33 → 674,33
; Note : negative = remove clusters from free space
; positive = add clusters to free space
;-----------------------------------------------------
test ecx,ecx ; no change
je add_dfs_no
cmp [fs_type],32 ; free disk space only used by fat32
jne add_dfs_no
test ecx, ecx ; no change
je add_dfs_no
cmp [fs_type], 32 ; free disk space only used by fat32
jne add_dfs_no
 
push eax ebx
mov eax,[ADR_FSINFO]
mov ebx,fsinfo_buffer
call hd_read
cmp [hd_error],0
jne add_not_fs
push eax ebx
mov eax, [ADR_FSINFO]
mov ebx, fsinfo_buffer
call hd_read
cmp [hd_error], 0
jne add_not_fs
 
cmp dword [ebx+0x1fc],0xaa550000 ; check sector id
jne add_not_fs
cmp dword [ebx+0x1fc], 0xaa550000; check sector id
jne add_not_fs
 
add [ebx+0x1e8],ecx
push [fatStartScan]
pop dword [ebx+0x1ec]
call hd_write
add [ebx+0x1e8], ecx
push [fatStartScan]
pop dword [ebx+0x1ec]
call hd_write
; cmp [hd_error],0
; jne add_not_fs
 
add_not_fs:
pop ebx eax
pop ebx eax
 
add_dfs_no:
ret
ret
 
 
file_read:
723,113 → 727,113
jz fat_ok_for_reading
cmp [fs_type], 32
jz fat_ok_for_reading
xor ebx,ebx
mov eax,ERROR_UNKNOWN_FS
mov [hd1_status], ebx
ret
xor ebx, ebx
mov eax, ERROR_UNKNOWN_FS
mov [hd1_status], ebx
ret
 
fat_ok_for_reading:
; call reserve_hd1
 
pushad
pushad
 
mov ebx,edx
call get_cluster_of_a_path
jc file_to_read_not_found
mov ebx, edx
call get_cluster_of_a_path
jc file_to_read_not_found
 
test edi,edi ; read rootdir
jne no_read_root
test edi, edi ; read rootdir
jne no_read_root
 
xor eax,eax
call get_dir_size ; return rootdir size
cmp [hd_error],0
jne file_access_denied
xor eax, eax
call get_dir_size ; return rootdir size
cmp [hd_error], 0
jne file_access_denied
 
mov [file_size],eax
mov eax,[ROOT_CLUSTER]
jmp file_read_start
mov [file_size], eax
mov eax, [ROOT_CLUSTER]
jmp file_read_start
 
no_read_root:
mov ebx,PUSHAD_EAX ; file name
call analyze_directory
jc file_to_read_not_found
mov ebx, PUSHAD_EAX ; file name
call analyze_directory
jc file_to_read_not_found
 
mov eax,[ebx+28] ; file size
test byte [ebx+11],0x10 ; is it directory?
jz read_set_size ; no
mov eax, [ebx+28] ; file size
test byte [ebx+11], 0x10; is it directory?
jz read_set_size ; no
 
mov eax,[ebx+20-2] ; FAT entry
mov ax,[ebx+26]
and eax,[fatMASK]
call get_dir_size
cmp [hd_error],0
jne file_access_denied
mov eax, [ebx+20-2] ; FAT entry
mov ax, [ebx+26]
and eax, [fatMASK]
call get_dir_size
cmp [hd_error], 0
jne file_access_denied
 
read_set_size:
mov [file_size],eax
mov [file_size], eax
 
mov eax,[ebx+20-2] ; FAT entry
mov ax,[ebx+26]
and eax,[fatMASK]
mov eax, [ebx+20-2] ; FAT entry
mov ax, [ebx+26]
and eax, [fatMASK]
 
file_read_start:
mov ebx,PUSHAD_ECX ; pointer to buffer
mov edx,PUSHAD_EBX ; file blocks to read
mov esi,PUSHAD_ESI ; first 512 block to read
mov ebx, PUSHAD_ECX ; pointer to buffer
mov edx, PUSHAD_EBX ; file blocks to read
mov esi, PUSHAD_ESI ; first 512 block to read
 
file_read_new_cluster:
call get_data_cluster
jc file_read_eof ; end of file or cluster out of range
call get_data_cluster
jc file_read_eof ; end of file or cluster out of range
 
test edx,edx ; is all read?
je file_read_OK ; yes
test edx, edx ; is all read?
je file_read_OK ; yes
 
call get_FAT ; get next cluster
cmp [hd_error],0
jne file_access_denied
call get_FAT ; get next cluster
cmp [hd_error], 0
jne file_access_denied
 
cmp eax,[fatRESERVED] ; end of file
jnb file_read_eof
cmp eax,2 ; incorrect fat chain
jnb file_read_new_cluster
cmp eax, [fatRESERVED]; end of file
jnb file_read_eof
cmp eax, 2 ; incorrect fat chain
jnb file_read_new_cluster
 
popad
mov [hd1_status],0
mov ebx,[file_size]
mov eax,ERROR_FAT_TABLE
ret
popad
mov [hd1_status], 0
mov ebx, [file_size]
mov eax, ERROR_FAT_TABLE
ret
 
file_read_eof:
cmp [hd_error],0
jne file_access_denied
popad
mov [hd1_status],0
mov ebx,[file_size]
mov eax,ERROR_END_OF_FILE
ret
cmp [hd_error], 0
jne file_access_denied
popad
mov [hd1_status], 0
mov ebx, [file_size]
mov eax, ERROR_END_OF_FILE
ret
 
file_read_OK:
popad
mov [hd1_status],0
mov ebx,[file_size]
xor eax,eax
ret
popad
mov [hd1_status], 0
mov ebx, [file_size]
xor eax, eax
ret
 
file_to_read_not_found:
cmp [hd_error],0
jne file_access_denied
popad
mov [hd1_status],0
xor ebx,ebx
mov eax,ERROR_FILE_NOT_FOUND
ret
cmp [hd_error], 0
jne file_access_denied
popad
mov [hd1_status], 0
xor ebx, ebx
mov eax, ERROR_FILE_NOT_FOUND
ret
 
file_access_denied:
popad
mov [hd1_status],0
xor ebx,ebx
mov eax,ERROR_ACCESS_DENIED
ret
popad
mov [hd1_status], 0
xor ebx, ebx
mov eax, ERROR_ACCESS_DENIED
ret
 
get_dir_size:
;-----------------------------------------------------
836,36 → 840,36
; input : eax = first cluster (0=rootdir)
; output : eax = directory size in bytes
;-----------------------------------------------------
push edx
xor edx,edx ; count of directory clusters
test eax,eax
jnz dir_size_next
push edx
xor edx, edx ; count of directory clusters
test eax, eax
jnz dir_size_next
 
mov eax,[ROOT_SECTORS]
shl eax,9 ; fat16 rootdir size in bytes
cmp [fs_type],16
je dir_size_ret
mov eax,[ROOT_CLUSTER]
mov eax, [ROOT_SECTORS]
shl eax, 9 ; fat16 rootdir size in bytes
cmp [fs_type], 16
je dir_size_ret
mov eax, [ROOT_CLUSTER]
 
dir_size_next:
cmp eax,2 ; incorrect fat chain
jb dir_size_end
cmp eax,[fatRESERVED] ; end of directory
ja dir_size_end
call get_FAT ; get next cluster
cmp [hd_error],0
jne dir_size_ret
cmp eax, 2 ; incorrect fat chain
jb dir_size_end
cmp eax, [fatRESERVED]; end of directory
ja dir_size_end
call get_FAT ; get next cluster
cmp [hd_error], 0
jne dir_size_ret
 
inc edx
jmp dir_size_next
inc edx
jmp dir_size_next
 
dir_size_end:
imul eax,[SECTORS_PER_CLUSTER],512 ; cluster size in bytes
imul eax,edx
imul eax, [SECTORS_PER_CLUSTER], 512; cluster size in bytes
imul eax, edx
 
dir_size_ret:
pop edx
ret
pop edx
ret
 
 
clear_cluster_chain:
872,31 → 876,31
;-----------------------------------------------------
; input : eax = first cluster
;-----------------------------------------------------
push eax ecx edx
xor ecx,ecx ; cluster count
push eax ecx edx
xor ecx, ecx ; cluster count
 
clean_new_chain:
cmp eax,[LAST_CLUSTER] ; end of file
ja delete_OK
cmp eax,2 ; unfinished fat chain or zero length file
jb delete_OK
cmp eax,[ROOT_CLUSTER] ; don't remove root cluster
jz delete_OK
cmp eax, [LAST_CLUSTER]; end of file
ja delete_OK
cmp eax, 2 ; unfinished fat chain or zero length file
jb delete_OK
cmp eax, [ROOT_CLUSTER]; don't remove root cluster
jz delete_OK
 
xor edx,edx
call set_FAT ; clear fat entry
cmp [hd_error],0
jne access_denied_01
xor edx, edx
call set_FAT ; clear fat entry
cmp [hd_error], 0
jne access_denied_01
 
inc ecx ; update cluster count
mov eax,edx ; old cluster
jmp clean_new_chain
inc ecx ; update cluster count
mov eax, edx ; old cluster
jmp clean_new_chain
 
delete_OK:
call add_disk_free_space ; add clusters to free disk space
call add_disk_free_space; add clusters to free disk space
access_denied_01:
pop edx ecx eax
ret
pop edx ecx eax
ret
 
 
get_hd_info:
912,65 → 916,65
jz info_fat_ok
cmp [fs_type], 32
jz info_fat_ok
xor edx,edx
xor ebx,ebx
xor ecx,ecx
mov eax,ERROR_UNKNOWN_FS
ret
xor edx, edx
xor ebx, ebx
xor ecx, ecx
mov eax, ERROR_UNKNOWN_FS
ret
 
info_fat_ok:
; call reserve_hd1
 
xor ecx,ecx ; count of free clusters
mov eax,2
mov ebx,[LAST_CLUSTER]
xor ecx, ecx ; count of free clusters
mov eax, 2
mov ebx, [LAST_CLUSTER]
 
info_cluster:
push eax
call get_FAT ; get cluster info
cmp [hd_error],0
jne info_access_denied
push eax
call get_FAT ; get cluster info
cmp [hd_error], 0
jne info_access_denied
 
test eax,eax ; is it free?
jnz info_used ; no
inc ecx
test eax, eax ; is it free?
jnz info_used ; no
inc ecx
 
info_used:
pop eax
inc eax
cmp eax,ebx ; is above last cluster?
jbe info_cluster ; no. test next cluster
pop eax
inc eax
cmp eax, ebx ; is above last cluster?
jbe info_cluster ; no. test next cluster
 
dec ebx ; cluster count
imul edx,[SECTORS_PER_CLUSTER],512 ; cluster size in bytes
mov [hd1_status],0
xor eax,eax
ret
dec ebx ; cluster count
imul edx, [SECTORS_PER_CLUSTER], 512; cluster size in bytes
mov [hd1_status], 0
xor eax, eax
ret
 
info_access_denied:
add esp,4
xor edx,edx
xor ebx,ebx
xor ecx,ecx
mov eax,ERROR_ACCESS_DENIED
ret
add esp, 4
xor edx, edx
xor ebx, ebx
xor ecx, ecx
mov eax, ERROR_ACCESS_DENIED
ret
 
update_disk:
;-----------------------------------------------------------
; write changed fat and cache to disk
;-----------------------------------------------------------
cmp [fat_change],0 ; is fat changed?
je upd_no_change
cmp [fat_change], 0 ; is fat changed?
je upd_no_change
 
call write_fat_sector
cmp [hd_error],0
jne update_disk_acces_denied
call write_fat_sector
cmp [hd_error], 0
jne update_disk_acces_denied
 
upd_no_change:
 
call write_cache
call write_cache
update_disk_acces_denied:
ret
ret
 
 
; \begin{diamond}
1049,44 → 1053,46
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
@@:
push edi
cmp byte [esi], 0
jnz @f
push edi
cmp byte [esi], 0
jnz @f
.noaccess:
pop edi
pop edi
.noaccess_2:
or ebx, -1
mov eax, ERROR_ACCESS_DENIED
ret
or ebx, -1
mov eax, ERROR_ACCESS_DENIED
ret
 
@@:
call hd_find_lfn
jnc .found
pop edi
cmp [hd_error],0
jne .noaccess_2
or ebx, -1
mov eax, ERROR_FILE_NOT_FOUND
ret
call hd_find_lfn
jnc .found
pop edi
cmp [hd_error], 0
jne .noaccess_2
or ebx, -1
mov eax, ERROR_FILE_NOT_FOUND
ret
 
.found:
test byte [edi+11], 0x10 ; do not allow read directories
jnz .noaccess
test ebx, ebx
jz .l1
cmp dword [ebx+4], 0
jz @f
test byte [edi+11], 0x10; do not allow read directories
jnz .noaccess
test ebx, ebx
jz .l1
cmp dword [ebx+4], 0
jz @f
xor ebx, ebx
.reteof:
mov eax, 6
pop edi
ret
mov eax, 6
pop edi
ret
@@:
mov ebx, [ebx]
mov ebx, [ebx]
.l1:
push ecx edx
push 0
1098,74 → 1104,74
mov ecx, eax
mov byte [esp], 6
@@:
mov eax, [edi+20-2]
mov ax, [edi+26]
mov eax, [edi+20-2]
mov ax, [edi+26]
; now eax=cluster, ebx=position, ecx=count, edx=buffer for data
.new_cluster:
jecxz .new_sector
test eax, eax
jz .eof
cmp eax, [fatRESERVED]
jae .eof
mov [cluster_tmp], eax
dec eax
dec eax
mov edi, [SECTORS_PER_CLUSTER]
imul eax, edi
add eax, [DATA_START]
jecxz .new_sector
test eax, eax
jz .eof
cmp eax, [fatRESERVED]
jae .eof
mov [cluster_tmp], eax
dec eax
dec eax
mov edi, [SECTORS_PER_CLUSTER]
imul eax, edi
add eax, [DATA_START]
.new_sector:
test ecx, ecx
jz .done
sub ebx, 512
jae .skip
add ebx, 512
jnz .force_buf
cmp ecx, 512
jb .force_buf
test ecx, ecx
jz .done
sub ebx, 512
jae .skip
add ebx, 512
jnz .force_buf
cmp ecx, 512
jb .force_buf
; we may read directly to given buffer
push ebx
mov ebx, edx
call hd_read
pop ebx
cmp [hd_error],0
jne .noaccess_1
add edx, 512
sub ecx, 512
jmp .skip
push ebx
mov ebx, edx
call hd_read
pop ebx
cmp [hd_error], 0
jne .noaccess_1
add edx, 512
sub ecx, 512
jmp .skip
.force_buf:
; we must read sector to temporary buffer and then copy it to destination
push eax ebx
mov ebx, buffer
call hd_read
mov eax, ebx
pop ebx
cmp [hd_error],0
jne .noaccess_3
add eax, ebx
push ecx
add ecx, ebx
cmp ecx, 512
jbe @f
mov ecx, 512
push eax ebx
mov ebx, buffer
call hd_read
mov eax, ebx
pop ebx
cmp [hd_error], 0
jne .noaccess_3
add eax, ebx
push ecx
add ecx, ebx
cmp ecx, 512
jbe @f
mov ecx, 512
@@:
sub ecx, ebx
mov ebx, edx
call memmove
add edx, ecx
sub [esp], ecx
pop ecx
pop eax
xor ebx, ebx
sub ecx, ebx
mov ebx, edx
call memmove
add edx, ecx
sub [esp], ecx
pop ecx
pop eax
xor ebx, ebx
.skip:
inc eax
dec edi
jnz .new_sector
mov eax, [cluster_tmp]
call get_FAT
cmp [hd_error],0
jne .noaccess_1
inc eax
dec edi
jnz .new_sector
mov eax, [cluster_tmp]
call get_FAT
cmp [hd_error], 0
jne .noaccess_1
 
jmp .new_cluster
jmp .new_cluster
.noaccess_3:
pop eax
.noaccess_1:
1200,6 → 1206,8
fs_HdReadFolder:
cmp [fs_type], 1
jz ntfs_HdReadFolder
cmp [fs_type], 2
jz ext2_HdReadFolder
cmp [fs_type], 16
jz @f
cmp [fs_type], 32
1241,7 → 1249,7
mov edi, edx
mov ecx, 32/4
xor eax, eax
rep stosd
rep stosd
pop ecx eax
mov byte [edx], 1 ; version
mov esi, edi ; esi points to BDFE
1520,7 → 1528,7
mov edi, buffer
push edi
xor eax, eax
rep stosd
rep stosd
pop edi
pop ecx
mov eax, [esp+4]
1586,6 → 1594,8
.common:
cmp [fs_type], 1
jz ntfs_HdRewrite
cmp [fs_type], 2
jz ext2_HdRewrite
cmp [fs_type], 16
jz @f
cmp [fs_type], 32
1758,7 → 1768,7
jz .test_short_name_cont
mov ecx, 11
push esi edi
repz cmpsb
repz cmpsb
pop edi esi
jz .short_name_found
.test_short_name_cont:
1783,7 → 1793,7
mov al, '~'
push ecx edi
mov ecx, 8
repnz scasb
repnz scasb
push 1
pop eax ; 1 entry
jnz .notilde
1914,7 → 1924,7
.nolfn:
xchg esi, [esp]
mov ecx, 11
rep movsb
rep movsb
mov word [edi], 20h ; attributes
sub edi, 11
pop esi ecx
1989,13 → 1999,13
push ecx
mov edi, buffer
mov ebx, edi
rep movsb
rep movsb
.writedircont:
mov ecx, buffer+0x200
sub ecx, edi
push eax
xor eax, eax
rep stosb
rep stosb
pop eax
pop ecx
.writecommon:
2068,7 → 2078,7
dec dword [esp+16]
push esi
mov ecx, 32/4
rep movsd
rep movsd
pop esi
mov dword [edi-32], '. '
mov dword [edi-32+4], ' '
2076,7 → 2086,7
mov byte [edi-32+11], 10h
push esi
mov ecx, 32/4
rep movsd
rep movsd
pop esi
mov dword [edi-32], '.. '
mov dword [edi-32+4], ' '
2120,6 → 2130,8
fs_HdWrite:
cmp [fs_type], 1
jz ntfs_HdWrite
cmp [fs_type], 2
jz ext2_HdWrite
cmp [fs_type], 16
jz @f
cmp [fs_type], 32
2286,7 → 2298,7
jbe @f
mov edi, buffer
add edi, [esp+4+12]
rep stosb
rep stosb
@@:
; zero uninitialized data in the last sector
mov ecx, 0x200
2294,7 → 2306,7
jbe @f
mov edi, buffer
add edi, esi
rep stosb
rep stosb
@@:
pop edi ecx
; copy new data
2336,7 → 2348,8
sub dword [esp], 0x200
jae @f
and dword [esp], 0
@@: jmp .write_loop
@@:
jmp .write_loop
 
hd_extend_file.zero_size:
xor eax, eax
2445,7 → 2458,8
cmp [hd_error], 0
jz @f
mov al, 11
@@: stc
@@:
stc
ret
 
;----------------------------------------------------------------
2463,6 → 2477,8
fs_HdSetFileEnd:
cmp [fs_type], 1
jz ntfs_HdSetFileEnd
cmp [fs_type], 2
jz ext2_HdSetFileEnd
cmp [fs_type], 16
jz @f
cmp [fs_type], 32
2578,7 → 2594,7
push eax
xor eax, eax
mov [esp+12], eax
rep stosb
rep stosb
pop eax
pop edi
call hd_write
2678,7 → 2694,7
mov ecx, 0x200
sub ecx, eax
xor eax, eax
rep stosb
rep stosb
pop eax
call hd_write
pop ebx
2695,6 → 2711,8
fs_HdGetFileInfo:
cmp [fs_type], 1
jz ntfs_HdGetFileInfo
cmp [fs_type], 2
jz ext2_HdGetFileInfo
cmp [fs_type], 16
jz @f
cmp [fs_type], 32
2723,6 → 2741,8
fs_HdSetFileInfo:
cmp [fs_type], 1
jz ntfs_HdSetFileInfo
cmp [fs_type], 2
jz ext2_HdSetFileInfo
cmp [fs_type], 16
jz @f
cmp [fs_type], 32
2773,6 → 2793,8
fs_HdDelete:
cmp [fs_type], 1
jz ntfs_HdDelete
cmp [fs_type], 2
jz ext2_HdDelete
cmp [fs_type], 16
jz @f
cmp [fs_type], 32
/kernel/branches/net/fs/fs.inc
21,12 → 21,14
 
 
iglobal
dir0: db 'HARDDISK '
dir0:
db 'HARDDISK '
db 'RAMDISK '
db 'FLOPPYDISK '
db 0
 
dir1: db 'FIRST '
dir1:
db 'FIRST '
db 'SECOND '
db 'THIRD '
db 'FOURTH '
34,7 → 36,8
 
not_select_IDE db 0
 
hd_address_table: dd 0x1f0,0x00,0x1f0,0x10
hd_address_table:
dd 0x1f0,0x00,0x1f0,0x10
dd 0x170,0x00,0x170,0x10
endg
 
89,178 → 92,178
; Extract parameters
; add eax, std_application_base_address ; abs start of info block
 
cmp dword [eax+0],15 ; GET_DISK_INFO
je fs_info
cmp dword [eax+0], 15; GET_DISK_INFO
je fs_info
 
cmp dword [CURRENT_TASK],1 ; no memory checks for kernel requests
jz no_checks_for_kernel
mov edx,eax
cmp dword [eax+0],1
jnz .usual_check
mov ebx,[eax+12]
cmp dword [CURRENT_TASK], 1; no memory checks for kernel requests
jz no_checks_for_kernel
mov edx, eax
cmp dword [eax+0], 1
jnz .usual_check
mov ebx, [eax+12]
; add ebx,std_application_base_address
mov ecx,[eax+8]
call check_region
test eax,eax
jnz area_in_app_mem
mov ecx, [eax+8]
call check_region
test eax, eax
jnz area_in_app_mem
 
.error_output:
mov esi,buffer_failed
call sys_msg_board_str
mov esi, buffer_failed
call sys_msg_board_str
; mov eax,7
mov dword [esp+36],7
ret
mov dword [esp+36], 7
ret
iglobal
buffer_failed db 'K : Buffer check failed',13,10,0
endg
.usual_check:
cmp dword [eax+0],0
mov ecx,512
jnz .small_size
mov ecx,[eax+8]
shl ecx,9
cmp dword [eax+0], 0
mov ecx, 512
jnz .small_size
mov ecx, [eax+8]
shl ecx, 9
.small_size:
mov ebx,[eax+12]
mov ebx, [eax+12]
; add ebx,std_application_base_address
call check_region
test eax,eax
jz .error_output
call check_region
test eax, eax
jz .error_output
area_in_app_mem:
mov eax,edx
mov eax, edx
no_checks_for_kernel:
 
fs_read:
 
mov ebx,[eax+20] ; program wants root directory ?
test bl,bl
je fs_getroot
test bh,bh
jne fs_noroot
mov ebx, [eax+20] ; program wants root directory ?
test bl, bl
je fs_getroot
test bh, bh
jne fs_noroot
fs_getroot:
; \begin{diamond}[18.03.2006]
; root - only read is allowed
; other operations return "access denied", eax=10
; (execute operation returns eax=-10)
cmp dword [eax], 0
jz .read_root
mov dword [esp+36], 10
ret
cmp dword [eax], 0
jz .read_root
mov dword [esp+36], 10
ret
.read_root:
; \end{diamond}[18.03.2006]
mov esi,dir0
mov edi,[eax+12]
mov esi, dir0
mov edi, [eax+12]
; add edi,std_application_base_address
mov ecx,11
push ecx
mov ecx, 11
push ecx
; cld ; already is
rep movsb
mov al,0x10
stosb
add edi,32-11-1
pop ecx
rep movsb
stosb
and dword [esp+36],0 ; ok read
mov dword [esp+24],32*2 ; size of root
ret
rep movsb
mov al, 0x10
stosb
add edi, 32-11-1
pop ecx
rep movsb
stosb
and dword [esp+36], 0; ok read
mov dword [esp+24], 32*2; size of root
ret
 
fs_info: ;start of code - Mihasik
push eax
cmp [eax+21],byte 'h'
je fs_info_h
cmp [eax+21],byte 'H'
je fs_info_h
cmp [eax+21],byte 'r'
je fs_info_r
cmp [eax+21],byte 'R'
je fs_info_r
mov eax,3 ;if unknown disk
xor ebx,ebx
xor ecx,ecx
xor edx,edx
jmp fs_info1
push eax
cmp [eax+21], byte 'h'
je fs_info_h
cmp [eax+21], byte 'H'
je fs_info_h
cmp [eax+21], byte 'r'
je fs_info_r
cmp [eax+21], byte 'R'
je fs_info_r
mov eax, 3 ;if unknown disk
xor ebx, ebx
xor ecx, ecx
xor edx, edx
jmp fs_info1
fs_info_r:
call ramdisk_free_space ;if ramdisk
mov ecx,edi ;free space in ecx
shr ecx,9 ;free clusters
mov ebx,2847 ;total clusters
mov edx,512 ;cluster size
xor eax,eax ;always 0
jmp fs_info1
call ramdisk_free_space;if ramdisk
mov ecx, edi ;free space in ecx
shr ecx, 9 ;free clusters
mov ebx, 2847 ;total clusters
mov edx, 512 ;cluster size
xor eax, eax ;always 0
jmp fs_info1
fs_info_h: ;if harddisk
call get_hd_info
call get_hd_info
fs_info1:
pop edi
mov [esp+36],eax
mov [esp+24],ebx ; total clusters on disk
mov [esp+32],ecx ; free clusters on disk
mov [edi],edx ; cluster size in bytes
ret ;end of code - Mihasik
pop edi
mov [esp+36], eax
mov [esp+24], ebx ; total clusters on disk
mov [esp+32], ecx ; free clusters on disk
mov [edi], edx ; cluster size in bytes
ret ;end of code - Mihasik
 
fs_noroot:
 
push dword [eax+0] ; read/write/delete/.../makedir/rename/lba/run
push dword [eax+4] ; 512 block number to read
push dword [eax+8] ; bytes to write/append or 512 blocks to read
mov ebx,[eax+12]
push dword [eax+0] ; read/write/delete/.../makedir/rename/lba/run
push dword [eax+4] ; 512 block number to read
push dword [eax+8] ; bytes to write/append or 512 blocks to read
mov ebx, [eax+12]
; add ebx,std_application_base_address
push ebx ; abs start of return/save area
push ebx ; abs start of return/save area
 
lea esi,[eax+20] ; abs start of dir + filename
mov edi,[eax+16]
lea esi, [eax+20] ; abs start of dir + filename
mov edi, [eax+16]
; add edi,std_application_base_address ; abs start of work area
 
call expand_pathz
call expand_pathz
 
push edi ; dir start
push ebx ; name of file start
push edi ; dir start
push ebx ; name of file start
 
mov eax,[edi+1]
cmp eax,'RD '
je fs_yesramdisk
cmp eax,'RAMD'
jne fs_noramdisk
mov eax, [edi+1]
cmp eax, 'RD '
je fs_yesramdisk
cmp eax, 'RAMD'
jne fs_noramdisk
 
fs_yesramdisk:
 
cmp byte [edi+1+11],0
je fs_give_dir1
cmp byte [edi+1+11], 0
je fs_give_dir1
 
mov eax,[edi+1+12]
cmp eax,'1 '
je fs_yesramdisk_first
cmp eax,'FIRS'
jne fs_noramdisk
mov eax, [edi+1+12]
cmp eax, '1 '
je fs_yesramdisk_first
cmp eax, 'FIRS'
jne fs_noramdisk
 
fs_yesramdisk_first:
 
cmp dword [esp+20],8 ; LBA read ramdisk
jne fs_no_LBA_read_ramdisk
cmp dword [esp+20], 8; LBA read ramdisk
jne fs_no_LBA_read_ramdisk
 
mov eax,[esp+16] ; LBA block to read
mov ecx,[esp+8] ; abs pointer to return area
mov eax, [esp+16] ; LBA block to read
mov ecx, [esp+8] ; abs pointer to return area
 
call LBA_read_ramdisk
jmp file_system_return
call LBA_read_ramdisk
jmp file_system_return
 
 
fs_no_LBA_read_ramdisk:
 
cmp dword [esp+20],0 ; READ
jne fs_noramdisk_read
cmp dword [esp+20], 0; READ
jne fs_noramdisk_read
 
mov eax,[esp+4] ; fname
add eax,2*12+1
mov ebx,[esp+16] ; block start
inc ebx
mov ecx,[esp+12] ; block count
mov edx,[esp+8] ; return
mov esi,[esp+0]
sub esi,eax
add esi,12+1 ; file name length
call fileread
mov eax, [esp+4] ; fname
add eax, 2*12+1
mov ebx, [esp+16] ; block start
inc ebx
mov ecx, [esp+12] ; block count
mov edx, [esp+8] ; return
mov esi, [esp+0]
sub esi, eax
add esi, 12+1 ; file name length
call fileread
 
jmp file_system_return
jmp file_system_return
 
 
fs_noramdisk_read:
267,50 → 270,50
fs_noramdisk:
 
;********************************************************************
mov eax,[edi+1]
cmp eax,'FD '
je fs_yesflpdisk
cmp eax,'FLOP'
jne fs_noflpdisk
mov eax, [edi+1]
cmp eax, 'FD '
je fs_yesflpdisk
cmp eax, 'FLOP'
jne fs_noflpdisk
 
fs_yesflpdisk:
call reserve_flp
call reserve_flp
 
cmp byte [edi+1+11],0
je fs_give_dir1
cmp byte [edi+1+11], 0
je fs_give_dir1
 
mov eax,[edi+1+12]
cmp eax,'1 '
je fs_yesflpdisk_first
cmp eax,'FIRS'
je fs_yesflpdisk_first
cmp eax,'2 '
je fs_yesflpdisk_second
cmp eax,'SECO'
jne fs_noflpdisk
jmp fs_yesflpdisk_second
mov eax, [edi+1+12]
cmp eax, '1 '
je fs_yesflpdisk_first
cmp eax, 'FIRS'
je fs_yesflpdisk_first
cmp eax, '2 '
je fs_yesflpdisk_second
cmp eax, 'SECO'
jne fs_noflpdisk
jmp fs_yesflpdisk_second
 
fs_yesflpdisk_first:
mov [flp_number],1
jmp fs_yesflpdisk_start
mov [flp_number], 1
jmp fs_yesflpdisk_start
fs_yesflpdisk_second:
mov [flp_number],2
mov [flp_number], 2
fs_yesflpdisk_start:
cmp dword [esp+20],0 ; READ
jne fs_noflpdisk_read
cmp dword [esp+20], 0; READ
jne fs_noflpdisk_read
 
mov eax,[esp+4] ; fname
add eax,2*12+1
mov ebx,[esp+16] ; block start
inc ebx
mov ecx,[esp+12] ; block count
mov edx,[esp+8] ; return
mov esi,[esp+0]
sub esi,eax
add esi,12+1 ; file name length
call floppy_fileread
mov eax, [esp+4] ; fname
add eax, 2*12+1
mov ebx, [esp+16] ; block start
inc ebx
mov ecx, [esp+12] ; block count
mov edx, [esp+8] ; return
mov esi, [esp+0]
sub esi, eax
add esi, 12+1 ; file name length
call floppy_fileread
 
jmp file_system_return
jmp file_system_return
 
 
fs_noflpdisk_read:
317,166 → 320,166
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
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
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
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
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
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
jmp fs_for_new_semantic
 
choice_necessity_partition:
mov eax,[edi+1+12]
call StringToNumber
mov [fat32part],eax
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
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 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
mov ebx, [edx]
add edx, 4
add eax, ebx
loop @b
jmp .f
.s:
sub eax,ebx
sub eax, ebx
.f:
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
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 '
je fs_yesharddisk
cmp eax,'HARD'
jne fs_noharddisk
mov eax, [edi+1]
cmp eax, 'HD '
je fs_yesharddisk
cmp eax, 'HARD'
jne fs_noharddisk
 
fs_yesharddisk:
cmp dword [esp+20],8 ; LBA read
jne fs_no_LBA_read
mov eax,[esp+16] ; LBA block to read
lea ebx,[edi+1+12] ; pointer to FIRST/SECOND/THIRD/FOURTH
mov ecx,[esp+8] ; abs pointer to return area
call LBA_read
jmp file_system_return
cmp dword [esp+20], 8; LBA read
jne fs_no_LBA_read
mov eax, [esp+16] ; LBA block to read
lea ebx, [edi+1+12] ; pointer to FIRST/SECOND/THIRD/FOURTH
mov ecx, [esp+8] ; abs pointer to return area
call LBA_read
jmp file_system_return
 
fs_no_LBA_read:
 
cmp byte [edi+1+11],0 ; directory read
je fs_give_dir1
call reserve_hd1
cmp byte [edi+1+11], 0; directory read
je fs_give_dir1
call reserve_hd1
fs_for_new_semantic:
call choice_necessity_partition
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
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
jmp file_system_return
@@:
 
cmp dword [esp+20],0 ; READ
jne fs_noharddisk_read
cmp dword [esp+20], 0; READ
jne fs_noharddisk_read
 
mov eax,[esp+0] ; /fname
lea edi,[eax+12]
mov byte [eax],0 ; path to asciiz
inc eax ; filename start
mov eax, [esp+0] ; /fname
lea edi, [eax+12]
mov byte [eax], 0 ; path to asciiz
inc eax ; filename start
 
mov ebx,[esp+12] ; count to read
mov ecx,[esp+8] ; buffer
mov edx,[esp+4]
add edx,12*2 ; dir start
sub edi,edx ; path length
mov esi,[esp+16] ; blocks to read
mov ebx, [esp+12] ; count to read
mov ecx, [esp+8] ; buffer
mov edx, [esp+4]
add edx, 12*2 ; dir start
sub edi, edx ; path length
mov esi, [esp+16] ; blocks to read
 
call file_read
call file_read
 
mov edi,[esp+0]
mov byte [edi],'/'
mov edi, [esp+0]
mov byte [edi], '/'
 
call free_hd_channel
and [hd1_status], 0
jmp file_system_return
call free_hd_channel
and [hd1_status], 0
jmp file_system_return
 
fs_noharddisk_read:
 
call free_hd_channel
and [hd1_status], 0
call free_hd_channel
and [hd1_status], 0
 
fs_noharddisk:
; \begin{diamond}[18.03.2006]
mov eax, 5 ; file not found
mov eax, 5 ; file not found
; à ìîæåò áûòü, âîçâðàùàòü äðóãîé êîä îøèáêè?
mov ebx, [esp+24+24] ; do not change ebx in application
mov ebx, [esp+24+24]; do not change ebx in application
; \end{diamond}[18.03.2006]
 
file_system_return:
 
add esp,24
add esp, 24
 
mov [esp+36],eax
mov [esp+24],ebx
ret
mov [esp+36], eax
mov [esp+24], ebx
ret
 
 
fs_give_dir1:
485,72 → 488,72
; /RD,/FD,/HD - only read is allowed
; other operations return "access denied", eax=10
; (execute operation returns eax=-10)
cmp dword [esp+20], 0
jz .read
add esp, 20
pop ecx
mov dword [esp+36], 10
ret
cmp dword [esp+20], 0
jz .read
add esp, 20
pop ecx
mov dword [esp+36], 10
ret
.read:
; \end{diamond}[18.03.2006]
mov al,0x10
mov ebx,1
mov edi,[esp+8]
mov esi,dir1
mov al, 0x10
mov ebx, 1
mov edi, [esp+8]
mov esi, dir1
fs_d1_new:
mov ecx,11
mov ecx, 11
; cld
rep movsb
stosb
add edi,32-11-1
dec ebx
jne fs_d1_new
rep movsb
stosb
add edi, 32-11-1
dec ebx
jne fs_d1_new
 
add esp,24
add esp, 24
 
and dword [esp+36],0 ; ok read
mov dword [esp+24],32*1 ; dir/data size
ret
and dword [esp+36], 0; ok read
mov dword [esp+24], 32*1; dir/data size
ret
 
 
 
LBA_read_ramdisk:
 
cmp [lba_read_enabled],1
je lbarrl1
cmp [lba_read_enabled], 1
je lbarrl1
 
xor ebx,ebx
mov eax,2
ret
xor ebx, ebx
mov eax, 2
ret
 
lbarrl1:
 
cmp eax,18*2*80
jb lbarrl2
xor ebx,ebx
mov eax,3
ret
cmp eax, 18*2*80
jb lbarrl2
xor ebx, ebx
mov eax, 3
ret
 
lbarrl2:
 
pushad
pushad
 
call restorefatchain
call restorefatchain
 
mov edi,ecx
mov esi,eax
mov edi, ecx
mov esi, eax
 
shl esi,9
add esi,RAMDISK
mov ecx,512/4
shl esi, 9
add esi, RAMDISK
mov ecx, 512/4
; cld
rep movsd
rep movsd
 
popad
popad
 
xor ebx,ebx
xor eax,eax
ret
xor ebx, ebx
xor eax, eax
ret
 
LBA_read:
 
560,106 → 563,106
; ebx = pointer to FIRST/SECOND/THIRD/FOURTH
; ecx = abs pointer to return area
 
cmp [lba_read_enabled],1
je lbarl1
mov eax,2
ret
cmp [lba_read_enabled], 1
je lbarl1
mov eax, 2
ret
 
lbarl1:
 
call reserve_hd1
call reserve_hd1
 
push eax
push ecx
push eax
push ecx
 
mov edi,hd_address_table
mov esi,dir1
mov eax,[ebx]
mov edx,'1 '
mov ecx,4
mov edi, hd_address_table
mov esi, dir1
mov eax, [ebx]
mov edx, '1 '
mov ecx, 4
blar0:
cmp eax,[esi]
je blar2
cmp eax,edx
je blar2
inc edx
add edi,8
add esi,11
dec ecx
jnz blar0
cmp eax, [esi]
je blar2
cmp eax, edx
je blar2
inc edx
add edi, 8
add esi, 11
dec ecx
jnz blar0
 
mov eax,1
mov ebx,1
jmp LBA_read_ret
mov eax, 1
mov ebx, 1
jmp LBA_read_ret
 
blar2:
mov eax,[edi+0]
mov ebx,[edi+4]
mov eax, [edi+0]
mov ebx, [edi+4]
 
mov [hdbase],eax
mov [hdid],ebx
mov [hdbase], eax
mov [hdid], ebx
 
call wait_for_hd_idle
cmp [hd_error],0
jne hd_lba_error
call wait_for_hd_idle
cmp [hd_error], 0
jne hd_lba_error
 
; eax = hd port
; ebx = set for primary (0x00) or slave (0x10)
 
cli
cli
 
mov edx,eax
inc edx
xor eax,eax
out dx,al
inc edx
inc eax
out dx,al
inc edx
mov eax,[esp+4]
out dx,al
shr eax,8
inc edx
out dx,al
shr eax,8
inc edx
out dx,al
shr eax,8
inc edx
and al,1+2+4+8
add al,bl
add al,128+64+32
out dx,al
mov edx, eax
inc edx
xor eax, eax
out dx, al
inc edx
inc eax
out dx, al
inc edx
mov eax, [esp+4]
out dx, al
shr eax, 8
inc edx
out dx, al
shr eax, 8
inc edx
out dx, al
shr eax, 8
inc edx
and al, 1+2+4+8
add al, bl
add al, 128+64+32
out dx, al
 
inc edx
mov al,20h
out dx,al
inc edx
mov al, 20h
out dx, al
 
sti
sti
 
call wait_for_sector_buffer
cmp [hd_error],0
jne hd_lba_error
call wait_for_sector_buffer
cmp [hd_error], 0
jne hd_lba_error
 
cli
cli
 
mov edi,[esp+0]
mov ecx,256
sub edx,7
cld
rep insw
mov edi, [esp+0]
mov ecx, 256
sub edx, 7
cld
rep insw
 
sti
sti
 
xor eax,eax
xor ebx,ebx
xor eax, eax
xor ebx, ebx
 
LBA_read_ret:
mov [hd_error],0
mov [hd1_status],0
add esp,2*4
mov [hd_error], 0
mov [hd1_status], 0
add esp, 2*4
 
ret
ret
 
 
expand_pathz:
671,66 → 674,66
; ebx = /file name - zero terminated
; esi = pointer after source
 
push eax
push ecx
push edi ;[esp+0]
push eax
push ecx
push edi;[esp+0]
 
pathz_start:
mov byte [edi],'/'
inc edi
mov al,32
mov ecx,11
cld
rep stosb ; clear filename area
sub edi,11
mov ebx,edi ; start of dir/file name
mov byte [edi], '/'
inc edi
mov al, 32
mov ecx, 11
cld
rep stosb ; clear filename area
sub edi, 11
mov ebx, edi ; start of dir/file name
 
pathz_new_char:
mov al,[esi]
inc esi
cmp al,0
je pathz_end
mov al, [esi]
inc esi
cmp al, 0
je pathz_end
 
cmp al,'/'
jne pathz_not_path
cmp edi,ebx ; skip first '/'
jz pathz_new_char
lea edi,[ebx+11] ; start of next directory
jmp pathz_start
cmp al, '/'
jne pathz_not_path
cmp edi, ebx ; skip first '/'
jz pathz_new_char
lea edi, [ebx+11] ; start of next directory
jmp pathz_start
 
pathz_not_path:
cmp al,'.'
jne pathz_not_ext
lea edi,[ebx+8] ; start of extension
jmp pathz_new_char
cmp al, '.'
jne pathz_not_ext
lea edi, [ebx+8] ; start of extension
jmp pathz_new_char
 
pathz_not_ext:
cmp al,'a'
jb pathz_not_low
cmp al,'z'
ja pathz_not_low
sub al,0x20 ; char to uppercase
cmp al, 'a'
jb pathz_not_low
cmp al, 'z'
ja pathz_not_low
sub al, 0x20 ; char to uppercase
 
pathz_not_low:
mov [edi],al
inc edi
mov eax,[esp+0] ; start_of_dest_path
add eax,512 ; keep maximum path under 512 bytes
cmp edi,eax
jb pathz_new_char
mov [edi], al
inc edi
mov eax, [esp+0] ; start_of_dest_path
add eax, 512 ; keep maximum path under 512 bytes
cmp edi, eax
jb pathz_new_char
 
pathz_end:
cmp ebx,edi ; if path end with '/'
jnz pathz_put_zero ; go back 1 level
sub ebx,12
cmp ebx, edi ; if path end with '/'
jnz pathz_put_zero ; go back 1 level
sub ebx, 12
 
pathz_put_zero:
mov byte [ebx+11],0
dec ebx ; include '/' char into file name
pop edi
pop ecx
pop eax
ret
mov byte [ebx+11], 0
dec ebx ; include '/' char into file name
pop edi
pop ecx
pop eax
ret
 
;*******************************************
;* string to number
747,51 → 750,52
; 1 - îøèáêà
; Åñëè CF=0, òî AX - ÷èñëî.
 
push bx
push cx
push dx
push edi
mov [partition_string],eax
mov edi,partition_string
xor cx,cx
push bx
push cx
push dx
push edi
mov [partition_string], eax
mov edi, partition_string
xor cx, cx
i1:
mov al,[edi]
cmp al,32 ;13
je i_exit
mov al, [edi]
cmp al, 32;13
je i_exit
; cmp al,'0'
; jb err
; cmp al,'9'
; ja err
sub al,48
shl cx,1
jc error
mov bx,cx
shl cx,1
jc error
shl cx,1
jc error
add cx,bx
jc error
cbw
add cx,ax
jc error
sub al, 48
shl cx, 1
jc error
mov bx, cx
shl cx, 1
jc error
shl cx, 1
jc error
add cx, bx
jc error
cbw
add cx, ax
jc error
i3:
inc edi
jmp i1
inc edi
jmp i1
i_exit:
mov ax,cx
clc
mov ax, cx
clc
i4:
movzx eax,ax
pop edi
pop dx
pop cx
pop bx
ret
movzx eax, ax
pop edi
pop dx
pop cx
pop bx
ret
 
error:
stc
jmp i4
stc
jmp i4
 
partition_string: dd 0
partition_string:
dd 0
db 32
/kernel/branches/net/fs/fs_lfn.inc
8,8 → 8,8
$Revision$
 
 
image_of_eax EQU esp+36
image_of_ebx EQU esp+24
image_of_eax EQU esp+32
image_of_ebx EQU esp+20
 
; System function 70 - files with long names (LFN)
; diamond, 2006
17,81 → 17,81
iglobal
; in this table names must be in lowercase
rootdirs:
db 2,'rd'
dd fs_OnRamdisk
dd fs_NextRamdisk
db 7,'ramdisk'
dd fs_OnRamdisk
dd fs_NextRamdisk
db 2,'fd'
dd fs_OnFloppy
dd fs_NextFloppy
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 2,'rd'
dd fs_OnRamdisk
dd fs_NextRamdisk
db 7,'ramdisk'
dd fs_OnRamdisk
dd fs_NextRamdisk
db 2,'fd'
dd fs_OnFloppy
dd fs_NextFloppy
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
dd fs_NextCd
db 3,'cd1'
dd fs_OnCd1
dd fs_NextCd
db 3,'cd2'
dd fs_OnCd2
dd fs_NextCd
db 3,'cd3'
dd fs_OnCd3
dd fs_NextCd
db 3,'cd0'
dd fs_OnCd0
dd fs_NextCd
db 3,'cd1'
dd fs_OnCd1
dd fs_NextCd
db 3,'cd2'
dd fs_OnCd2
dd fs_NextCd
db 3,'cd3'
dd fs_OnCd3
dd fs_NextCd
;***********************************************
db 0
db 0
 
 
virtual_root_query:
dd fs_HasRamdisk
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_HasRamdisk
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
dd fs_HasCd1
db 'cd1',0
dd fs_HasCd2
db 'cd2',0
dd fs_HasCd3
db 'cd3',0
dd fs_HasCd0
db 'cd0',0
dd fs_HasCd1
db 'cd1',0
dd fs_HasCd2
db 'cd2',0
dd fs_HasCd3
db 'cd3',0
;**********************************************
dd 0
dd 0
 
fs_additional_handlers:
dd biosdisk_handler, biosdisk_enum_root
dd dyndisk_handler, dyndisk_enum_root
; add new handlers here
dd 0
 
endg
 
file_system_lfn:
; in: eax->fileinfo block
; in: ebx->fileinfo block
; operation codes:
; 0 : read file
; 1 : read folder
105,211 → 105,210
; 9 : create directory
 
; parse file name
xchg ebx, eax
lea esi, [ebx+20]
lodsb
test al, al
jnz @f
mov esi, [esi]
lodsb
lea esi, [ebx+20]
lodsb
test al, al
jnz @f
mov esi, [esi]
lodsb
@@:
cmp al, '/'
jz .notcurdir
dec esi
mov ebp, esi
test al, al
jnz @f
xor ebp, ebp
cmp al, '/'
jz .notcurdir
dec esi
mov ebp, esi
test al, al
jnz @f
xor ebp, ebp
@@:
mov esi, [current_slot]
mov esi, [esi+APPDATA.cur_dir]
jmp .parse_normal
mov esi, [current_slot]
mov esi, [esi+APPDATA.cur_dir]
jmp .parse_normal
.notcurdir:
cmp byte [esi], 0
jz .rootdir
call process_replace_file_name
cmp byte [esi], 0
jz .rootdir
call process_replace_file_name
.parse_normal:
cmp dword [ebx], 7
jne @F
mov edx, [ebx+4]
mov ebx, [ebx+8]
call fs_execute ; esi+ebp, ebx, edx
mov [image_of_eax], eax
ret
cmp dword [ebx], 7
jne @F
mov edx, [ebx+4]
mov ebx, [ebx+8]
call fs_execute; esi+ebp, ebx, edx
mov [image_of_eax], eax
ret
@@:
mov edi, rootdirs-8
xor ecx, ecx
push esi
mov edi, rootdirs-8
xor ecx, ecx
push esi
.scan1:
pop esi
add edi, ecx
scasd
scasd
mov cl, byte [edi]
test cl, cl
jz .notfound_try
inc edi
push esi
pop esi
add edi, ecx
scasd
scasd
mov cl, byte [edi]
test cl, cl
jz .notfound_try
inc edi
push esi
@@:
lodsb
or al, 20h
scasb
loopz @b
jnz .scan1
lodsb
cmp al, '/'
jz .found1
test al, al
jnz .scan1
pop eax
lodsb
or al, 20h
scasb
loopz @b
jnz .scan1
lodsb
cmp al, '/'
jz .found1
test al, al
jnz .scan1
pop eax
; directory /xxx
.maindir:
mov esi, [edi+4]
mov esi, [edi+4]
.maindir_noesi:
cmp dword [ebx], 1
jnz .access_denied
xor eax, eax
mov ebp, [ebx+12]
mov edx, [ebx+16]
cmp dword [ebx], 1
jnz .access_denied
xor eax, eax
mov ebp, [ebx+12] ;количество блоков для считывания
mov edx, [ebx+16] ;куда записывать рузельтат
; add edx, std_application_base_address
push dword [ebx+4] ; first block
mov ebx, [ebx+8] ; flags
push dword [ebx+4] ; first block
mov ebx, [ebx+8] ; flags
; ebx=flags, [esp]=first block, ebp=number of blocks, edx=return area, esi='Next' handler
mov edi, edx
push ecx
mov ecx, 32/4
rep stosd
pop ecx
mov byte [edx], 1 ; version
mov edi, edx
push ecx
mov ecx, 32/4
rep stosd
pop ecx
mov byte [edx], 1 ; version
.maindir_loop:
call esi
jc .maindir_done
inc dword [edx+8]
dec dword [esp]
jns .maindir_loop
dec ebp
js .maindir_loop
inc dword [edx+4]
mov dword [edi], 0x10 ; attributes: folder
mov dword [edi+4], 1 ; name type: UNICODE
push eax
xor eax, eax
add edi, 8
push ecx
mov ecx, 40/4-2
rep stosd
pop ecx
pop eax
push eax edx
call esi
jc .maindir_done
inc dword [edx+8]
dec dword [esp]
jns .maindir_loop
dec ebp
js .maindir_loop
inc dword [edx+4]
mov dword [edi], 0x10 ; attributes: folder
mov dword [edi+4], 1 ; name type: UNICODE
push eax
xor eax, eax
add edi, 8
push ecx
mov ecx, 40/4-2
rep stosd
pop ecx
pop eax
push eax edx
; convert number in eax to decimal UNICODE string
push edi
push ecx
push -'0'
mov ecx, 10
push edi
push ecx
push -'0'
mov ecx, 10
@@:
xor edx, edx
div ecx
push edx
test eax, eax
jnz @b
xor edx, edx
div ecx
push edx
test eax, eax
jnz @b
@@:
pop eax
add al, '0'
stosb
test bl, 1 ; UNICODE name?
jz .ansi2
mov byte [edi], 0
inc edi
pop eax
add al, '0'
stosb
test bl, 1 ; UNICODE name?
jz .ansi2
mov byte [edi], 0
inc edi
.ansi2:
test al, al
jnz @b
mov byte [edi-1], 0
pop ecx
pop edi
test al, al
jnz @b
mov byte [edi-1], 0
pop ecx
pop edi
; UNICODE name length is 520 bytes, ANSI - 264
add edi, 520
test bl, 1
jnz @f
sub edi, 520-264
add edi, 520
test bl, 1
jnz @f
sub edi, 520-264
@@:
pop edx eax
jmp .maindir_loop
pop edx eax
jmp .maindir_loop
.maindir_done:
pop eax
mov ebx, [edx+4]
xor eax, eax
dec ebp
js @f
mov al, ERROR_END_OF_FILE
pop eax
mov ebx, [edx+4]
xor eax, eax
dec ebp
js @f
mov al, ERROR_END_OF_FILE
@@:
mov [image_of_eax], eax
mov [image_of_ebx], ebx
ret
mov [image_of_eax], eax
mov [image_of_ebx], ebx
ret
; directory /
.rootdir:
cmp dword [ebx], 1 ; read folder?
jz .readroot
cmp dword [ebx], 1 ; read folder?
jz .readroot
.access_denied:
mov dword [image_of_eax], 10 ; access denied
ret
mov dword [image_of_eax], 10 ; access denied
ret
 
.readroot:
; virtual root folder - special handler
mov esi, virtual_root_query
mov ebp, [ebx+12]
mov edx, [ebx+16]
mov esi, virtual_root_query
mov ebp, [ebx+12]
mov edx, [ebx+16]
; add edx, std_application_base_address
push dword [ebx+4] ; first block
mov ebx, [ebx+8] ; flags
xor eax, eax
push dword [ebx+4] ; first block
mov ebx, [ebx+8] ; flags
xor eax, eax
; eax=0, [esp]=first block, ebx=flags, ebp=number of blocks, edx=return area
mov edi, edx
mov ecx, 32/4
rep stosd
mov byte [edx], 1 ; version
mov edi, edx
mov ecx, 32/4
rep stosd
mov byte [edx], 1 ; version
.readroot_loop:
cmp dword [esi], eax
jz .readroot_done_static
call dword [esi]
add esi, 4
test eax, eax
jnz @f
cmp dword [esi], eax
jz .readroot_done_static
call dword [esi]
add esi, 4
test eax, eax
jnz @f
.readroot_next:
or ecx, -1
xchg esi, edi
repnz scasb
xchg esi, edi
jmp .readroot_loop
or ecx, -1
xchg esi, edi
repnz scasb
xchg esi, edi
jmp .readroot_loop
@@:
xor eax, eax
inc dword [edx+8]
dec dword [esp]
jns .readroot_next
dec ebp
js .readroot_next
inc dword [edx+4]
mov dword [edi], 0x10 ; attributes: folder
mov dword [edi+4], ebx ; name type: UNICODE
add edi, 8
mov ecx, 40/4-2
rep stosd
push edi
xor eax, eax
inc dword [edx+8]
dec dword [esp]
jns .readroot_next
dec ebp
js .readroot_next
inc dword [edx+4]
mov dword [edi], 0x10 ; attributes: folder
mov dword [edi+4], ebx ; name type: UNICODE
add edi, 8
mov ecx, 40/4-2
rep stosd
push edi
@@:
lodsb
stosb
test bl, 1
jz .ansi
mov byte [edi], 0
inc edi
lodsb
stosb
test bl, 1
jz .ansi
mov byte [edi], 0
inc edi
.ansi:
test eax, eax
jnz @b
pop edi
add edi, 520
test bl, 1
jnz .readroot_loop
sub edi, 520-264
jmp .readroot_loop
test eax, eax
jnz @b
pop edi
add edi, 520
test bl, 1
jnz .readroot_loop
sub edi, 520-264
jmp .readroot_loop
.readroot_done_static:
mov esi, fs_additional_handlers-8
sub esp, 16
337,7 → 336,7
mov dword [edi+4], ebx
add edi, 8
mov ecx, 40/4-2
rep stosd
rep stosd
push esi edi
lea esi, [esp+12]
@@:
358,16 → 357,16
jmp .readroot_ah_loop2
.readroot_done:
add esp, 16
pop eax
mov ebx, [edx+4]
xor eax, eax
dec ebp
js @f
mov al, ERROR_END_OF_FILE
pop eax
mov ebx, [edx+4]
xor eax, eax
dec ebp
js @f
mov al, ERROR_END_OF_FILE
@@:
mov [image_of_eax], eax
mov [image_of_ebx], ebx
ret
mov [image_of_eax], eax
mov [image_of_ebx], ebx
ret
.notfound_try:
mov edi, fs_additional_handlers
@@:
378,52 → 377,53
scasd
jmp @b
.notfound:
mov dword [image_of_eax], ERROR_FILE_NOT_FOUND
and dword [image_of_ebx], 0
ret
mov dword [image_of_eax], ERROR_FILE_NOT_FOUND
and dword [image_of_ebx], 0
ret
 
.notfounda:
cmp edi, esp
jnz .notfound
add esp, 8
call dword [edi+4]
add esp, 16
jmp .notfound
 
.found1:
pop eax
cmp byte [esi], 0
jz .maindir
pop eax
cmp byte [esi], 0
jz .maindir
.found2:
; read partition number
xor ecx, ecx
xor eax, eax
xor ecx, ecx
xor eax, eax
@@:
lodsb
cmp al, '/'
jz .done1
test al, al
jz .done1
sub al, '0'
cmp al, 9
ja .notfounda
lea ecx, [ecx*5]
lea ecx, [ecx*2+eax]
jmp @b
lodsb
cmp al, '/'
jz .done1
test al, al
jz .done1
sub al, '0'
cmp al, 9
ja .notfounda
lea ecx, [ecx*5]
lea ecx, [ecx*2+eax]
jmp @b
.done1:
jecxz .notfounda
test al, al
jnz @f
dec esi
jecxz .notfounda
test al, al
jnz @f
dec esi
@@:
cmp byte [esi], 0
jnz @f
test ebp, ebp
jz @f
mov esi, ebp
xor ebp, ebp
cmp byte [esi], 0
jnz @f
test ebp, ebp
jz @f
mov esi, ebp
xor ebp, ebp
@@:
; now [edi] contains handler address, ecx - partition number,
; esi points to ASCIIZ string - rest of name
jmp dword [edi]
jmp dword [edi]
 
; handlers for devices
; in: ecx = 0 => query virtual directory /xxx
434,287 → 434,287
; out: [image_of_eax]=image of eax, [image_of_ebx]=image of ebx
 
fs_OnRamdisk:
cmp ecx, 1
jnz file_system_lfn.notfound
mov eax, [ebx]
cmp eax, fs_NumRamdiskServices
jae .not_impl
mov ecx, [ebx+12]
mov edx, [ebx+16]
cmp ecx, 1
jnz file_system_lfn.notfound
mov eax, [ebx]
cmp eax, fs_NumRamdiskServices
jae .not_impl
mov ecx, [ebx+12]
mov edx, [ebx+16]
; add edx, std_application_base_address
add ebx, 4
call dword [fs_RamdiskServices + eax*4]
mov [image_of_eax], eax
mov [image_of_ebx], ebx
ret
add ebx, 4
call dword [fs_RamdiskServices + eax*4]
mov [image_of_eax], eax
mov [image_of_ebx], ebx
ret
.not_impl:
mov dword [image_of_eax], 2 ; not implemented
ret
mov dword [image_of_eax], 2 ; not implemented
ret
 
fs_NotImplemented:
mov eax, 2
ret
mov eax, 2
ret
 
fs_RamdiskServices:
dd fs_RamdiskRead
dd fs_RamdiskReadFolder
dd fs_RamdiskRewrite
dd fs_RamdiskWrite
dd fs_RamdiskSetFileEnd
dd fs_RamdiskGetFileInfo
dd fs_RamdiskSetFileInfo
dd 0
dd fs_RamdiskDelete
dd fs_RamdiskCreateFolder
dd fs_RamdiskRead
dd fs_RamdiskReadFolder
dd fs_RamdiskRewrite
dd fs_RamdiskWrite
dd fs_RamdiskSetFileEnd
dd fs_RamdiskGetFileInfo
dd fs_RamdiskSetFileInfo
dd 0
dd fs_RamdiskDelete
dd fs_RamdiskCreateFolder
fs_NumRamdiskServices = ($ - fs_RamdiskServices)/4
 
fs_OnFloppy:
cmp ecx, 2
ja file_system_lfn.notfound
mov eax, [ebx]
cmp eax, fs_NumFloppyServices
jae fs_OnRamdisk.not_impl
call reserve_flp
mov [flp_number], cl
mov ecx, [ebx+12]
mov edx, [ebx+16]
cmp ecx, 2
ja file_system_lfn.notfound
mov eax, [ebx]
cmp eax, fs_NumFloppyServices
jae fs_OnRamdisk.not_impl
call reserve_flp
mov [flp_number], cl
mov ecx, [ebx+12]
mov edx, [ebx+16]
; add edx, std_application_base_address
add ebx, 4
call dword [fs_FloppyServices + eax*4]
and [flp_status], 0
mov [image_of_eax], eax
mov [image_of_ebx], ebx
ret
add ebx, 4
call dword [fs_FloppyServices + eax*4]
and [flp_status], 0
mov [image_of_eax], eax
mov [image_of_ebx], ebx
ret
 
fs_FloppyServices:
dd fs_FloppyRead
dd fs_FloppyReadFolder
dd fs_FloppyRewrite
dd fs_FloppyWrite
dd fs_FloppySetFileEnd
dd fs_FloppyGetFileInfo
dd fs_FloppySetFileInfo
dd 0
dd fs_FloppyDelete
dd fs_FloppyCreateFolder
dd fs_FloppyRead
dd fs_FloppyReadFolder
dd fs_FloppyRewrite
dd fs_FloppyWrite
dd fs_FloppySetFileEnd
dd fs_FloppyGetFileInfo
dd fs_FloppySetFileInfo
dd 0
dd fs_FloppyDelete
dd fs_FloppyCreateFolder
fs_NumFloppyServices = ($ - fs_FloppyServices)/4
 
fs_OnHd0:
call reserve_hd1
mov [hdbase], 0x1F0
mov [hdid], 0
push 1
jmp fs_OnHd
call reserve_hd1
mov [hdbase], 0x1F0
mov [hdid], 0
push 1
jmp fs_OnHd
fs_OnHd1:
call reserve_hd1
mov [hdbase], 0x1F0
mov [hdid], 0x10
push 2
jmp fs_OnHd
call reserve_hd1
mov [hdbase], 0x1F0
mov [hdid], 0x10
push 2
jmp fs_OnHd
fs_OnHd2:
call reserve_hd1
mov [hdbase], 0x170
mov [hdid], 0
push 3
jmp fs_OnHd
call reserve_hd1
mov [hdbase], 0x170
mov [hdid], 0
push 3
jmp fs_OnHd
fs_OnHd3:
call reserve_hd1
mov [hdbase], 0x170
mov [hdid], 0x10
push 4
call reserve_hd1
mov [hdbase], 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]
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
jbe @f
.nf:
call free_hd_channel
and [hd1_status], 0
mov dword [image_of_eax], 5 ; not found
ret
call free_hd_channel
and [hd1_status], 0
mov dword [image_of_eax], 5 ; not found
ret
@@:
mov [fat32part], ecx
push ebx esi
call choice_necessity_partition_1
pop esi ebx
mov ecx, [ebx+12]
mov edx, [ebx+16]
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
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
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
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
mov [ChannelNumber],1
mov [DiskNumber],0
push 6
push 1
jmp fs_OnCd
call reserve_cd
mov [ChannelNumber], 1
mov [DiskNumber], 0
push 6
push 1
jmp fs_OnCd
fs_OnCd1:
call reserve_cd
mov [ChannelNumber],1
mov [DiskNumber],1
push 4
push 2
jmp fs_OnCd
call reserve_cd
mov [ChannelNumber], 1
mov [DiskNumber], 1
push 4
push 2
jmp fs_OnCd
fs_OnCd2:
call reserve_cd
mov [ChannelNumber],2
mov [DiskNumber],0
push 2
push 3
jmp fs_OnCd
call reserve_cd
mov [ChannelNumber], 2
mov [DiskNumber], 0
push 2
push 3
jmp fs_OnCd
fs_OnCd3:
call reserve_cd
mov [ChannelNumber],2
mov [DiskNumber],1
push 0
push 4
call reserve_cd
mov [ChannelNumber], 2
mov [DiskNumber], 1
push 0
push 4
fs_OnCd:
call reserve_cd_channel
pop eax
mov [cdpos], eax
pop eax
cmp ecx, 0x100
jae .nf
push ecx ebx
mov cl,al
mov bl,[DRIVE_DATA+1]
shr bl,cl
test bl,2
pop ebx ecx
call reserve_cd_channel
pop eax
mov [cdpos], eax
pop eax
cmp ecx, 0x100
jae .nf
push ecx ebx
mov cl, al
mov bl, [DRIVE_DATA+1]
shr bl, cl
test bl, 2
pop ebx ecx
 
jnz @f
jnz @f
.nf:
call free_cd_channel
and [cd_status], 0
mov dword [image_of_eax], 5 ; not found
ret
call free_cd_channel
and [cd_status], 0
mov dword [image_of_eax], 5 ; not found
ret
@@:
mov ecx, [ebx+12]
mov edx, [ebx+16]
mov ecx, [ebx+12]
mov edx, [ebx+16]
; add edx, std_application_base_address
mov eax, [ebx]
cmp eax,fs_NumCdServices
jae .not_impl
add ebx, 4
call dword [fs_CdServices + eax*4]
call free_cd_channel
and [cd_status], 0
mov [image_of_eax], eax
mov [image_of_ebx], ebx
ret
mov eax, [ebx]
cmp eax, fs_NumCdServices
jae .not_impl
add ebx, 4
call dword [fs_CdServices + eax*4]
call free_cd_channel
and [cd_status], 0
mov [image_of_eax], eax
mov [image_of_ebx], ebx
ret
.not_impl:
call free_cd_channel
and [cd_status], 0
mov dword [image_of_eax], 2 ; not implemented
ret
call free_cd_channel
and [cd_status], 0
mov dword [image_of_eax], 2 ; not implemented
ret
 
fs_CdServices:
dd fs_CdRead
dd fs_CdReadFolder
dd fs_NotImplemented
dd fs_NotImplemented
dd fs_NotImplemented
dd fs_CdGetFileInfo
dd fs_NotImplemented
dd 0
dd fs_NotImplemented
dd fs_NotImplemented
dd fs_CdRead
dd fs_CdReadFolder
dd fs_NotImplemented
dd fs_NotImplemented
dd fs_NotImplemented
dd fs_CdGetFileInfo
dd fs_NotImplemented
dd 0
dd fs_NotImplemented
dd fs_NotImplemented
fs_NumCdServices = ($ - fs_CdServices)/4
 
;*******************************************************
 
fs_HasRamdisk:
mov al, 1 ; we always have ramdisk
ret
mov al, 1 ; we always have ramdisk
ret
 
fs_HasFloppy:
cmp byte [DRIVE_DATA], 0
setnz al
ret
cmp byte [DRIVE_DATA], 0
setnz al
ret
 
fs_HasHd0:
mov al, [DRIVE_DATA+1]
and al, 11000000b
cmp al, 01000000b
setz al
ret
mov al, [DRIVE_DATA+1]
and al, 11000000b
cmp al, 01000000b
setz al
ret
fs_HasHd1:
mov al, [DRIVE_DATA+1]
and al, 00110000b
cmp al, 00010000b
setz al
ret
mov al, [DRIVE_DATA+1]
and al, 00110000b
cmp al, 00010000b
setz al
ret
fs_HasHd2:
mov al, [DRIVE_DATA+1]
and al, 00001100b
cmp al, 00000100b
setz al
ret
mov al, [DRIVE_DATA+1]
and al, 00001100b
cmp al, 00000100b
setz al
ret
fs_HasHd3:
mov al, [DRIVE_DATA+1]
and al, 00000011b
cmp al, 00000001b
setz al
ret
mov al, [DRIVE_DATA+1]
and al, 00000011b
cmp al, 00000001b
setz al
ret
 
;*******************************************************
fs_HasCd0:
mov al, [DRIVE_DATA+1]
and al, 11000000b
cmp al, 10000000b
setz al
ret
mov al, [DRIVE_DATA+1]
and al, 11000000b
cmp al, 10000000b
setz al
ret
fs_HasCd1:
mov al, [DRIVE_DATA+1]
and al, 00110000b
cmp al, 00100000b
setz al
ret
mov al, [DRIVE_DATA+1]
and al, 00110000b
cmp al, 00100000b
setz al
ret
fs_HasCd2:
mov al, [DRIVE_DATA+1]
and al, 00001100b
cmp al, 00001000b
setz al
ret
mov al, [DRIVE_DATA+1]
and al, 00001100b
cmp al, 00001000b
setz al
ret
fs_HasCd3:
mov al, [DRIVE_DATA+1]
and al, 00000011b
cmp al, 00000010b
setz al
ret
mov al, [DRIVE_DATA+1]
and al, 00000011b
cmp al, 00000010b
setz al
ret
;*******************************************************
 
; fs_NextXXX functions:
724,65 → 724,65
 
fs_NextRamdisk:
; we always have /rd/1
test eax, eax
stc
jnz @f
mov al, 1
clc
test eax, eax
stc
jnz @f
mov al, 1
clc
@@:
ret
ret
 
fs_NextFloppy:
; we have /fd/1 iff (([DRIVE_DATA] and 0xF0) != 0) and /fd/2 iff (([DRIVE_DATA] and 0x0F) != 0)
test byte [DRIVE_DATA], 0xF0
jz .no1
test eax, eax
jnz .no1
inc eax
ret ; CF cleared
test byte [DRIVE_DATA], 0xF0
jz .no1
test eax, eax
jnz .no1
inc eax
ret ; CF cleared
.no1:
test byte [DRIVE_DATA], 0x0F
jz .no2
cmp al, 2
jae .no2
mov al, 2
clc
ret
test byte [DRIVE_DATA], 0x0F
jz .no2
cmp al, 2
jae .no2
mov al, 2
clc
ret
.no2:
stc
ret
stc
ret
 
; on hdx, we have partitions from 1 to [0x40002+x]
fs_NextHd0:
push 0
jmp fs_NextHd
push 0
jmp fs_NextHd
fs_NextHd1:
push 1
jmp fs_NextHd
push 1
jmp fs_NextHd
fs_NextHd2:
push 2
jmp fs_NextHd
push 2
jmp fs_NextHd
fs_NextHd3:
push 3
push 3
fs_NextHd:
pop ecx
movzx ecx, byte [DRIVE_DATA+2+ecx]
cmp eax, ecx
jae fs_NextFloppy.no2
inc eax
clc
ret
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
test eax, eax
stc
jnz @f
mov al, 1
clc
test eax, eax
stc
jnz @f
mov al, 1
clc
@@:
ret
ret
;*******************************************************
 
; Additional FS handlers.
852,6 → 852,8
jmp file_system_lfn.maindir_noesi
@@:
push ecx
push ecx
push biosdisk_cleanup
push fs_OnBd
mov edi, esp
jmp file_system_lfn.found2
858,19 → 860,20
 
fs_BdNext:
cmp eax, [BiosDiskPartitions+ecx*4]
inc eax
cmc
ret
inc eax
cmc
biosdisk_cleanup:
ret
 
fs_OnBd:
pop edx edx
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
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.
904,7 → 907,7
xor eax, eax
ret
.big:
push ecx
push ecx edx
push -'0'
mov ecx, 10
@@:
919,227 → 922,229
add al, '0'
stosb
jnz @b
pop ecx
pop edx ecx
pop eax
inc eax
ret
 
process_replace_file_name:
mov ebp, [full_file_name_table]
mov edi, [full_file_name_table.size]
dec edi
shl edi, 7
add edi, ebp
mov ebp, [full_file_name_table]
mov edi, [full_file_name_table.size]
dec edi
shl edi, 7
add edi, ebp
.loop:
cmp edi, ebp
jb .notfound
push esi edi
cmp edi, ebp
jb .notfound
push esi edi
@@:
cmp byte [edi], 0
jz .dest_done
lodsb
test al, al
jz .cont
or al, 20h
scasb
jz @b
jmp .cont
cmp byte [edi], 0
jz .dest_done
lodsb
test al, al
jz .cont
or al, 20h
scasb
jz @b
jmp .cont
.dest_done:
cmp byte [esi], 0
jz .found
cmp byte [esi], '/'
jnz .cont
inc esi
jmp .found
cmp byte [esi], 0
jz .found
cmp byte [esi], '/'
jnz .cont
inc esi
jmp .found
.cont:
pop edi esi
sub edi, 128
jmp .loop
pop edi esi
sub edi, 128
jmp .loop
.found:
pop edi eax
mov ebp, esi
cmp byte [esi], 0
lea esi, [edi+64]
jnz .ret
pop edi eax
mov ebp, esi
cmp byte [esi], 0
lea esi, [edi+64]
jnz .ret
.notfound:
xor ebp, ebp
xor ebp, ebp
.ret:
ret
ret
 
sys_current_directory:
; mov esi, [current_slot]
; mov esi, [esi+APPDATA.cur_dir]
; mov edx, esi
; mov esi, [current_slot]
; mov esi, [esi+APPDATA.cur_dir]
; mov edx, esi
 
;get length string of appdata.cur_dir
mov eax, [current_slot]
mov edi, [eax+APPDATA.cur_dir]
mov eax, [current_slot]
mov edi, [eax+APPDATA.cur_dir]
 
dec ebx
jz .set
dec ebx
jz .get
ret
dec ebx
jz .set
dec ebx
jz .get
ret
.get:
; sysfunction 30.2: [for app] eax=30,ebx=2,ecx->buffer,edx=len
; for our code: ebx->buffer,ecx=len
max_cur_dir equ 0x1000
max_cur_dir equ 0x1000
 
mov ebx,edi
mov ebx, edi
 
push ecx
push edi
push ecx
push edi
 
xor eax,eax
mov ecx,max_cur_dir
xor eax, eax
mov ecx, max_cur_dir
 
repne scasb ;find zerro at and string
jnz .error ; no zero in cur_dir: internal error, should not happen
repne scasb ;find zerro at and string
jnz .error ; no zero in cur_dir: internal error, should not happen
 
sub edi,ebx ;lenght for copy
inc edi
mov [esp+32+8],edi ;return in eax
sub edi, ebx ;lenght for copy
inc edi
mov [esp+32+8], edi ;return in eax
 
cmp edx, edi
jbe @f
mov edx, edi
cmp edx, edi
jbe @f
mov edx, edi
@@:
;source string
pop esi
pop esi
;destination string
pop edi
cmp edx, 1
jbe .ret
pop edi
cmp edx, 1
jbe .ret
 
mov al,'/' ;start string with '/'
stosb
mov ecx,edx
rep movsb ;copy string
.ret: ret
mov al, '/' ;start string with '/'
stosb
mov ecx, edx
rep movsb ;copy string
.ret:
ret
 
.error: add esp,8
or dword [esp+32],-1 ;error not found zerro at string ->[eax+APPDATA.cur_dir]
ret
.error:
add esp, 8
or dword [esp+32], -1 ;error not found zerro at string ->[eax+APPDATA.cur_dir]
ret
.set:
; sysfunction 30.1: [for app] eax=30,ebx=1,ecx->string
; for our code: ebx->string to set
; use generic resolver with APPDATA.cur_dir as destination
push max_cur_dir ;0x1000
push edi ;destination
mov ebx,ecx
call get_full_file_name
ret
push max_cur_dir ;0x1000
push edi ;destination
mov ebx, ecx
call get_full_file_name
ret
 
; in: ebx = file name, [esp+4] = destination, [esp+8] = sizeof destination
; destroys all registers except ebp,esp
get_full_file_name:
push ebp
mov esi, [current_slot]
mov esi, [esi+APPDATA.cur_dir]
mov edx, esi
push ebp
mov esi, [current_slot]
mov esi, [esi+APPDATA.cur_dir]
mov edx, esi
@@:
inc esi
cmp byte [esi-1], 0
jnz @b
dec esi
cmp byte [ebx], '/'
jz .set_absolute
inc esi
cmp byte [esi-1], 0
jnz @b
dec esi
cmp byte [ebx], '/'
jz .set_absolute
; string gives relative path
mov edi, [esp+8] ; destination
mov edi, [esp+8] ; destination
.relative:
cmp byte [ebx], 0
jz .set_ok
cmp word [ebx], '.'
jz .set_ok
cmp word [ebx], './'
jnz @f
add ebx, 2
jmp .relative
cmp byte [ebx], 0
jz .set_ok
cmp word [ebx], '.'
jz .set_ok
cmp word [ebx], './'
jnz @f
add ebx, 2
jmp .relative
@@:
cmp word [ebx], '..'
jnz .doset_relative
cmp byte [ebx+2], 0
jz @f
cmp byte [ebx+2], '/'
jnz .doset_relative
cmp word [ebx], '..'
jnz .doset_relative
cmp byte [ebx+2], 0
jz @f
cmp byte [ebx+2], '/'
jnz .doset_relative
@@:
dec esi
cmp byte [esi], '/'
jnz @b
add ebx, 3
jmp .relative
dec esi
cmp byte [esi], '/'
jnz @b
add ebx, 3
jmp .relative
.set_ok:
cmp edx, edi ; is destination equal to APPDATA.cur_dir?
jz .set_ok.cur_dir
sub esi, edx
cmp esi, [esp+12]
jb .set_ok.copy
cmp edx, edi ; is destination equal to APPDATA.cur_dir?
jz .set_ok.cur_dir
sub esi, edx
cmp esi, [esp+12]
jb .set_ok.copy
.fail:
mov byte [edi], 0
xor eax, eax ; fail
pop ebp
ret 8
mov byte [edi], 0
xor eax, eax ; fail
pop ebp
ret 8
.set_ok.copy:
mov ecx, esi
mov esi, edx
rep movsb
mov byte [edi], 0
mov ecx, esi
mov esi, edx
rep movsb
mov byte [edi], 0
.ret.ok:
mov al, 1 ; ok
pop ebp
ret 8
mov al, 1 ; ok
pop ebp
ret 8
.set_ok.cur_dir:
mov byte [esi], 0
jmp .ret.ok
mov byte [esi], 0
jmp .ret.ok
.doset_relative:
cmp edx, edi
jz .doset_relative.cur_dir
sub esi, edx
cmp esi, [esp+12]
jae .fail
mov ecx, esi
mov esi, edx
mov edx, edi
rep movsb
jmp .doset_relative.copy
cmp edx, edi
jz .doset_relative.cur_dir
sub esi, edx
cmp esi, [esp+12]
jae .fail
mov ecx, esi
mov esi, edx
mov edx, edi
rep movsb
jmp .doset_relative.copy
.doset_relative.cur_dir:
mov edi, esi
mov edi, esi
.doset_relative.copy:
add edx, [esp+12]
mov byte [edi], '/'
inc edi
cmp edi, edx
jae .overflow
add edx, [esp+12]
mov byte [edi], '/'
inc edi
cmp edi, edx
jae .overflow
@@:
mov al, [ebx]
inc ebx
stosb
test al, al
jz .ret.ok
cmp edi, edx
jb @b
mov al, [ebx]
inc ebx
stosb
test al, al
jz .ret.ok
cmp edi, edx
jb @b
.overflow:
dec edi
jmp .fail
dec edi
jmp .fail
.set_absolute:
lea esi, [ebx+1]
call process_replace_file_name
mov edi, [esp+8]
mov edx, [esp+12]
add edx, edi
lea esi, [ebx+1]
call process_replace_file_name
mov edi, [esp+8]
mov edx, [esp+12]
add edx, edi
.set_copy:
lodsb
stosb
test al, al
jz .set_part2
lodsb
stosb
test al, al
jz .set_part2
.set_copy_cont:
cmp edi, edx
jb .set_copy
jmp .overflow
cmp edi, edx
jb .set_copy
jmp .overflow
.set_part2:
mov esi, ebp
xor ebp, ebp
test esi, esi
jz .ret.ok
mov byte [edi-1], '/'
jmp .set_copy_cont
mov esi, ebp
xor ebp, ebp
test esi, esi
jz .ret.ok
mov byte [edi-1], '/'
jmp .set_copy_cont
/kernel/branches/net/fs/iso9660.inc
5,72 → 5,76
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision:1322 $
$Revision$
 
 
uglobal
cd_current_pointer_of_input dd 0
cd_current_pointer_of_input_2 dd 0
cd_mem_location dd 0
cd_counter_block dd 0
IDE_Channel_1 db 0
IDE_Channel_2 db 0
cd_mem_location dd 0
cd_counter_block dd 0
IDE_Channel_1 db 0
IDE_Channel_2 db 0
endg
 
reserve_cd:
 
cli
cmp [cd_status],0
je reserve_ok2
cli
cmp [cd_status], 0
je reserve_ok2
 
sti
call change_task
jmp reserve_cd
sti
call change_task
jmp reserve_cd
 
reserve_ok2:
 
push eax
mov eax,[CURRENT_TASK]
shl eax,5
mov eax,[eax+CURRENT_TASK+TASKDATA.pid]
mov [cd_status],eax
pop eax
sti
ret
push eax
mov eax, [CURRENT_TASK]
shl eax, 5
mov eax, [eax+CURRENT_TASK+TASKDATA.pid]
mov [cd_status], eax
pop eax
sti
ret
 
reserve_cd_channel:
cmp [ChannelNumber],1
jne .IDE_Channel_2
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
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_1
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
ret
mov [IDE_Channel_1], 1
sti
ret
.reserve_ok_2:
mov [IDE_Channel_2],1
ret
mov [IDE_Channel_2], 1
sti
ret
 
free_cd_channel:
cmp [ChannelNumber],1
jne .IDE_Channel_2
cmp [ChannelNumber], 1
jne .IDE_Channel_2
.IDE_Channel_1:
mov [IDE_Channel_1],0
ret
mov [IDE_Channel_1], 0
sti
ret
.IDE_Channel_2:
mov [IDE_Channel_2],0
ret
mov [IDE_Channel_2], 0
sti
ret
 
uglobal
cd_status dd 0
91,113 → 95,113
;
;--------------------------------------------------------------
fs_CdRead:
push edi
cmp byte [esi], 0
jnz @f
push edi
cmp byte [esi], 0
jnz @f
.noaccess:
pop edi
pop edi
.noaccess_2:
or ebx, -1
mov eax, ERROR_ACCESS_DENIED
ret
or ebx, -1
mov eax, ERROR_ACCESS_DENIED
ret
 
.noaccess_3:
pop eax edx ecx edi
jmp .noaccess_2
pop eax edx ecx edi
jmp .noaccess_2
 
@@:
call cd_find_lfn
jnc .found
pop edi
cmp [DevErrorCode],0
jne .noaccess_2
or ebx, -1
mov eax, ERROR_FILE_NOT_FOUND
ret
call cd_find_lfn
jnc .found
pop edi
cmp [DevErrorCode], 0
jne .noaccess_2
or ebx, -1
mov eax, ERROR_FILE_NOT_FOUND
ret
 
.found:
mov edi,[cd_current_pointer_of_input]
test byte [edi+25],10b ; do not allow read directories
jnz .noaccess
test ebx, ebx
jz .l1
cmp dword [ebx+4], 0
jz @f
xor ebx, ebx
mov edi, [cd_current_pointer_of_input]
test byte [edi+25], 10b; do not allow read directories
jnz .noaccess
test ebx, ebx
jz .l1
cmp dword [ebx+4], 0
jz @f
xor ebx, ebx
.reteof:
mov eax, 6 ; end of file
pop edi
ret
mov eax, 6; end of file
pop edi
ret
@@:
mov ebx, [ebx]
mov ebx, [ebx]
.l1:
push ecx edx
push 0
mov eax, [edi+10] ; ðåàëüíûé ðàçìåð ôàéëîâîé ñåêöèè
sub eax, ebx
jb .eof
cmp eax, ecx
jae @f
mov ecx, eax
mov byte [esp], 6
push ecx edx
push 0
mov eax, [edi+10] ; ðåàëüíûé ðàçìåð ôàéëîâîé ñåêöèè
sub eax, ebx
jb .eof
cmp eax, ecx
jae @f
mov ecx, eax
mov byte [esp], 6
@@:
mov eax,[edi+2]
mov [CDSectorAddress],eax
mov eax, [edi+2]
mov [CDSectorAddress], eax
; now eax=cluster, ebx=position, ecx=count, edx=buffer for data
.new_sector:
test ecx, ecx
jz .done
sub ebx, 2048
jae .next
add ebx, 2048
jnz .incomplete_sector
cmp ecx, 2048
jb .incomplete_sector
test ecx, ecx
jz .done
sub ebx, 2048
jae .next
add ebx, 2048
jnz .incomplete_sector
cmp ecx, 2048
jb .incomplete_sector
; we may read and memmove complete sector
mov [CDDataBuf_pointer],edx
call ReadCDWRetr ; ÷èòàåì ñåêòîð ôàéëà
cmp [DevErrorCode],0
jne .noaccess_3
add edx, 2048
sub ecx, 2048
mov [CDDataBuf_pointer], edx
call ReadCDWRetr; ÷èòàåì ñåêòîð ôàéëà
cmp [DevErrorCode], 0
jne .noaccess_3
add edx, 2048
sub ecx, 2048
.next:
inc dword [CDSectorAddress]
jmp .new_sector
inc dword [CDSectorAddress]
jmp .new_sector
.incomplete_sector:
; we must read and memmove incomplete sector
mov [CDDataBuf_pointer],CDDataBuf
call ReadCDWRetr ; ÷èòàåì ñåêòîð ôàéëà
cmp [DevErrorCode],0
jne .noaccess_3
push ecx
add ecx, ebx
cmp ecx, 2048
jbe @f
mov ecx, 2048
mov [CDDataBuf_pointer], CDDataBuf
call ReadCDWRetr; ÷èòàåì ñåêòîð ôàéëà
cmp [DevErrorCode], 0
jne .noaccess_3
push ecx
add ecx, ebx
cmp ecx, 2048
jbe @f
mov ecx, 2048
@@:
sub ecx, ebx
push edi esi ecx
mov edi,edx
lea esi, [CDDataBuf + ebx]
cld
rep movsb
pop ecx esi edi
add edx, ecx
sub [esp], ecx
pop ecx
xor ebx, ebx
jmp .next
sub ecx, ebx
push edi esi ecx
mov edi, edx
lea esi, [CDDataBuf + ebx]
cld
rep movsb
pop ecx esi edi
add edx, ecx
sub [esp], ecx
pop ecx
xor ebx, ebx
jmp .next
 
.done:
mov ebx, edx
pop eax edx ecx edi
sub ebx, edx
ret
mov ebx, edx
pop eax edx ecx edi
sub ebx, edx
ret
.eof:
mov ebx, edx
pop eax edx ecx
sub ebx, edx
jmp .reteof
mov ebx, edx
pop eax edx ecx
sub ebx, edx
jmp .reteof
 
;----------------------------------------------------------------
;
215,242 → 219,242
;
;--------------------------------------------------------------
fs_CdReadFolder:
push edi
call cd_find_lfn
jnc .found
pop edi
cmp [DevErrorCode], 0
jne .noaccess_1
or ebx, -1
mov eax, ERROR_FILE_NOT_FOUND
ret
push edi
call cd_find_lfn
jnc .found
pop edi
cmp [DevErrorCode], 0
jne .noaccess_1
or ebx, -1
mov eax, ERROR_FILE_NOT_FOUND
ret
.found:
mov edi, [cd_current_pointer_of_input]
test byte [edi+25], 10b ; do not allow read directories
jnz .found_dir
pop edi
mov edi, [cd_current_pointer_of_input]
test byte [edi+25], 10b ; do not allow read directories
jnz .found_dir
pop edi
.noaccess_1:
or ebx, -1
mov eax, ERROR_ACCESS_DENIED
ret
or ebx, -1
mov eax, ERROR_ACCESS_DENIED
ret
.found_dir:
mov eax, [edi+2] ; eax=cluster
mov [CDSectorAddress], eax
mov eax, [edi+10] ; ðàçìåð äèðåêòðîðèè
mov eax, [edi+2] ; eax=cluster
mov [CDSectorAddress], eax
mov eax, [edi+10] ; ðàçìåð äèðåêòðîðèè
.doit:
; init header
push eax ecx
mov edi, edx
mov ecx, 32/4
xor eax, eax
rep stosd
pop ecx eax
mov byte [edx], 1 ; version
mov [cd_mem_location], edx
add [cd_mem_location], 32
push eax ecx
mov edi, edx
mov ecx, 32/4
xor eax, eax
rep stosd
pop ecx eax
mov byte [edx], 1 ; version
mov [cd_mem_location], edx
add [cd_mem_location], 32
; íà÷èíàåì ïåðåáðîñêó ÁÄÂÊ â ÓÑÂÊ
;.mainloop:
mov [cd_counter_block], dword 0
dec dword [CDSectorAddress]
push ecx
mov [cd_counter_block], dword 0
dec dword [CDSectorAddress]
push ecx
.read_to_buffer:
inc dword [CDSectorAddress]
mov [CDDataBuf_pointer], CDDataBuf
call ReadCDWRetr ; ÷èòàåì ñåêòîð äèðåêòîðèè
cmp [DevErrorCode], 0
jne .noaccess_1
call .get_names_from_buffer
sub eax,2048
inc dword [CDSectorAddress]
mov [CDDataBuf_pointer], CDDataBuf
call ReadCDWRetr ; ÷èòàåì ñåêòîð äèðåêòîðèè
cmp [DevErrorCode], 0
jne .noaccess_1
call .get_names_from_buffer
sub eax, 2048
; äèðåêòîðèÿ çàêîí÷èëàñü?
ja .read_to_buffer
mov edi, [cd_counter_block]
mov [edx+8], edi
mov edi, [ebx]
sub [edx+4], edi
xor eax, eax
dec ecx
js @f
mov al, ERROR_END_OF_FILE
ja .read_to_buffer
mov edi, [cd_counter_block]
mov [edx+8], edi
mov edi, [ebx]
sub [edx+4], edi
xor eax, eax
dec ecx
js @f
mov al, ERROR_END_OF_FILE
@@:
pop ecx edi
mov ebx, [edx+4]
ret
pop ecx edi
mov ebx, [edx+4]
ret
 
.get_names_from_buffer:
mov [cd_current_pointer_of_input_2],CDDataBuf
push eax esi edi edx
mov [cd_current_pointer_of_input_2], CDDataBuf
push eax esi edi edx
.get_names_from_buffer_1:
call cd_get_name
jc .end_buffer
inc dword [cd_counter_block]
mov eax,[cd_counter_block]
cmp [ebx],eax
jae .get_names_from_buffer_1
test ecx, ecx
jz .get_names_from_buffer_1
mov edi,[cd_counter_block]
mov [edx+4],edi
dec ecx
mov esi,ebp
mov edi,[cd_mem_location]
add edi,40
test dword [ebx+4], 1 ; 0=ANSI, 1=UNICODE
jnz .unicode
call cd_get_name
jc .end_buffer
inc dword [cd_counter_block]
mov eax, [cd_counter_block]
cmp [ebx], eax
jae .get_names_from_buffer_1
test ecx, ecx
jz .get_names_from_buffer_1
mov edi, [cd_counter_block]
mov [edx+4], edi
dec ecx
mov esi, ebp
mov edi, [cd_mem_location]
add edi, 40
test dword [ebx+4], 1; 0=ANSI, 1=UNICODE
jnz .unicode
; jmp .unicode
.ansi:
cmp [cd_counter_block],2
jbe .ansi_parent_directory
cld
lodsw
xchg ah,al
call uni2ansi_char
cld
stosb
cmp [cd_counter_block], 2
jbe .ansi_parent_directory
cld
lodsw
xchg ah, al
call uni2ansi_char
cld
stosb
; ïðîâåðêà êîíöà ôàéëà
mov ax,[esi]
cmp ax,word 3B00h ; ñåïàðàòîð êîíöà ôàéëà ';'
je .cd_get_parameters_of_file_1
mov ax, [esi]
cmp ax, word 3B00h; ñåïàðàòîð êîíöà ôàéëà ';'
je .cd_get_parameters_of_file_1
; ïðîâåðêà äëÿ ôàéëîâ íå çàêàí÷èâàþùèõñÿ ñåïàðàòîðîì
movzx eax,byte [ebp-33]
add eax,ebp
sub eax,34
cmp esi,eax
je .cd_get_parameters_of_file_1
movzx eax, byte [ebp-33]
add eax, ebp
sub eax, 34
cmp esi, eax
je .cd_get_parameters_of_file_1
; ïðîâåðêà êîíöà ïàïêè
movzx eax,byte [ebp-1]
add eax,ebp
cmp esi,eax
jb .ansi
movzx eax, byte [ebp-1]
add eax, ebp
cmp esi, eax
jb .ansi
.cd_get_parameters_of_file_1:
mov [edi],byte 0
call cd_get_parameters_of_file
add [cd_mem_location],304
jmp .get_names_from_buffer_1
mov [edi], byte 0
call cd_get_parameters_of_file
add [cd_mem_location], 304
jmp .get_names_from_buffer_1
 
.ansi_parent_directory:
cmp [cd_counter_block],2
je @f
mov [edi],byte '.'
inc edi
jmp .cd_get_parameters_of_file_1
cmp [cd_counter_block], 2
je @f
mov [edi], byte '.'
inc edi
jmp .cd_get_parameters_of_file_1
@@:
mov [edi],word '..'
add edi,2
jmp .cd_get_parameters_of_file_1
mov [edi], word '..'
add edi, 2
jmp .cd_get_parameters_of_file_1
 
.unicode:
cmp [cd_counter_block],2
jbe .unicode_parent_directory
cld
movsw
cmp [cd_counter_block], 2
jbe .unicode_parent_directory
cld
movsw
; ïðîâåðêà êîíöà ôàéëà
mov ax,[esi]
cmp ax,word 3B00h ; ñåïàðàòîð êîíöà ôàéëà ';'
je .cd_get_parameters_of_file_2
mov ax, [esi]
cmp ax, word 3B00h; ñåïàðàòîð êîíöà ôàéëà ';'
je .cd_get_parameters_of_file_2
; ïðîâåðêà äëÿ ôàéëîâ íå çàêàí÷èâàþùèõñÿ ñåïàðàòîðîì
movzx eax,byte [ebp-33]
add eax,ebp
sub eax,34
cmp esi,eax
je .cd_get_parameters_of_file_2
movzx eax, byte [ebp-33]
add eax, ebp
sub eax, 34
cmp esi, eax
je .cd_get_parameters_of_file_2
; ïðîâåðêà êîíöà ïàïêè
movzx eax,byte [ebp-1]
add eax,ebp
cmp esi,eax
jb .unicode
movzx eax, byte [ebp-1]
add eax, ebp
cmp esi, eax
jb .unicode
.cd_get_parameters_of_file_2:
mov [edi],word 0
call cd_get_parameters_of_file
add [cd_mem_location],560
jmp .get_names_from_buffer_1
mov [edi], word 0
call cd_get_parameters_of_file
add [cd_mem_location], 560
jmp .get_names_from_buffer_1
 
.unicode_parent_directory:
cmp [cd_counter_block],2
je @f
mov [edi],word 2E00h ; '.'
add edi,2
jmp .cd_get_parameters_of_file_2
cmp [cd_counter_block], 2
je @f
mov [edi], word 2E00h; '.'
add edi, 2
jmp .cd_get_parameters_of_file_2
@@:
mov [edi],dword 2E002E00h ; '..'
add edi,4
jmp .cd_get_parameters_of_file_2
mov [edi], dword 2E002E00h; '..'
add edi, 4
jmp .cd_get_parameters_of_file_2
 
.end_buffer:
pop edx edi esi eax
ret
pop edx edi esi eax
ret
 
cd_get_parameters_of_file:
mov edi,[cd_mem_location]
mov edi, [cd_mem_location]
cd_get_parameters_of_file_1:
; ïîëó÷àåì àòðèáóòû ôàéëà
xor eax,eax
xor eax, eax
; ôàéë íå àðõèâèðîâàëñÿ
inc eax
shl eax,1
inc eax
shl eax, 1
; ýòî êàòàëîã?
test [ebp-8],byte 2
jz .file
inc eax
test [ebp-8], byte 2
jz .file
inc eax
.file:
; ìåòêà òîìà íå êàê â FAT, â ýòîì âèäå îòñóòñâóåò
; ôàéë íå ÿâëÿåòñÿ ñèñòåìíûì
shl eax,3
shl eax, 3
; ôàéë ÿâëÿåòñÿ ñêðûòûì? (àòðèáóò ñóùåñòâîâàíèå)
test [ebp-8],byte 1
jz .hidden
inc eax
test [ebp-8], byte 1
jz .hidden
inc eax
.hidden:
shl eax,1
shl eax, 1
; ôàéë âñåãäà òîëüêî äëÿ ÷òåíèÿ, òàê êàê ýòî CD
inc eax
mov [edi],eax
inc eax
mov [edi], eax
; ïîëó÷àåì âðåìÿ äëÿ ôàéëà
;÷àñ
movzx eax,byte [ebp-12]
shl eax,8
movzx eax, byte [ebp-12]
shl eax, 8
;ìèíóòà
mov al,[ebp-11]
shl eax,8
mov al, [ebp-11]
shl eax, 8
;ñåêóíäà
mov al,[ebp-10]
mov al, [ebp-10]
;âðåìÿ ñîçäàíèÿ ôàéëà
mov [edi+8],eax
mov [edi+8], eax
;âðåìÿ ïîñëåäíåãî äîñòóïà
mov [edi+16],eax
mov [edi+16], eax
;âðåìÿ ïîñëåäíåé çàïèñè
mov [edi+24],eax
mov [edi+24], eax
; ïîëó÷àåì äàòó äëÿ ôàéëà
;ãîä
movzx eax,byte [ebp-15]
add eax,1900
shl eax,8
movzx eax, byte [ebp-15]
add eax, 1900
shl eax, 8
;ìåñÿö
mov al,[ebp-14]
shl eax,8
mov al, [ebp-14]
shl eax, 8
;äåíü
mov al,[ebp-13]
mov al, [ebp-13]
;äàòà ñîçäàíèÿ ôàéëà
mov [edi+12],eax
mov [edi+12], eax
;âðåìÿ ïîñëåäíåãî äîñòóïà
mov [edi+20],eax
mov [edi+20], eax
;âðåìÿ ïîñëåäíåé çàïèñè
mov [edi+28],eax
mov [edi+28], eax
; ïîëó÷àåì òèï äàííûõ èìåíè
xor eax,eax
test dword [ebx+4], 1 ; 0=ANSI, 1=UNICODE
jnz .unicode_1
mov [edi+4],eax
jmp @f
xor eax, eax
test dword [ebx+4], 1; 0=ANSI, 1=UNICODE
jnz .unicode_1
mov [edi+4], eax
jmp @f
.unicode_1:
inc eax
mov [edi+4],eax
inc eax
mov [edi+4], eax
@@:
; ïîëó÷àåì ðàçìåð ôàéëà â áàéòàõ
xor eax,eax
mov [edi+32+4],eax
mov eax,[ebp-23]
mov [edi+32],eax
ret
xor eax, eax
mov [edi+32+4], eax
mov eax, [ebp-23]
mov [edi+32], eax
ret
 
;----------------------------------------------------------------
;
459,186 → 463,186
;
;----------------------------------------------------------------
fs_CdGetFileInfo:
cmp byte [esi], 0
jnz @f
mov eax, 2
ret
cmp byte [esi], 0
jnz @f
mov eax, 2
ret
@@:
push edi
call cd_find_lfn
pushfd
cmp [DevErrorCode], 0
jz @f
popfd
pop edi
mov eax, 11
ret
push edi
call cd_find_lfn
pushfd
cmp [DevErrorCode], 0
jz @f
popfd
pop edi
mov eax, 11
ret
@@:
popfd
jnc @f
pop edi
mov eax, ERROR_FILE_NOT_FOUND
ret
popfd
jnc @f
pop edi
mov eax, ERROR_FILE_NOT_FOUND
ret
@@:
 
mov edi, edx
push ebp
mov ebp, [cd_current_pointer_of_input]
add ebp, 33
call cd_get_parameters_of_file_1
pop ebp
and dword [edi+4], 0
pop edi
xor eax, eax
ret
mov edi, edx
push ebp
mov ebp, [cd_current_pointer_of_input]
add ebp, 33
call cd_get_parameters_of_file_1
pop ebp
and dword [edi+4], 0
pop edi
xor eax, eax
ret
 
;----------------------------------------------------------------
cd_find_lfn:
mov [cd_appl_data],0
mov [cd_appl_data], 0
; in: esi+ebp -> name
; out: CF=1 - file not found
; else CF=0 and [cd_current_pointer_of_input] direntry
push eax esi
push eax esi
; 16 ñåêòîð íà÷àëî íàáîðà äåñêðèïòîðîâ òîìîâ
 
call WaitUnitReady
cmp [DevErrorCode],0
jne .access_denied
call WaitUnitReady
cmp [DevErrorCode], 0
jne .access_denied
 
call prevent_medium_removal
call prevent_medium_removal
; òåñòîâîå ÷òåíèå
mov [CDSectorAddress],dword 16
mov [CDDataBuf_pointer],CDDataBuf
call ReadCDWRetr ;_1
cmp [DevErrorCode],0
jne .access_denied
mov [CDSectorAddress], dword 16
mov [CDDataBuf_pointer], CDDataBuf
call ReadCDWRetr;_1
cmp [DevErrorCode], 0
jne .access_denied
 
; âû÷èñëåíèå ïîñëåäíåé ñåññèè
call WaitUnitReady
cmp [DevErrorCode],0
jne .access_denied
call Read_TOC
mov ah,[CDDataBuf+4+4]
mov al,[CDDataBuf+4+5]
shl eax,16
mov ah,[CDDataBuf+4+6]
mov al,[CDDataBuf+4+7]
add eax,15
mov [CDSectorAddress],eax
call WaitUnitReady
cmp [DevErrorCode], 0
jne .access_denied
call Read_TOC
mov ah, [CDDataBuf+4+4]
mov al, [CDDataBuf+4+5]
shl eax, 16
mov ah, [CDDataBuf+4+6]
mov al, [CDDataBuf+4+7]
add eax, 15
mov [CDSectorAddress], eax
; mov [CDSectorAddress],dword 15
mov [CDDataBuf_pointer],CDDataBuf
mov [CDDataBuf_pointer], CDDataBuf
 
.start:
inc dword [CDSectorAddress]
call ReadCDWRetr ;_1
cmp [DevErrorCode],0
jne .access_denied
inc dword [CDSectorAddress]
call ReadCDWRetr;_1
cmp [DevErrorCode], 0
jne .access_denied
 
.start_check:
; ïðîâåðêà íà âøèâîñòü
cmp [CDDataBuf+1],dword 'CD00'
jne .access_denied
cmp [CDDataBuf+5],byte '1'
jne .access_denied
cmp [CDDataBuf+1], dword 'CD00'
jne .access_denied
cmp [CDDataBuf+5], byte '1'
jne .access_denied
; ñåêòîð ÿâëÿåòñÿ òåðìèíàòîðîì íàáîð äåñêðèïòîðîâ òîìîâ?
cmp [CDDataBuf],byte 0xff
je .access_denied
cmp [CDDataBuf], byte 0xff
je .access_denied
; ñåêòîð ÿâëÿåòñÿ äîïîëíèòåëüíûì è óëó÷øåííûì äåñêðèïòîðîì òîìà?
cmp [CDDataBuf],byte 0x2
jne .start
cmp [CDDataBuf], byte 0x2
jne .start
; ñåêòîð ÿâëÿåòñÿ äîïîëíèòåëüíûì äåñêðèïòîðîì òîìà?
cmp [CDDataBuf+6],byte 0x1
jne .start
cmp [CDDataBuf+6], byte 0x1
jne .start
 
; ïàðàìåòðû root äèðåêòðîðèè
mov eax,[CDDataBuf+0x9c+2] ; íà÷àëî root äèðåêòðîðèè
mov [CDSectorAddress],eax
mov eax,[CDDataBuf+0x9c+10] ; ðàçìåð root äèðåêòðîðèè
cmp byte [esi], 0
jnz @f
mov [cd_current_pointer_of_input],CDDataBuf+0x9c
jmp .done
mov eax, [CDDataBuf+0x9c+2]; íà÷àëî root äèðåêòðîðèè
mov [CDSectorAddress], eax
mov eax, [CDDataBuf+0x9c+10]; ðàçìåð root äèðåêòðîðèè
cmp byte [esi], 0
jnz @f
mov [cd_current_pointer_of_input], CDDataBuf+0x9c
jmp .done
@@:
; íà÷èíàåì ïîèñê
.mainloop:
dec dword [CDSectorAddress]
dec dword [CDSectorAddress]
.read_to_buffer:
inc dword [CDSectorAddress]
mov [CDDataBuf_pointer],CDDataBuf
call ReadCDWRetr ; ÷èòàåì ñåêòîð äèðåêòîðèè
cmp [DevErrorCode],0
jne .access_denied
push ebp
call cd_find_name_in_buffer
pop ebp
jnc .found
sub eax,2048
inc dword [CDSectorAddress]
mov [CDDataBuf_pointer], CDDataBuf
call ReadCDWRetr ; ÷èòàåì ñåêòîð äèðåêòîðèè
cmp [DevErrorCode], 0
jne .access_denied
push ebp
call cd_find_name_in_buffer
pop ebp
jnc .found
sub eax, 2048
; äèðåêòîðèÿ çàêîí÷èëàñü?
cmp eax,0
ja .read_to_buffer
cmp eax, 0
ja .read_to_buffer
; íåò èñêîìîãî ýëåìåíòà öåïî÷êè
.access_denied:
pop esi eax
mov [cd_appl_data],1
stc
ret
pop esi eax
mov [cd_appl_data], 1
stc
ret
; èñêîìûé ýëåìåíò öåïî÷êè íàéäåí
.found:
; êîíåö ïóòè ôàéëà
cmp byte [esi-1], 0
jz .done
cmp byte [esi-1], 0
jz .done
.nested:
mov eax,[cd_current_pointer_of_input]
push dword [eax+2]
pop dword [CDSectorAddress] ; íà÷àëî äèðåêòîðèè
mov eax,[eax+2+8] ; ðàçìåð äèðåêòîðèè
jmp .mainloop
mov eax, [cd_current_pointer_of_input]
push dword [eax+2]
pop dword [CDSectorAddress] ; íà÷àëî äèðåêòîðèè
mov eax, [eax+2+8]; ðàçìåð äèðåêòîðèè
jmp .mainloop
; óêàçàòåëü ôàéëà íàéäåí
.done:
test ebp, ebp
jz @f
mov esi, ebp
xor ebp, ebp
jmp .nested
test ebp, ebp
jz @f
mov esi, ebp
xor ebp, ebp
jmp .nested
@@:
pop esi eax
mov [cd_appl_data],1
clc
ret
pop esi eax
mov [cd_appl_data], 1
clc
ret
 
cd_find_name_in_buffer:
mov [cd_current_pointer_of_input_2],CDDataBuf
mov [cd_current_pointer_of_input_2], CDDataBuf
.start:
call cd_get_name
jc .not_found
call cd_compare_name
jc .start
call cd_get_name
jc .not_found
call cd_compare_name
jc .start
.found:
clc
ret
clc
ret
.not_found:
stc
ret
stc
ret
 
cd_get_name:
push eax
mov ebp,[cd_current_pointer_of_input_2]
mov [cd_current_pointer_of_input],ebp
mov eax,[ebp]
test eax,eax ; âõîäû çàêîí÷èëèñü?
jz .next_sector
cmp ebp,CDDataBuf+2048 ; áóôåð çàêîí÷èëñÿ?
jae .next_sector
movzx eax, byte [ebp]
add [cd_current_pointer_of_input_2],eax ; ñëåäóþùèé âõîä êàòàëîãà
add ebp,33 ; óêàçàòåëü óñòàíîâëåí íà íà÷àëî èìåíè
pop eax
clc
ret
push eax
mov ebp, [cd_current_pointer_of_input_2]
mov [cd_current_pointer_of_input], ebp
mov eax, [ebp]
test eax, eax ; âõîäû çàêîí÷èëèñü?
jz .next_sector
cmp ebp, CDDataBuf+2048 ; áóôåð çàêîí÷èëñÿ?
jae .next_sector
movzx eax, byte [ebp]
add [cd_current_pointer_of_input_2], eax; ñëåäóþùèé âõîä êàòàëîãà
add ebp, 33; óêàçàòåëü óñòàíîâëåí íà íà÷àëî èìåíè
pop eax
clc
ret
.next_sector:
pop eax
stc
ret
pop eax
stc
ret
 
cd_compare_name:
; compares ASCIIZ-names, case-insensitive (cp866 encoding)
646,112 → 650,112
; out: if names match: ZF=1 and esi->next component of name
; else: ZF=0, esi is not changed
; destroys eax
push esi eax edi
mov edi,ebp
push esi eax edi
mov edi, ebp
.loop:
cld
lodsb
push eax
call char_todown
call ansi2uni_char
xchg ah,al
scasw
pop eax
je .coincides
call char_toupper
call ansi2uni_char
xchg ah,al
sub edi,2
scasw
jne .name_not_coincide
cld
lodsb
push eax
call char_todown
call ansi2uni_char
xchg ah, al
scasw
pop eax
je .coincides
call char_toupper
call ansi2uni_char
xchg ah, al
sub edi, 2
scasw
jne .name_not_coincide
.coincides:
cmp [esi],byte '/' ; ðàçäåëèòåëü ïóòè, êîíåö èìåíè òåêóùåãî ýëåìåíòà
je .done
cmp [esi],byte 0 ; ðàçäåëèòåëü ïóòè, êîíåö èìåíè òåêóùåãî ýëåìåíòà
je .done
jmp .loop
cmp [esi], byte '/'; ðàçäåëèòåëü ïóòè, êîíåö èìåíè òåêóùåãî ýëåìåíòà
je .done
cmp [esi], byte 0; ðàçäåëèòåëü ïóòè, êîíåö èìåíè òåêóùåãî ýëåìåíòà
je .done
jmp .loop
.name_not_coincide:
pop edi eax esi
stc
ret
pop edi eax esi
stc
ret
.done:
; ïðîâåðêà êîíöà ôàéëà
cmp [edi],word 3B00h ; ñåïàðàòîð êîíöà ôàéëà ';'
je .done_1
cmp [edi], word 3B00h; ñåïàðàòîð êîíöà ôàéëà ';'
je .done_1
; ïðîâåðêà äëÿ ôàéëîâ íå çàêàí÷èâàþùèõñÿ ñåïàðàòîðîì
movzx eax,byte [ebp-33]
add eax,ebp
sub eax,34
cmp edi,eax
je .done_1
movzx eax, byte [ebp-33]
add eax, ebp
sub eax, 34
cmp edi, eax
je .done_1
; ïðîâåðêà êîíöà ïàïêè
movzx eax,byte [ebp-1]
add eax,ebp
cmp edi,eax
jne .name_not_coincide
movzx eax, byte [ebp-1]
add eax, ebp
cmp edi, eax
jne .name_not_coincide
.done_1:
pop edi eax
add esp,4
inc esi
clc
ret
pop edi eax
add esp, 4
inc esi
clc
ret
 
char_todown:
; convert character to uppercase, using cp866 encoding
; in: al=symbol
; out: al=converted symbol
cmp al, 'A'
jb .ret
cmp al, 'Z'
jbe .az
cmp al, '€'
jb .ret
cmp al, ''
jb .rus1
cmp al, 'Ÿ'
ja .ret
cmp al, 'A'
jb .ret
cmp al, 'Z'
jbe .az
cmp al, '€'
jb .ret
cmp al, ''
jb .rus1
cmp al, 'Ÿ'
ja .ret
; 0x90-0x9F -> 0xE0-0xEF
add al, 'à'-''
add al, 'à'-''
.ret:
ret
ret
.rus1:
; 0x80-0x8F -> 0xA0-0xAF
.az:
add al, 0x20
ret
add al, 0x20
ret
 
uni2ansi_char:
; convert UNICODE character in al to ANSI character in ax, using cp866 encoding
; in: ax=UNICODE character
; out: al=converted ANSI character
cmp ax, 0x80
jb .ascii
cmp ax, 0x401
jz .yo1
cmp ax, 0x451
jz .yo2
cmp ax, 0x410
jb .unk
cmp ax, 0x440
jb .rus1
cmp ax, 0x450
jb .rus2
cmp ax, 0x80
jb .ascii
cmp ax, 0x401
jz .yo1
cmp ax, 0x451
jz .yo2
cmp ax, 0x410
jb .unk
cmp ax, 0x440
jb .rus1
cmp ax, 0x450
jb .rus2
.unk:
mov al, '_'
jmp .doit
mov al, '_'
jmp .doit
.yo1:
mov al, 'ð'
jmp .doit
mov al, 'ð'
jmp .doit
.yo2:
mov al, 'ñ'
jmp .doit
mov al, 'ñ'
jmp .doit
.rus1:
; 0x410-0x43F -> 0x80-0xAF
add al, 0x70
jmp .doit
add al, 0x70
jmp .doit
.rus2:
; 0x440-0x44F -> 0xE0-0xEF
add al, 0xA0
add al, 0xA0
.ascii:
.doit:
ret
ret
/kernel/branches/net/fs/ntfs.inc
8,7 → 8,7
$Revision$
 
 
ntfs_test_bootsec:
ntfs_test_bootsec:
; in: ebx->buffer, edx=size of partition
; out: CF set <=> invalid
; 1. Name=='NTFS '
95,8 → 95,8
 
ntfs_setup: ; CODE XREF: part_set.inc
; By given bootsector, initialize some NTFS variables
call ntfs_test_bootsec
jc problem_fat_dec_count
; call ntfs_test_bootsec ; checking boot sector was already
; jc problem_fat_dec_count
movzx eax, byte [ebx+13]
mov [ntfs_data.sectors_per_cluster], eax
mov eax, [ebx+0x28]
256,7 → 256,7
mov edi, eax
mov ecx, [ntfs_data.mft_retrieval_size]
add ecx, ecx
rep movsd
rep movsd
push [ntfs_data.mft_retrieval]
mov [ntfs_data.mft_retrieval], eax
call kernel_free
639,7 → 639,7
mov edi, ntfs_attrlist_mft_buf
@@:
mov ecx, 0x200/4
rep movsd
rep movsd
mov eax, edi
pop edi esi
sub esi, 0x200
915,7 → 915,7
cmp ecx, 8
ja .end
push ecx
rep movsb
rep movsb
pop ecx
sub ecx, 8
neg ecx
923,13 → 923,13
jae .end
push eax
xor eax, eax
rep stosb
rep stosb
pop ecx
shr ecx, 4
cmp ecx, 8
ja .end
push ecx
rep movsb
rep movsb
pop ecx
sub ecx, 8
neg ecx
936,12 → 936,24
cmp byte [esi-1], 80h
cmc
sbb eax, eax
rep stosb
rep stosb
stc
.end:
pop edi ecx eax
ret
 
unichar_toupper:
push eax
call uni2ansi_char
cmp al, '_'
jz .unk
add esp, 4
call char_toupper
jmp ansi2uni_char
.unk:
pop eax
ret
 
ntfs_find_lfn:
; in: esi+ebp -> name
; out: CF=1 - file not found
1007,7 → 1019,7
mov edi, eax
mov ecx, [ntfs_data.cur_index_size]
shl ecx, 9-2
rep movsd
rep movsd
mov esi, eax
mov [ntfs_data.cur_index_size], ebp
push esi ebp
1030,8 → 1042,7
push edi
@@:
lodsw
call uni2ansi_char
call char_toupper
call unichar_toupper
push eax
mov al, [edi]
inc edi
1038,7 → 1049,8
cmp al, '/'
jz .slash
call char_toupper
cmp al, [esp]
call ansi2uni_char
cmp ax, [esp]
pop eax
loopz @b
jz .found
1187,7 → 1199,7
@@:
mov [esp+10h+4], ecx
mov edi, edx
rep movsb
rep movsb
mov edx, edi
pop ecx
sub ecx, [esp+10h]
1241,7 → 1253,7
mov edi, edx
mov esi, ntfs_bitmap_buf
add [esp+10h+4], ecx
rep movsb
rep movsb
pop ecx
xor eax, eax
cmp ecx, [ntfs_cur_read]
1358,7 → 1370,7
mov edi, eax
mov ecx, [ntfs_data.cur_index_size]
shl ecx, 9-2
rep movsd
rep movsd
mov esi, eax
mov [ntfs_data.cur_index_size], ebp
push esi ebp
1376,7 → 1388,7
mov edi, edx
mov ecx, 32/4
xor eax, eax
rep stosd
rep stosd
mov byte [edx], 1 ; version
mov ecx, [esp+4+18h]
push edx
1410,7 → 1422,7
mov [ntfs_cur_buf], edi
mov ecx, 0x400/4
xor eax, eax
rep stosd
rep stosd
mov [ntfs_cur_attr], 0xB0 ; $BITMAP
and [ntfs_cur_offs], 0
mov [ntfs_cur_size], 2
1466,7 → 1478,7
mov [ntfs_cur_buf], edi
mov ecx, 0x400/4
xor eax, eax
rep stosd
rep stosd
pop edi ecx
pop eax
push [ntfs_cur_offs]
1528,7 → 1540,7
lea ecx, [esi+1]
test byte [edi-0x24], 1
jz @f
rep stosw
rep stosw
pop ecx
xor eax, eax
stosw
1536,7 → 1548,7
add edi, 520
ret
@@:
rep stosb
rep stosb
pop ecx
xor eax, eax
stosb
1568,9 → 1580,9
test byte [edi-0x24], 1
jz .ansi
shr ecx, 1
rep movsd
rep movsd
adc ecx, ecx
rep movsw
rep movsw
and word [edi], 0
pop edi
add edi, 520
1641,6 → 1653,7
xchg eax, [esp]
div [_10000000]
pop edx
.sec:
; edx:eax = number of seconds since January 1, 1601
push eax
mov eax, edx
1813,3 → 1826,4
pop edi esi
xor eax, eax
ret
 
/kernel/branches/net/fs/parse_fn.inc
38,66 → 38,66
; use bx_from_load and init system directory /sys
proc Parser_params
locals
buff db 4 dup(?) ; for test cd
buff db 4 dup(?) ; for test cd
endl
mov eax,[OS_BASE+0x10000+bx_from_load]
mov ecx,sysdir_path
mov [ecx-64],dword 'sys'
cmp al,'r' ; if ram disk
jnz @f
mov [ecx],dword 'RD/?'
mov [ecx+3],byte ah
mov [ecx+4],byte 0
ret
mov eax, [OS_BASE+0x10000+bx_from_load]
mov ecx, sysdir_path
mov [ecx-64], dword 'sys'
cmp al, 'r'; if ram disk
jnz @f
mov [ecx], dword 'RD/?'
mov [ecx+3], byte ah
mov [ecx+4], byte 0
ret
@@:
cmp al,'m' ; if ram disk
jnz @f
mov [ecx],dword 'CD?/' ; if cd disk {m}
mov [ecx+4],byte '1'
mov [ecx+5],dword '/KOL'
mov [ecx+9],dword 'IBRI'
mov [ecx+13],byte 0
cmp al, 'm'; if ram disk
jnz @f
mov [ecx], dword 'CD?/'; if cd disk {m}
mov [ecx+4], byte '1'
mov [ecx+5], dword '/KOL'
mov [ecx+9], dword 'IBRI'
mov [ecx+13], byte 0
.next_cd:
mov [ecx+2],byte ah
inc ah
cmp ah,'5'
je .not_found_cd
lea edx,[buff]
pushad
stdcall read_file,read_firstapp,edx,0,4
popad
cmp [edx],dword 'MENU'
jne .next_cd
jmp .ok
mov [ecx+2], byte ah
inc ah
cmp ah, '5'
je .not_found_cd
lea edx, [buff]
pushad
stdcall read_file, read_firstapp, edx, 0, 4
popad
cmp [edx], dword 'MENU'
jne .next_cd
jmp .ok
@@:
sub al,49
mov [ecx],dword 'HD?/' ; if hard disk
mov [ecx+2],byte al
mov [ecx+4],byte ah
mov [ecx+5],dword '/KOL'
mov [ecx+9],dword 'IBRI'
mov [ecx+13],byte 0
sub al, 49
mov [ecx], dword 'HD?/'; if hard disk
mov [ecx+2], byte al
mov [ecx+4], byte ah
mov [ecx+5], dword '/KOL'
mov [ecx+9], dword 'IBRI'
mov [ecx+13], byte 0
.ok:
.not_found_cd:
ret
ret
endp
 
proc load_file_parse_table
stdcall kernel_alloc,0x1000
mov [tmp_file_name_table],eax
mov edi,eax
mov esi,sysdir_name
mov ecx,128/4
rep movsd
stdcall kernel_alloc, 0x1000
mov [tmp_file_name_table], eax
mov edi, eax
mov esi, sysdir_name
mov ecx, 128/4
rep movsd
 
invoke ini.enum_keys,conf_fname,conf_path_sect,get_every_key
invoke ini.enum_keys, conf_fname, conf_path_sect, get_every_key
 
mov eax,[tmp_file_name_table]
mov [full_file_name_table],eax
mov eax,[tmp_file_name_size]
mov [full_file_name_table.size],eax
ret
mov eax, [tmp_file_name_table]
mov [full_file_name_table], eax
mov eax, [tmp_file_name_size]
mov [full_file_name_table.size], eax
ret
endp
 
uglobal
129,7 → 129,7
@@:
stosb
 
invoke ini.get_str, [f_name],[sec_name],ecx,ebx,64,def_val_1
invoke ini.get_str, [f_name], [sec_name], ecx, ebx, 64, def_val_1
 
cmp byte [ebx], '/'
jnz @f
136,7 → 136,7
lea esi, [ebx+1]
mov edi, ebx
mov ecx, 63
rep movsb
rep movsb
@@:
push ebp
mov ebp, [tmp_file_name_table]
/kernel/branches/net/fs/part_set.inc
9,6 → 9,7
 
 
;*************************************************************
;* 13.02.2010 Find all partition and check supported FS
;* 12.07.2007 Check all 4 entry of MBR and EMBR
;* 29.04.2006 Elimination of hangup after the
;* expiration hd_wait_timeout - Mario79
26,7 → 27,7
;******************************************************
PARTITION_START dd 0x3f
PARTITION_END dd 0
fs_type db 0 ; 0=none, 1=NTFS, 16=FAT16, 32=FAT32
fs_type db 0 ; 1=NTFS, 2=EXT2/3, 16=FAT16, 32=FAT32
align 4
 
fs_dependent_data_start:
54,7 → 55,8
fs_dependent_data_end:
file_system_data_size = $ - PARTITION_START
if file_system_data_size > 96
ERROR: sizeof(file system data) too big!
ERROR:
sizeof(file system data) too big!
end if
 
virtual at fs_dependent_data_start
74,10 → 76,36
.cur_index_size dd ?
.cur_index_buf dd ?
if $ > fs_dependent_data_end
ERROR: increase sizeof(fs_dependent_data)!
ERROR:
increase sizeof(fs_dependent_data)!
end if
end virtual
 
virtual at fs_dependent_data_start
; EXT2 data
ext2_data:
.log_block_size dd ?
.block_size dd ?
.count_block_in_block dd ?
.blocks_per_group dd ?
.inodes_per_group dd ?
.global_desc_table dd ?
.root_inode dd ? ; pointer to root inode in memory
.inode_size dd ?
.count_pointer_in_block dd ? ; block_size / 4
.count_pointer_in_block_square dd ? ; (block_size / 4)**2
.ext2_save_block dd ? ; ¡«®ª ­  £«®¡ «ì­ãî 1 ¯à®æ¥¤ãàã
.ext2_temp_block dd ? ; ¡«®ª ¤«ï ¬¥«ª¨å ¯à®æ¥¤ãà
.ext2_save_inode dd ? ; inode ­  £«®¡ «ì­ãî ¯à®æ¥¤ãàã
.ext2_temp_inode dd ? ; inode ¤«ï ¬¥«ª¨å ¯à®æ¥¤ãà
.sb dd ? ; superblock
.groups_count dd ?
if $ > fs_dependent_data_end
ERROR:
increase sizeof(fs_dependent_data)!
end if
end virtual
 
;***************************************************************************
; End place
; Mario79
105,6 → 133,7
db 0xd6 ; Old Multiuser DOS secured: fat16 >32M
db 0x07 ; NTFS
db 0x27 ; NTFS, hidden
db 0x83 ; Linux native file system (ext2fs)
partition_types_end:
 
 
118,233 → 147,249
endg
 
; Partition chain used:
; MBR ; PARTITION2 ; PARTITION3 ; PARTITION4
;==========================================================
; fat16/32 +-- fat16/32 +-- fat16/32 +-- fat16/32 +--
; extended --+ extended --+ extended --+ extended --+
; 0 0 0 0
; 0 0 0 0
; Notes:
; - extended partition need to be in second entry on table
; - it will skip over removed partitions
; MBR <---------------------
; | |
; |-> PARTITION1 |
; |-> EXTENDED PARTITION - ;not need be second partition
; |-> PARTITION3
; |-> PARTITION4
 
set_FAT32_variables:
mov [problem_partition],0
call reserve_hd1
call reserve_hd_channel
set_PARTITION_variables:
set_FAT32_variables: ;deprecated
and [problem_partition], 0
call reserve_hd1
call reserve_hd_channel
 
pushad
pushad
 
cmp dword [hdpos],0
je problem_hd
cmp dword [hdpos], 0
je problem_hd
 
xor ecx,ecx ; partition count
mov edx,-1 ; flag for partition
xor eax,eax ; read MBR
xor ebp,ebp ; extended partition start
xor ecx, ecx ; partition count
;or edx,-1 ; flag for partition
xor eax, eax ; address MBR
xor ebp, ebp ; extended partition start
 
new_partition:
test ebp,ebp ; is there extended partition?
jnz extended_already_set ; yes
xchg ebp,eax ; no. set it now
new_mbr:
test ebp, ebp ; is there extended partition? (MBR or EMBR)
jnz extended_already_set; yes
xchg ebp, eax ; no. set it now
 
extended_already_set:
add eax,ebp ; mbr=mbr+0, ext_part=ext_start+relat_start
mov ebx,buffer
call hd_read
cmp [hd_error],0
jne problem_hd
add eax, ebp ; mbr=mbr+0, ext_part=ext_start+relat_start
mov ebx, buffer
call hd_read
cmp [hd_error], 0
jne problem_hd
 
cmp word [ebx+0x1fe],0xaa55 ; is it valid boot sector?
jnz end_partition_chain
cmp dword [ebx+0x1be+0xc],0 ; skip over empty partition
; jz next_partition
jnz .next_primary_partition
cmp dword [ebx+0x1be+0xc+16],0
jnz next_primary_partition
cmp dword [ebx+0x1be+0xc+16+16],0
jnz next_primary_partition_1
cmp dword [ebx+0x1be+0xc+16+16+16],0
jnz next_primary_partition_2
jmp next_partition
.next_primary_partition:
push eax
mov al,[ebx+0x1be+4] ; get primary partition type
call scan_partition_types
pop eax
jnz next_primary_partition ; no. skip over
cmp word [ebx+0x1fe], 0xaa55; is it valid boot sector?
jnz end_partition_chain
push eax ; push only one time
cmp dword [ebx+0x1be+0xc], 0; skip over empty partition
jnz test_primary_partition_0
cmp dword [ebx+0x1be+0xc+16], 0
jnz test_primary_partition_1
cmp dword [ebx+0x1be+0xc+16+16], 0
jnz test_primary_partition_2
cmp dword [ebx+0x1be+0xc+16+16+16], 0
jnz test_primary_partition_3
pop eax
jmp end_partition_chain
 
inc ecx
cmp ecx,[fat32part] ; is it wanted partition?
jnz next_primary_partition ; no
test_primary_partition_0:
mov al, [ebx+0x1be+4]; get primary partition type
call scan_partition_types
jnz test_primary_partition_1; no. skip over
 
mov edx, eax ; start sector
add edx, [ebx+0x1be+8] ; add relative start
push edx
add edx, [ebx+0x1be+12] ; add length
dec edx ; PARTITION_END is inclusive
mov [PARTITION_END], edx ; note that this can be changed
inc ecx
cmp ecx, [known_part]; is it wanted partition?
jnz test_primary_partition_1; no
 
pop eax
;mov edx, eax ; start sector
add eax, [ebx+0x1be+8] ; add relative start
;mov [PARTITON_START],edx
;push edx
mov edx, [ebx+0x1be+12] ; length
;add edx, eax ; add length
;dec edx ; PARTITION_END is inclusive
;mov [PARTITION_END], edx ; note that this can be changed
; when file system data will be available
mov dl, [ebx+0x1be+4]
mov [fs_type], dl ; save for FS recognizer (separate FAT vs NTFS)
pop edx
mov cl, [ebx+0x1be+4] ; fs_type
;mov [fs_type], dl ; save for FS recognizer (separate FAT vs NTFS)
;pop edx
jmp hd_and_partition_ok
 
next_primary_partition:
push eax
mov al,[ebx+0x1be+4+16] ; get primary partition type
call scan_partition_types
pop eax
jnz next_primary_partition_1 ; no. skip over
test_primary_partition_1:
mov al, [ebx+0x1be+4+16]; get primary partition type
call scan_partition_types
jnz test_primary_partition_2 ; no. skip over
 
inc ecx
cmp ecx,[fat32part] ; is it wanted partition?
jnz next_primary_partition_1 ; no
inc ecx
cmp ecx, [known_part]; is it wanted partition?
jnz test_primary_partition_2 ; no
 
mov edx, eax
add edx, [ebx+0x1be+8+16]
push edx
add edx, [ebx+0x1be+12+16]
dec edx
mov [PARTITION_END], edx
mov dl, [ebx+0x1be+4+16]
mov [fs_type], dl
pop edx
pop eax
add eax, [ebx+0x1be+8+16]
mov edx, [ebx+0x1be+12+16]
mov cl, [ebx+0x1be+4+16]
jmp hd_and_partition_ok
 
next_primary_partition_1:
push eax
mov al,[ebx+0x1be+4+16+16] ; get primary partition type
call scan_partition_types
pop eax
jnz next_primary_partition_2 ; no. skip over
;mov edx, eax
;add edx, [ebx+0x1be+8+16]
;push edx
;add edx, [ebx+0x1be+12+16]
;dec edx
;mov [PARTITION_END], edx
;mov al, [ebx+0x1be+4+16]
;mov [fs_type], dl
;pop edx
 
inc ecx
cmp ecx,[fat32part] ; is it wanted partition?
jnz next_primary_partition_2 ; no
test_primary_partition_2:
mov al, [ebx+0x1be+4+16+16]; get primary partition type
call scan_partition_types
jnz test_primary_partition_3 ; no. skip over
 
mov edx, eax
add edx, [ebx+0x1be+8+16+16]
push edx
add edx, [ebx+0x1be+12+16+16]
dec edx
mov [PARTITION_END], edx
mov dl, [ebx+0x1be+4+16+16]
mov [fs_type], dl
pop edx
inc ecx
cmp ecx, [known_part]; is it wanted partition?
jnz test_primary_partition_3 ; no
 
next_primary_partition_2:
push eax
mov al,[ebx+0x1be+4+16+16+16] ; get primary partition type
call scan_partition_types
pop eax
jnz next_partition ; no. skip over
pop eax
add eax, [ebx+0x1be+8+16+16]
mov edx, [ebx+0x1be+12+16+16]
mov cl, [ebx+0x1be+4+16+16]
jmp hd_and_partition_ok
;mov edx, eax
;add edx, [ebx+0x1be+8+16+16]
;push edx
;add edx, [ebx+0x1be+12+16+16]
;dec edx
;mov [PARTITION_END], edx
;mov al, [ebx+0x1be+4+16+16]
;mov [fs_type], dl
;pop edx
 
inc ecx
cmp ecx,[fat32part] ; is it wanted partition?
jnz next_partition ; no
test_primary_partition_3:
mov al, [ebx+0x1be+4+16+16+16]; get primary partition type
call scan_partition_types
jnz test_ext_partition_0 ; no. skip over
 
mov edx, eax
add edx, [ebx+0x1be+8+16+16+16]
push edx
add edx, [ebx+0x1be+12+16+16+16]
dec edx
mov [PARTITION_END], edx
mov dl, [ebx+0x1be+4+16+16+16]
mov [fs_type], dl
pop edx
inc ecx
cmp ecx, [known_part]; is it wanted partition?
jnz test_ext_partition_0; no
 
next_partition:
push eax
mov al,[ebx+0x1be+4] ; get extended partition type
call scan_extended_types
pop eax
jnz next_partition_1
pop eax
add eax, [ebx+0x1be+8+16+16+16]
mov edx, [ebx+0x1be+12+16+16+16]
mov cl, [ebx+0x1be+4+16+16+16]
jmp hd_and_partition_ok
 
mov eax,[ebx+0x1be+8] ; add relative start
test eax,eax ; is there extended partition?
jnz new_partition ; yes. read it
;mov edx, eax
;add edx, [ebx+0x1be+8+16+16+16]
;push edx
;add edx, [ebx+0x1be+12+16+16+16]
;dec edx
;mov [PARTITION_END], edx
;mov al, [ebx+0x1be+4+16+16+16]
;mov [fs_type], dl
;pop edx
 
next_partition_1:
push eax
mov al,[ebx+0x1be+4+16] ; get extended partition type
call scan_extended_types
pop eax
jnz next_partition_2
test_ext_partition_0:
pop eax ; ¯à®áâ® ¢ëª¨¤ë¢ ¥¬ ¨§ á⥪ 
mov al, [ebx+0x1be+4]; get extended partition type
call scan_extended_types
jnz test_ext_partition_1
 
mov eax,[ebx+0x1be+8+16] ; add relative start
test eax,eax ; is there extended partition?
jnz new_partition ; yes. read it
mov eax, [ebx+0x1be+8]; add relative start
test eax, eax ; is there extended partition?
jnz new_mbr ; yes. read it
 
next_partition_2:
push eax
mov al,[ebx+0x1be+4+16+16] ; get extended partition type
call scan_extended_types
pop eax
jnz next_partition_3
test_ext_partition_1:
mov al, [ebx+0x1be+4+16]; get extended partition type
call scan_extended_types
jnz test_ext_partition_2
 
mov eax,[ebx+0x1be+8+16+16] ; add relative start
test eax,eax ; is there extended partition?
jnz new_partition ; yes. read it
next_partition_3:
push eax
mov al,[ebx+0x1be+4+16+16+16] ; get extended partition type
call scan_extended_types
pop eax
jnz end_partition_chain ; no. end chain
mov eax, [ebx+0x1be+8+16]; add relative start
test eax, eax ; is there extended partition?
jnz new_mbr ; yes. read it
 
mov eax,[ebx+0x1be+8+16+16+16] ; get start of extended partition
test eax,eax ; is there extended partition?
jnz new_partition ; yes. read it
test_ext_partition_2:
mov al, [ebx+0x1be+4+16+16]; get extended partition type
call scan_extended_types
jnz test_ext_partition_3
 
mov eax, [ebx+0x1be+8+16+16]; add relative start
test eax, eax ; is there extended partition?
jnz new_mbr ; yes. read it
 
test_ext_partition_3:
mov al, [ebx+0x1be+4+16+16+16]; get extended partition type
call scan_extended_types
jnz end_partition_chain; no. end chain
 
mov eax, [ebx+0x1be+8+16+16+16]; get start of extended partition
test eax, eax ; is there extended partition?
jnz new_mbr ; yes. read it
 
end_partition_chain:
mov [partition_count],ecx
;mov [partition_count],ecx
 
cmp edx,-1 ; found wanted partition?
jnz hd_and_partition_ok ; yes. install it
jmp problem_partition_or_fat
;cmp edx,-1 ; found wanted partition?
;jnz hd_and_partition_ok ; yes. install it
;jmp problem_partition_or_fat
problem_hd:
or [problem_partition], 2
jmp return_from_part_set
 
 
scan_partition_types:
push ecx
mov edi,partition_types
mov ecx,partition_types_end-partition_types
cld
repne scasb ; is partition type ok?
pop ecx
ret
push ecx
mov edi, partition_types
mov ecx, partition_types_end-partition_types
cld
repne scasb ; is partition type ok?
pop ecx
ret
 
scan_extended_types:
push ecx
mov edi,extended_types
mov ecx,extended_types_end-extended_types
cld
repne scasb ; is it extended partition?
pop ecx
ret
push ecx
mov edi, extended_types
mov ecx, extended_types_end-extended_types
cld
repne scasb ; is it extended partition?
pop ecx
ret
 
problem_fat_dec_count: ; bootsector is missing or another problem
dec [partition_count] ; remove it from partition_count
; dec [partition_count] ; remove it from partition_count
 
problem_partition_or_fat:
problem_hd:
popad
or [problem_partition], 1
 
mov [fs_type],0
call free_hd_channel
mov [hd1_status],0 ; free
mov [problem_partition],1
ret
return_from_part_set:
popad
;mov [fs_type],0
call free_hd_channel
mov [hd1_status], 0 ; free
ret
 
hd_and_partition_ok:
mov eax,edx
mov [PARTITION_START],eax
mov edx, [PARTITION_END]
sub edx, eax
inc edx ; edx = length of partition
 
;eax = PARTITION_START edx=PARTITION_LENGTH cl=fs_type
mov [fs_type], cl
;mov eax,edx
mov [PARTITION_START], eax
add edx, eax
dec edx
mov [PARTITION_END], edx
 
; mov edx, [PARTITION_END]
; sub edx, eax
; inc edx ; edx = length of partition § ç¥¬ ®­® ­ ¬??
 
; mov [hd_setup],1
mov ebx,buffer
call hd_read ; read boot sector of partition
mov ebx, buffer
call hd_read ; read boot sector of partition
cmp [hd_error], 0
jz boot_read_ok
cmp [fs_type], 7
366,116 → 411,124
add eax, [PARTITION_START]
call hd_read
cmp [hd_error], 0
jnz problem_fat_dec_count ; ­¥ áã¤ì¡ ...
jnz problem_fat_dec_count ; no chance...
boot_read_ok:
; mov [hd_setup], 0
 
; if we are running on NTFS, check bootsector
; cmp [fs_type], 7
; jz ntfs_setup
call ntfs_test_bootsec
 
call ntfs_test_bootsec ; test ntfs
jnc ntfs_setup
 
cmp word [ebx+0x1fe],0xaa55 ; is it valid boot sector?
jnz problem_fat_dec_count
call ext2_test_superblock ; test ext2fs
jnc ext2_setup
 
movzx eax,word [ebx+0xe] ; sectors reserved
add eax,[PARTITION_START]
mov [FAT_START],eax ; fat_start = partition_start + reserved
mov eax, [PARTITION_START] ;ext2 test changes [buffer]
call hd_read
cmp [hd_error], 0
jnz problem_fat_dec_count
 
movzx eax,byte [ebx+0xd] ; sectors per cluster
test eax,eax
jz problem_fat_dec_count
mov [SECTORS_PER_CLUSTER],eax
cmp word [ebx+0x1fe], 0xaa55; is it valid boot sector?
jnz problem_fat_dec_count
 
movzx ecx,word [ebx+0xb] ; bytes per sector
cmp ecx,0x200
jnz problem_fat_dec_count
mov [BYTES_PER_SECTOR],ecx
movzx eax, word [ebx+0xe]; sectors reserved
add eax, [PARTITION_START]
mov [FAT_START], eax; fat_start = partition_start + reserved
 
movzx eax,word [ebx+0x11] ; count of rootdir entries (=0 fat32)
mov edx,32
mul edx
dec ecx
add eax,ecx ; round up if not equal count
inc ecx ; bytes per sector
div ecx
mov [ROOT_SECTORS],eax ; count of rootdir sectors
movzx eax, byte [ebx+0xd]; sectors per cluster
test eax, eax
jz problem_fat_dec_count
mov [SECTORS_PER_CLUSTER], eax
 
movzx eax,word [ebx+0x16] ; sectors per fat <65536
test eax,eax
jnz fat16_fatsize
mov eax,[ebx+0x24] ; sectors per fat
movzx ecx, word [ebx+0xb]; bytes per sector
cmp ecx, 0x200
jnz problem_fat_dec_count
mov [BYTES_PER_SECTOR], ecx
 
movzx eax, word [ebx+0x11]; count of rootdir entries (=0 fat32)
mov edx, 32
mul edx
dec ecx
add eax, ecx ; round up if not equal count
inc ecx ; bytes per sector
div ecx
mov [ROOT_SECTORS], eax; count of rootdir sectors
 
movzx eax, word [ebx+0x16]; sectors per fat <65536
test eax, eax
jnz fat16_fatsize
mov eax, [ebx+0x24] ; sectors per fat
fat16_fatsize:
mov [SECTORS_PER_FAT],eax
mov [SECTORS_PER_FAT], eax
 
movzx eax,byte [ebx+0x10] ; number of fats
test eax,eax ; if 0 it's not fat partition
jz problem_fat_dec_count
mov [NUMBER_OF_FATS],eax
imul eax,[SECTORS_PER_FAT]
add eax,[FAT_START]
mov [ROOT_START],eax ; rootdir = fat_start + fat_size * fat_count
add eax,[ROOT_SECTORS] ; rootdir sectors should be 0 on fat32
mov [DATA_START],eax ; data area = rootdir + rootdir_size
movzx eax, byte [ebx+0x10]; number of fats
test eax, eax ; if 0 it's not fat partition
jz problem_fat_dec_count
mov [NUMBER_OF_FATS], eax
imul eax, [SECTORS_PER_FAT]
add eax, [FAT_START]
mov [ROOT_START], eax; rootdir = fat_start + fat_size * fat_count
add eax, [ROOT_SECTORS]; rootdir sectors should be 0 on fat32
mov [DATA_START], eax; data area = rootdir + rootdir_size
 
movzx eax,word [ebx+0x13] ; total sector count <65536
test eax,eax
jnz fat16_total
mov eax,[ebx+0x20] ; total sector count
movzx eax, word [ebx+0x13]; total sector count <65536
test eax, eax
jnz fat16_total
mov eax, [ebx+0x20] ; total sector count
fat16_total:
add eax,[PARTITION_START]
dec eax
mov [PARTITION_END],eax
inc eax
sub eax,[DATA_START] ; eax = count of data sectors
xor edx,edx
div dword [SECTORS_PER_CLUSTER]
inc eax
mov [LAST_CLUSTER],eax
dec eax ; cluster count
mov [fatStartScan],2
add eax, [PARTITION_START]
dec eax
mov [PARTITION_END], eax
inc eax
sub eax, [DATA_START]; eax = count of data sectors
xor edx, edx
div dword [SECTORS_PER_CLUSTER]
inc eax
mov [LAST_CLUSTER], eax
dec eax ; cluster count
mov [fatStartScan], 2
 
; limits by Microsoft Hardware White Paper v1.03
cmp eax,4085 ; 0xff5
jb problem_fat_dec_count ; fat12 not supported
cmp eax,65525 ; 0xfff5
jb fat16_partition
cmp eax, 4085 ; 0xff5
jb problem_fat_dec_count; fat12 not supported
cmp eax, 65525 ; 0xfff5
jb fat16_partition
 
fat32_partition:
mov eax,[ebx+0x2c] ; rootdir cluster
mov [ROOT_CLUSTER],eax
movzx eax,word [ebx+0x30] ; fs info sector
add eax,[PARTITION_START]
mov [ADR_FSINFO],eax
call hd_read
mov eax,[ebx+0x1ec]
cmp eax,-1
jz @f
mov [fatStartScan],eax
mov eax, [ebx+0x2c] ; rootdir cluster
mov [ROOT_CLUSTER], eax
movzx eax, word [ebx+0x30]; fs info sector
add eax, [PARTITION_START]
mov [ADR_FSINFO], eax
call hd_read
mov eax, [ebx+0x1ec]
cmp eax, -1
jz @f
mov [fatStartScan], eax
@@:
 
popad
popad
 
mov [fatRESERVED],0x0FFFFFF6
mov [fatBAD],0x0FFFFFF7
mov [fatEND],0x0FFFFFF8
mov [fatMASK],0x0FFFFFFF
mov [fs_type],32 ; Fat32
call free_hd_channel
mov [hd1_status],0 ; free
ret
mov [fatRESERVED], 0x0FFFFFF6
mov [fatBAD], 0x0FFFFFF7
mov [fatEND], 0x0FFFFFF8
mov [fatMASK], 0x0FFFFFFF
mov [fs_type], 32 ; Fat32
call free_hd_channel
mov [hd1_status], 0 ; free
ret
 
fat16_partition:
xor eax,eax
mov [ROOT_CLUSTER],eax
xor eax, eax
mov [ROOT_CLUSTER], eax
 
popad
popad
 
mov [fatRESERVED],0x0000FFF6
mov [fatBAD],0x0000FFF7
mov [fatEND],0x0000FFF8
mov [fatMASK],0x0000FFFF
mov [fs_type],16 ; Fat16
call free_hd_channel
mov [hd1_status],0 ; free
ret
mov [fatRESERVED], 0x0000FFF6
mov [fatBAD], 0x0000FFF7
mov [fatEND], 0x0000FFF8
mov [fatMASK], 0x0000FFFF
mov [fs_type], 16 ; Fat16
call free_hd_channel
mov [hd1_status], 0 ; free
ret