/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 |