/kernel/trunk/fs/ext.inc |
---|
11,7 → 11,7 |
; in: |
; ebx -> parameter structure of sysfunc 70 |
; ebp -> EXTFS structure |
; esi -> path string |
; esi -> path string in UTF-8 |
; out: |
; eax, ebx = return values for sysfunc 70 |
iglobal |
193,7 → 193,7 |
cmp [ebx+SUPERBLOCK.magic], 0xEF53 |
jne .fail |
cmp [ebx+SUPERBLOCK.state], 1 |
jne .fail |
ja .fail |
test [ebx+SUPERBLOCK.incompatibleFlags], not INCOMPATIBLE_SUPPORT |
jnz .fail |
cmp [ebx+SUPERBLOCK.sectorsPerBlockLog], 6 ; 64KB |
1176,7 → 1176,7 |
; in: |
; eax = inode on which to link |
; ebx = inode to link |
; esi -> name |
; esi -> name in UTF-8 |
; dl = file type |
push esi edi ebx ecx eax edx |
call strlen |
1414,9 → 1414,9 |
ret |
findInode_parent: |
; in: esi -> path |
; in: esi -> path string in UTF-8 |
; out: |
; edi -> file name |
; edi -> file name in UTF-8 |
; esi = inode |
push esi |
xor edi, edi |
1449,7 → 1449,7 |
ret |
findInode: |
; in: esi -> path string |
; in: esi -> path string in UTF-8 |
; out: |
; [ebp+EXTFS.mainInodeBuffer] = inode |
; esi = inode number |
1485,32 → 1485,16 |
call extfsReadBlock |
jc .error_get_block |
push esi edx |
sub esp, 256 |
mov edx, ebx |
add edx, [ebp+EXTFS.bytesPerBlock] |
.start_rec: |
cmp [ebx+DIRENTRY.inodeNumber], 0 |
jz .next_rec |
mov edi, esp |
push esi |
movzx ecx, [ebx+DIRENTRY.nameLength] |
lea esi, [ebx+DIRENTRY.name] |
call utf8_to_cp866 |
mov ecx, edi |
lea edi, [esp+4] |
sub ecx, edi ; number of bytes in resulting string |
mov esi, [esp] |
@@: ; edi -> converted string in stack, ecx = size, esi -> original file path |
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 |
lea edi, [ebx+DIRENTRY.name] |
repz cmpsb |
jz .test_find |
@@: ; doesn't match |
pop esi |
.next_rec: |
1528,8 → 1512,7 |
jne @b |
inc esi |
@@: |
add esp, 256+4 |
pop edx edi ecx |
pop edx edx edi ecx |
; ebx -> matched directory entry, esi -> name without parent, or not changed |
cmp edi, esi |
je .next_folder_block |
1697,10 → 1680,12 |
inc dword [edi+8] |
inc dword [edi+4] |
push ebx edi ecx esi edx |
pushd [edi+12] |
mov edi, edx |
xor eax, eax |
mov ecx, 40 / 4 |
rep stosd |
popd [edx+4] |
mov eax, [ebx+DIRENTRY.inodeNumber] |
lea ebx, [ebp+EXTFS.tempInodeBuffer] |
call readInode |
1730,16 → 1715,25 |
@@: |
mov esi, [esp+12] |
movzx ecx, [esi+DIRENTRY.nameLength] |
lea esi, [esi+DIRENTRY.name] |
add ecx, esi |
cmp byte [esi], '.' |
jnz @f |
or byte [edx], KOS_HIDDEN |
@@: |
lea edi, [edx+40] |
lea esi, [esi+DIRENTRY.name] |
call utf8_to_cp866 |
cmp byte [edx+4], 1 |
jz .utf16 |
@@: |
call utf8to16 |
call uni2ansi_char |
stosb |
cmp esi, ecx |
jc @b |
and byte [edi], 0 |
add edx, 40+264 |
@@: |
pop esi ecx edi ebx |
cmp byte [edx+40], '.' |
jne @f |
or dword [edx], KOS_HIDDEN |
@@: |
add edx, 40+264 ; go to the next record |
dec ecx |
.empty_rec: |
movzx eax, [ebx+DIRENTRY.entryLength] |
1754,6 → 1748,15 |
push .wanted_start |
jmp .end_block |
.utf16: |
call utf8to16 |
stosw |
cmp esi, ecx |
jc .utf16 |
and word [edi], 0 |
add edx, 40+520 |
jmp @b |
.end_dir: |
call ext_unlock |
mov edx, [edi+28] |
/kernel/trunk/fs/fat.inc |
---|
11,7 → 11,7 |
; in: |
; ebx -> parameter structure of sysfunc 70 |
; ebp -> FAT structure |
; esi -> path string |
; esi -> path string in UTF-8 |
; out: |
; eax, ebx = return values for sysfunc 70 |
iglobal |
445,37 → 445,22 |
endg |
fat_name_is_legal: |
; in: esi->(long) name |
; out: CF set <=> legal |
; destroys eax |
; in: esi -> UTF-8 name |
; out: CF=1 -> legal |
push esi |
xor eax, eax |
@@: |
lodsb |
test al, al |
jz .done |
cmp al, 80h |
jae .big |
js @b |
test [fat_legal_chars+eax], 1 |
jnz @b |
.err: |
test al, al |
jnz @f |
stc |
@@: |
pop esi |
clc |
ret |
.big: |
; 0x80-0xAF, 0xE0-0xEF |
cmp al, 0xB0 |
jb @b |
cmp al, 0xE0 |
jb .err |
cmp al, 0xF0 |
jb @b |
jmp .err |
.done: |
sub esi, [esp] |
cmp esi, 257 |
pop esi |
ret |
fat_next_short_name: |
; in: edi->8+3 name |
567,9 → 552,9 |
ret |
fat_gen_short_name: |
; in: esi->long name |
; in: |
; esi -> UTF-8 name |
; edi->buffer (8+3=11 chars) |
; out: buffer filled |
pushad |
mov eax, ' ' |
push edi |
583,38 → 568,24 |
.loop: |
lodsb |
test al, al |
js .space |
jz .done |
call char_toupper |
cmp al, ' ' |
test [fat_legal_chars+eax], 2 |
jz .space |
cmp al, 80h |
ja .big |
test [fat_legal_chars+eax], 2 |
jnz .symbol |
.inv_symbol: |
mov al, '_' |
or bh, 1 |
.symbol: |
cmp al, '.' |
jz .dot |
.normal_symbol: |
dec bl |
jns .store |
mov bl, 0 |
inc bl |
.space: |
or bh, 1 |
jmp .loop |
.store: |
call cp866toUpper |
stosb |
jmp .loop |
.big: |
cmp al, 0xB0 |
jb .normal_symbol |
cmp al, 0xE0 |
jb .inv_symbol |
cmp al, 0xF0 |
jb .normal_symbol |
jmp .inv_symbol |
.dot: |
test bh, 2 |
jz .firstdot |
1187,107 → 1158,58 |
lea ecx, [ebp+FAT.Lock] |
jmp mutex_unlock |
fat_get_name: |
; in: edi->FAT entry |
; out: CF=1 - no valid entry |
; else CF=0 and ebp->ASCIIZ-name |
; (maximum length of filename is 255 (wide) symbols without trailing 0, |
; but implementation requires buffer 261 words) |
; destroys eax |
; out: ebp -> UTF-16 name, CF=1 -> no valid entry |
cmp byte [edi], 0 |
jz .no |
cmp byte [edi], 0xE5 |
jnz @f |
.no: |
stc |
ret |
@@: |
jz .no |
cmp byte [edi+11], 0xF |
jz .longname |
test byte [edi+11], 8 |
jnz .no |
push ecx |
push edi ebp |
test byte [ebp-4], 1 |
jnz .unicode_short |
mov eax, [edi] |
mov ecx, [edi+4] |
mov [ebp], eax |
mov [ebp+4], ecx |
push ecx esi edi |
mov esi, edi |
mov edi, ebp |
mov ecx, 8 |
@@: |
cmp byte [ebp+ecx-1], ' ' |
loope @b |
mov eax, [edi+8] |
cmp al, ' ' |
je .done |
shl eax, 8 |
mov al, '.' |
lea ebp, [ebp+ecx+1] |
mov [ebp], eax |
mov ecx, 3 |
@@: |
rol eax, 8 |
cmp al, ' ' |
jne .done |
loop @b |
dec ebp |
.done: |
and byte [ebp+ecx+1], 0 ; CF=0 |
pop ebp edi ecx |
ret |
.unicode_short: |
mov ecx, 8 |
push ecx |
@@: |
mov al, [edi] |
inc edi |
lodsb |
call ansi2uni_char |
mov [ebp], ax |
inc ebp |
inc ebp |
stosw |
loop @b |
pop ecx |
mov cl, 8 |
@@: |
cmp word [ebp-2], ' ' |
cmp word [edi-2], ' ' |
jnz @f |
dec ebp |
dec ebp |
sub edi, 2 |
loop @b |
@@: |
mov word [ebp], '.' |
inc ebp |
inc ebp |
mov ecx, 3 |
push ecx |
mov word [edi], '.' |
add edi, 2 |
mov cl, 3 |
@@: |
mov al, [edi] |
inc edi |
lodsb |
call ansi2uni_char |
mov [ebp], ax |
inc ebp |
inc ebp |
stosw |
loop @b |
pop ecx |
mov cl, 3 |
@@: |
cmp word [ebp-2], ' ' |
cmp word [edi-2], ' ' |
jnz @f |
dec ebp |
dec ebp |
sub edi, 2 |
loop @b |
dec ebp |
dec ebp |
sub edi, 2 |
@@: |
and word [ebp], 0 ; CF=0 |
pop ebp edi ecx |
and word [edi], 0 ; CF=0 |
pop edi esi ecx |
ret |
.no: |
stc |
ret |
.longname: |
; LFN |
mov al, byte [edi] |
and eax, 0x3F |
dec eax |
1295,86 → 1217,62 |
jae .no ; ignore invalid entries |
mov word [ebp+260*2], 0 ; force null-terminating for orphans |
imul eax, 13*2 |
add ebp, eax |
test byte [edi], 0x40 |
jz @f |
mov word [ebp+13*2], 0 |
@@: |
push eax |
; now copy name from edi to ebp ... |
mov eax, [edi+1] |
mov [ebp], eax ; symbols 1,2 |
mov eax, [edi+5] |
mov [ebp+4], eax ; 3,4 |
mov eax, [edi+9] |
mov [ebp+8], ax ; 5 |
mov eax, [edi+14] |
mov [ebp+10], eax ; 6,7 |
mov eax, [edi+18] |
mov [ebp+14], eax ; 8,9 |
mov eax, [edi+22] |
mov [ebp+18], eax ; 10,11 |
mov eax, [edi+28] |
mov [ebp+22], eax ; 12,13 |
; ... done |
pop eax |
sub ebp, eax |
test eax, eax |
jz @f |
; if this is not first entry, more processing required |
stc |
ret |
@@: |
; if this is first entry: |
test byte [ebp-4], 1 |
jnz .ret |
; buffer at ebp contains UNICODE name, convert it to ANSI |
mov word [ebp+eax+13*2], 0 |
@@: ; copy name (13 chars in UTF-16) |
push esi edi |
mov esi, ebp |
mov edi, ebp |
call uni2ansi_str |
lea esi, [edi+1] |
lea edi, [ebp+eax] |
movsd |
movsd |
movsd |
inc esi |
sub edi, 2 |
movsd |
movsd |
movsd |
add esi, 2 |
movsd |
pop edi esi |
.ret: |
clc |
test eax, eax |
jnz .no ; if this is not first entry, more processing required |
ret |
fat_compare_name: |
; compares ASCIIZ-names, case-insensitive (cp866 encoding) |
; in: esi->name, ebp->name |
; out: if names match: ZF=1 and esi->next component of name |
; else: ZF=0, esi is not changed |
; destroys eax |
; in: esi -> name in UTF-8, ebp -> name in UTF-16 |
; out: |
; ZF=1 -> names match, esi -> next component of name |
; ZF=0 -> esi is not changed |
push ebp esi |
.loop: |
mov al, [ebp] |
inc ebp |
call char_toupper |
push eax |
lodsb |
call char_toupper |
cmp al, [esp] |
@@: |
call utf8to16 |
call utf16toUpper |
mov edx, eax |
mov ax, [ebp] |
call utf16toUpper |
cmp ax, dx |
jnz .done |
pop eax |
test al, al |
jnz .loop |
add ebp, 2 |
test ax, ax |
jnz @b |
dec esi |
pop eax |
pop ebp |
xor eax, eax ; set ZF flag |
pop eax ebp |
xor eax, eax ; set ZF |
ret |
.done: |
cmp al, '/' |
cmp dx, '/' |
jnz @f |
cmp byte [esp], 0 |
test ax, ax |
jnz @f |
mov [esp+4], esi |
mov [esp], esi |
@@: |
pop eax |
pop esi ebp |
ret |
fat_find_lfn: |
; in: esi->name |
; in: esi -> name in UTF-8 |
; [esp+4] = next |
; [esp+8] = first |
; [esp+C]... - possibly parameters for first and next |
1385,26 → 1283,26 |
call dword [eax-4] |
jc .reterr |
sub esp, 262*2 ; reserve place for LFN |
push 0 ; for fat_get_name: read ASCII name |
.l1: |
lea ebp, [esp+4] |
lea ebp, [esp] |
call fat_get_name |
jc .l2 |
call fat_compare_name |
jz .found |
.l2: |
mov ebp, [esp+8+262*2+4] |
lea eax, [esp+0Ch+20h+262*2+4] |
mov ebp, [esp+8+262*2] |
lea eax, [esp+0Ch+20h+262*2] |
call dword [eax-8] |
jnc .l1 |
add esp, 262*2+4 |
add esp, 262*2 |
.reterr: |
mov [esp+28], eax |
stc |
popa |
ret |
.found: |
add esp, 262*2+4 |
add esp, 262*2 |
mov ebp, [esp+8] |
; if this is LFN entry, advance to true entry |
cmp byte [edi+11], 0xF |
1481,9 → 1379,8 |
fat_entry_to_bdfe: |
; convert FAT entry at edi to BDFE (block of data of folder entry) at esi, advance esi |
; destroys eax |
mov eax, [ebp-4] |
mov [esi+4], eax ; ASCII/UNICODE name |
mov [esi+4], eax ; cp866/UNICODE name |
fat_entry_to_bdfe2: |
movzx eax, byte [edi+11] |
mov [esi], eax ; attributes |
1512,6 → 1409,7 |
push ecx edi |
lea edi, [esi+40] |
mov esi, ebp |
mov ecx, 263 |
test byte [esi-4], 1 |
jz .ansi |
mov ecx, 260/2 |
1522,10 → 1420,14 |
pop edi ecx |
.ret: |
ret |
.ansi: |
mov ecx, 264/4 |
rep movsd |
mov [edi-1], al |
lodsw |
call uni2ansi_char |
stosb |
loop .ansi |
xor eax, eax |
stosb |
jmp @b |
bdfe_to_fat_entry: |
1557,7 → 1459,7 |
ret |
hd_find_lfn: |
; in: esi -> path string |
; in: esi -> path string in UTF-8 |
; out: CF=1 - file not found, eax=error code |
; else CF=0 and edi->direntry, eax=sector |
push esi edi |
1825,7 → 1727,7 |
.doit: |
push esi |
sub esp, 262*2 ; reserve space for LFN |
push dword [ebx+8] ; for fat_get_name: read ANSI/UNICODE name |
push dword [ebx+8] ; cp866/UNICODE name |
mov edx, [ebx+16] ; pointer to buffer |
; init header |
push eax |
2386,22 → 2288,19 |
movi eax, 1 ; 1 entry |
jnz .notilde |
; we need ceil(strlen(esi)/13) additional entries = floor((strlen(esi)+12+13)/13) total |
xor eax, eax |
xor ecx, ecx |
push esi |
@@: |
cmp byte [esi], 0 |
jz @f |
inc esi |
inc eax |
jmp @b |
@@: |
sub esi, eax |
add eax, 12+13 |
call utf8to16 |
inc ecx |
test ax, ax |
jnz @b |
pop esi |
mov eax, ecx |
add eax, 12+13-1 |
mov ecx, 13 |
push edx |
cdq |
div ecx |
pop edx |
.notilde: |
push -1 |
push -1 |
2490,26 → 2389,28 |
add al, [esi] |
inc esi |
loop @b |
pop ecx esi |
pop edi |
pop ecx esi edi |
pop dword [esp+8+12+12] |
pop dword [esp+8+12+12] |
; edi points to first entry in free chunk |
dec ecx |
jz .nolfn |
push esi |
push eax |
push esi eax |
lea eax, [esp+8+8+12+8] |
call dword [eax+8] ; begin write |
mov al, 40h |
.writelfn: |
or al, cl |
stosb |
mov esi, [esp+4] |
push ecx |
dec ecx |
jz @f |
imul ecx, 13 |
add esi, ecx |
stosb |
.scroll: |
call utf8to16 |
loop .scroll |
@@: |
mov cl, 5 |
call fat_read_symbols |
mov ax, 0xF |
2527,8 → 2428,7 |
call dword [eax+12] ; next write |
xor eax, eax |
loop .writelfn |
pop eax |
pop esi |
pop eax esi |
.nolfn: |
xchg esi, [esp] |
mov ecx, 11 |
2730,21 → 2630,20 |
mov [edi-32+20], cx |
jmp .writedircont |
fat_read_symbol: |
or ax, -1 |
test esi, esi |
jz .retFFFF |
lodsb |
test al, al |
jnz ansi2uni_char |
xor eax, eax |
xor esi, esi |
.retFFFF: |
@@: |
or eax, -1 |
rep stosw |
ret |
fat_read_symbols: |
call fat_read_symbol |
test esi, esi |
jz @b |
call utf8to16 |
stosw |
test ax, ax |
jnz @f |
xor esi, esi |
@@: |
loop fat_read_symbols |
ret |
/kernel/trunk/fs/fs_lfn.inc |
---|
67,6 → 67,11 |
@@: |
cmp word [ebp], '/' |
jz .rootdir |
cmp byte [ebp], 2 |
jnz @f |
cmp dword[ebp+1], '/' |
jz .rootdir |
@@: |
stdcall kernel_alloc, maxPathLength |
push ebx |
mov ebx, ebp |
75,6 → 80,8 |
push eax |
call get_full_file_name |
pop ebx |
test eax, eax |
jz .notfound |
mov esi, ebp |
mov ax, [ebp] |
or ax, 2020h |
349,16 → 356,14 |
process_replace_file_name: |
; in: [esi] = virtual path |
; out: [esi]+[ebp] = physical path |
pushfd |
cli |
mov ebp, [full_file_name_table] |
xor edi, edi |
xor ebp, ebp |
.loop: |
cmp edi, [full_file_name_table.size] |
jae .notfound |
push esi edi |
shl edi, 7 |
add edi, ebp |
add edi, [full_file_name_table] |
@@: |
cmp byte [edi], 0 |
jz .dest_done |
378,24 → 383,18 |
jz .found |
cmp byte [esi], '/' |
jnz .cont |
inc esi |
.found: |
pop edi eax |
shl edi, 7 |
add edi, ebp |
add edi, [full_file_name_table] |
mov ebp, esi |
cmp byte [esi], 0 |
lea esi, [edi+64] |
jnz .ret |
.notfound: |
xor ebp, ebp |
.ret: |
popfd |
ret |
;----------------------------------------------------------------------------- |
uglobal |
lock_flag_for_f30_3 rb 1 |
addDirSeal db ? |
endg |
sys_current_directory: ; sysfunction 30 |
407,62 → 406,86 |
jz .get |
dec ebx |
jz .mount_additional_directory |
dec ebx |
jz .get16 |
@@: |
ret |
.mount_additional_directory: |
; in: ecx -> dir name+dir path (128) |
cmp [lock_flag_for_f30_3], 1 ; check lock |
je @f |
mov al, 1 |
xchg [addDirSeal], al |
test al, al |
jnz @b |
mov esi, ecx |
mov edi, sysdir_name1 |
mov ecx, 63 |
pushfd |
cli |
cld |
rep movsb ; copying fake directory name |
inc esi |
xor eax, eax |
stosb ; terminator of name, in case if we get the inlet trash |
mov ecx, 63 |
rep movsb ; copying real directory path for mounting |
xor eax, eax |
stosb |
; increase the pointer of inputs for procedure "process_replace_file_name" |
mov cl, 63 |
cmp word [esi], 2 |
jz .utf16 |
call cp866toUTF8_string |
@@: |
mov byte [edi], 0 |
mov [full_file_name_table.size], 2 |
mov [lock_flag_for_f30_3], 1 ; lock |
popfd |
@@: |
ret |
.utf16: |
add esi, 2 |
call UTF16to8_string |
jmp @b |
.get: ; in: ecx -> buffer, edx = length |
mov ebx, edi ; buffer |
push ecx |
push edi |
xor eax, eax |
mov ecx, maxPathLength |
repne scasb |
jnz .error |
sub edi, ebx |
inc edi |
mov [esp+32+8], edi ; return in eax |
cmp edx, edi |
jbe @f |
mov edx, edi |
mov esi, edi |
mov edi, ecx |
cmp edx, maxPathLength |
jc @f |
mov edx, maxPathLength |
@@: |
pop esi |
pop edi |
cmp edx, 1 |
jbe .ret |
mov al, '/' |
stosb |
mov ecx, edx |
rep movsb |
.ret: |
dec ecx |
@@: |
dec ecx |
js @f |
call utf8to16 |
call uni2ansi_char |
stosb |
test al, al |
jnz @b |
sub edx, ecx |
mov ecx, edx |
@@: |
mov [esp+32], ecx |
ret |
.error: |
add esp, 8 |
or dword[esp+32], -1 |
.get16: |
mov esi, edi |
mov edi, ecx |
cmp edx, maxPathLength |
jc @f |
mov edx, maxPathLength |
@@: |
shr edx, 1 |
mov ax, '/' |
stosw |
mov ecx, edx |
dec ecx |
@@: |
dec ecx |
js @f |
call utf8to16 |
stosw |
test ax, ax |
jnz @b |
sub edx, ecx |
mov ecx, edx |
@@: |
mov [esp+32], ecx |
ret |
.set: |
473,50 → 496,62 |
mov ebx, ecx |
get_full_file_name: |
; in: ebx -> file name, [esp+4] -> destination, [esp+8] = max length |
; destroys all registers |
push ebp |
cmp byte [ebx], '/' |
; out: eax=0 -> out of length |
push ebp ebx |
mov esi, ebx |
cmp byte [ebx], 2 |
jnz @f |
inc esi |
@@: |
cmp byte [esi], '/' |
jnz .set_relative |
lea esi, [ebx+1] |
inc esi |
cmp byte [ebx], 2 |
jnz @f |
inc esi |
@@: |
call process_replace_file_name |
mov edi, [esp+8] |
mov edx, [esp+12] |
add edx, edi |
.set_copy: |
mov edi, [esp+12] |
mov ecx, [esp+16] |
test ebp, ebp |
jz .absolute |
@@: |
lodsb |
stosb |
dec ecx |
test al, al |
jz .set_part2 |
.set_copy_cont: |
cmp edi, edx |
jb .set_copy |
.overflow: |
jnz @b |
mov esi, ebp |
dec edi |
.absolute: |
cmp byte [ebx], 2 |
jz @f |
call cp866toUTF8_string |
jns .ret |
jmp .fail |
@@: |
call UTF16to8_string |
jns .ret |
.fail: |
mov byte [edi], 0 |
xor eax, eax |
pop ebp |
pop ebx ebp |
ret 8 |
.set_part2: |
mov esi, ebp |
xor ebp, ebp |
test esi, esi |
jz .ret.ok |
mov byte [edi-1], '/' |
jmp .set_copy_cont |
.set_relative: |
mov edi, [current_slot] |
mov edi, [edi+APPDATA.cur_dir] |
mov edx, edi |
mov ecx, [esp+12] |
mov ecx, [esp+16] |
xor eax, eax |
repnz scasb |
mov esi, edi |
dec esi |
mov edi, [esp+8] |
mov edi, [esp+12] |
jecxz .fail |
cmp byte [ebx], 2 |
jz .relative16 |
.relative: |
cmp byte [ebx], 0 |
jz .set_ok |
523,11 → 558,7 |
cmp word [ebx], '.' |
jz .set_ok |
cmp word [ebx], './' |
jnz @f |
add ebx, 2 |
jmp .relative |
@@: |
jz .next |
cmp word [ebx], '..' |
jnz .doset_relative |
cmp byte [ebx+2], 0 |
534,15 → 565,17 |
jz @f |
cmp byte [ebx+2], '/' |
jnz .doset_relative |
inc ebx |
@@: |
dec esi |
cmp byte [esi], '/' |
jnz @b |
add ebx, 3 |
.next: |
add ebx, 2 |
jmp .relative |
.set_ok: |
cmp edx, edi ; is destination equal to APPDATA.cur_dir? |
cmp edx, edi ; is destination equal to cur_dir? |
jz @f |
mov ecx, esi |
sub ecx, edx |
549,42 → 582,58 |
mov esi, edx |
rep movsb |
mov byte [edi], 0 |
.ret.ok: |
.ret: |
mov al, 1 |
pop ebp |
pop ebx ebp |
ret 8 |
@@: |
mov byte [esi], 0 |
jmp .ret.ok |
jmp .ret |
.doset_relative: |
cmp edx, edi |
jz .doset_relative.cur_dir |
cmp edx, edi ; is destination equal to cur_dir? |
mov edi, esi |
jz @f |
mov edi, [esp+12] |
mov ecx, esi |
sub ecx, edx |
mov esi, edx |
mov edx, edi |
rep movsb |
jmp .doset_relative.copy |
.doset_relative.cur_dir: |
mov edi, esi |
.doset_relative.copy: |
add edx, [esp+12] |
@@: |
mov byte [edi], '/' |
inc edi |
cmp edi, edx |
jae .overflow |
mov esi, ebx |
mov ecx, edx |
add ecx, [esp+16] |
sub ecx, edi |
mov ebx, [esp] |
jmp .absolute |
.relative16: |
cmp word [ebx], 0 |
jz .set_ok |
cmp word [ebx], '.' |
jnz .doset_relative |
cmp word [ebx+2], 0 |
jz .set_ok |
cmp word [ebx+2], '/' |
jz .next16 |
cmp word [ebx+2], '.' |
jnz .doset_relative |
cmp word [ebx+4], 0 |
jz @f |
cmp word [ebx+4], '/' |
jnz .doset_relative |
add ebx, 2 |
@@: |
mov al, [ebx] |
inc ebx |
stosb |
test al, al |
jz .ret.ok |
cmp edi, edx |
jb @b |
jmp .overflow |
dec esi |
cmp byte [esi], '/' |
jnz @b |
.next16: |
add ebx, 4 |
jmp .relative16 |
include "parse_fn.inc" |
include "fs_common.inc" |
/kernel/trunk/fs/iso9660.inc |
---|
9,7 → 9,7 |
; CD external functions |
; in: |
; esi -> path string |
; esi -> path string in UTF-8 |
; ebx -> offset in file (qword) |
; ecx = bytes to read |
; edx -> buffer |
604,9 → 604,8 |
;----------------------------------------------------------------------------- |
cd_find_lfn: |
mov [cd_appl_data], 0 |
; in: esi -> path string |
; out: CF=1 - file not found |
; else CF=0 and [cd_current_pointer_of_input] direntry |
; in: esi -> path string in UTF-8 |
; out: [cd_current_pointer_of_input] -> direntry, CF=1 -> file not found |
push eax esi |
; Sector 16 - start set of volume descriptors |
call WaitUnitReady |
754,45 → 753,25 |
ret |
;----------------------------------------------------------------------------- |
cd_compare_name: |
; compares ASCIIZ-names, case-insensitive (cp866 encoding) |
; in: esi->name, ebp->name |
; 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 |
; in: esi -> UTF-8 name, ebp -> UTF-16BE name |
; out: CF=0 -> names match, esi -> next component of name |
; CF=1 -> esi is not changed |
push edx edi eax esi |
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 |
call utf8to16 |
call utf16toUpper |
mov edx, eax |
mov ax, [edi] |
xchg al, ah |
call utf16toUpper |
cmp ax, dx |
jne .name_not_coincide |
;-------------------------------------- |
.coincides: |
add edi, 2 |
cmp [esi], byte '/' ; path separator is end of current element |
je .done |
cmp [esi], byte 0 ; path separator end of name |
je .done |
jmp .loop |
;-------------------------------------- |
.name_not_coincide: |
pop edi eax esi |
stc |
ret |
;-------------------------------------- |
jne .loop |
.done: |
; check end of file |
cmp [edi], word 3B00h; separator end of file ';' |
808,10 → 787,12 |
add eax, ebp |
cmp edi, eax |
jne .name_not_coincide |
;-------------------------------------- |
.done_1: |
pop edi eax |
add esp, 4 |
pop eax eax edi edx |
inc esi |
clc |
ret |
.name_not_coincide: |
pop esi eax edi edx |
stc |
ret |
/kernel/trunk/fs/ntfs.inc |
---|
11,7 → 11,7 |
; in: |
; ebx -> parameter structure of sysfunc 70 |
; ebp -> NTFS structure |
; esi -> path string |
; esi -> path string in UTF-8 |
; out: |
; eax, ebx = return values for sysfunc 70 |
iglobal |
1161,20 → 1161,8 |
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 -> path string |
; in: esi -> path string in UTF-8 |
; out: |
; [ebp+NTFS.cur_iRecord] = target fileRecord |
; eax -> target index in the node |
1214,39 → 1202,40 |
add eax, rootNode |
cmp [ebp+NTFS.cur_read], eax |
jc .err |
mov edi, [esp+4] |
mov eax, [ebp+NTFS.mftLastRead] |
mov [ebp+NTFS.rootLastRead], eax |
mov eax, [ebp+NTFS.attr_offs] |
mov [ebp+NTFS.indexRoot], eax |
; edi -> name, esi -> current index node |
.scanloop: |
.scanloop: ; esi -> current index node |
add esi, [esi+indexOffset] |
.scanloopint: |
push esi |
test byte [esi+indexFlags], 2 |
jnz .subnode |
push esi |
movzx ecx, byte [esi+fileNameLength] |
add esi, fileName |
push edi |
lea edi, [esi+fileName] |
mov esi, [esp+8] |
@@: |
lodsw |
call unichar_toupper |
call utf8to16 |
cmp ax, '/' |
jz .subnode |
call utf16toUpper |
push eax |
mov al, [edi] |
inc edi |
cmp al, '/' |
jz .slash |
call char_toupper |
call ansi2uni_char |
cmp ax, [esp] |
mov ax, [edi] |
call utf16toUpper |
cmp [esp], ax |
pop eax |
loopz @b |
jc .subnode |
jnz .scanloopcont |
add edi, 2 |
loop @b |
call utf8to16 |
cmp ax, '/' |
jz .found |
pop edi |
test ax, ax |
jz .found |
.scanloopcont: |
pop esi |
jb .subnode |
.scanloopcont: |
movzx eax, word [esi+indexAllocatedSize] |
add esi, eax |
jmp .scanloopint |
1273,7 → 1262,7 |
jmp .doit2 |
.notfound: |
mov [esp+1Ch], esi |
mov [esp+28], esi |
.err: |
popad |
stc |
1282,11 → 1271,8 |
.ret: |
ret |
.slash: |
pop eax |
pop edi |
.subnode: |
pop esi |
.subnode: |
test byte [esi+indexFlags], 1 |
jz .notfound |
mov eax, [ebp+NTFS.LastRead] |
1321,25 → 1307,14 |
jmp .scanloop |
.found: |
cmp byte [edi], 0 |
jz @f |
cmp byte [edi], '/' |
jz @f |
pop edi |
pop esi |
jmp .scanloopcont |
@@: |
pop esi |
pop esi |
mov eax, [esi] |
mov [esp+8], esi |
pop eax |
mov [esp+28], eax |
mov eax, [eax+fileRecordReference] |
mov [ebp+NTFS.cur_iRecord], eax |
mov [esp+1Ch], esi |
mov [esp+4], edi |
popad |
cmp byte [esi], 0 |
cmp byte [esi-1], 0 |
jz .ret2 |
inc esi |
pop eax |
jmp .doit2 |
1859,8 → 1834,7 |
lodsw |
call uni2ansi_char |
stosb |
dec ecx |
jnz @b |
loop @b |
mov byte [edi], 0 |
jmp .end |
1964,25 → 1938,29 |
cmp [ebp+NTFS.fragmentCount], 1 |
jnz ntfsUnsupported ; record fragmented |
; 2. Prepare directory record |
mov ecx, esi |
mov edi, esi |
mov edx, eax |
xor ecx, ecx |
@@: ; count characters |
call utf8to16 |
cmp ax, '/' |
jz ntfsNotFound ; path folder not found |
inc ecx |
cmp byte [ecx], '/' |
jz ntfsNotFound ; path folder not found |
cmp byte [ecx], 0 |
test ax, ax |
jnz @b |
sub ecx, esi |
push ecx ; name length |
dec ecx |
push ecx ; name length in chars |
push edi |
shl ecx, 1 |
add ecx, fileName+7 |
and ecx, not 7 |
mov edi, [ebp+NTFS.cur_index_buf] |
mov edx, [ebx+12] |
mov [ebp+NTFS.fileRealSize], edx |
mov edx, [ebx+16] |
mov [ebp+NTFS.fileDataBuffer], edx |
push esi |
mov eax, [ebx+12] |
mov [ebp+NTFS.fileRealSize], eax |
mov eax, [ebx+16] |
mov [ebp+NTFS.fileDataBuffer], eax |
push ecx ; index length |
mov eax, edx |
mov edx, ecx |
cmp dword [edi], 'INDX' |
jz .indexRecord |
2483,11 → 2461,9 |
mov [edi+fileNameLength], cl |
add edi, fileName |
@@: ; record filename |
lodsb |
call ansi2uni_char |
call utf8to16 |
stosw |
dec ecx |
jnz @b |
loop @b |
mov eax, [ebp+NTFS.LastRead] |
mov [ebp+NTFS.nodeLastRead], eax |
cmp [ebp+NTFS.bFolder], 0 |
2805,8 → 2781,7 |
add esi, 510 |
movsw |
mov [esi-2], ax |
dec ecx |
jnz @b |
loop @b |
mov eax, edx |
xor edx, edx |
pop ecx |
/kernel/trunk/fs/parse_fn.inc |
---|
237,77 → 237,54 |
ret |
endp |
char_todown: |
; convert character in al to downcase, using cp866 encoding |
cmp al, 'A' |
cp866toUpper: |
; convert cp866 character in al to uppercase |
cmp al, 'a' |
jb .ret |
cmp al, 'Z' |
jbe .az |
cmp al, 0x80 ; 'А' |
cmp al, 'z' |
jbe @f |
cmp al, 0xA0 |
jb .ret |
cmp al, 0x90 ; 'Р' |
cmp al, 0xB0 |
jb @f |
cmp al, 0xE0 |
jb .ret |
cmp al, 0xF0 |
jb .rus |
cmp al, 0xF0 ; 'Ё' |
jz .yo |
cmp al, 0x9F ; 'Я' |
cmp al, 0xF7 |
ja .ret |
; 0x90-0x9F -> 0xE0-0xEF |
add al, 0xE0-0x90 |
and eax, -2 |
.ret: |
ret |
.az: |
.rus: ; 0x80-0x8F -> 0xA0-0xAF |
add al, 0x20 |
@@: |
sub eax, 32 |
ret |
.yo: |
inc al |
.rus: |
sub eax, 0xE0-0x90 |
ret |
char_toupper: |
; convert character in al to uppercase, using cp866 encoding |
cmp al, 'a' |
utf16toUpper: |
; convert UTF-16 character in ax to uppercase |
cmp ax, 'a' |
jb .ret |
cmp al, 'z' |
jbe .az |
cmp al, 0xA0 ; 'а' |
cmp ax, 'z' |
jbe @f |
cmp ax, 430h |
jb .ret |
cmp al, 0xE0 ; 'р' |
jb .rus |
cmp al, 0xF1 ; 'ё' |
jz .yo |
cmp al, 0xEF ; 'я' |
ja .ret |
; 0xE0-0xEF -> 0x90-0x9F |
sub al, 0xE0-0x90 |
cmp ax, 450h |
jb @f |
cmp ax, 460h |
jnc .ret |
sub eax, 80 |
.ret: |
ret |
.az: |
.rus: ; 0xA0-0xAF -> 0x80-0x8F |
and al, not 0x20 |
@@: |
sub eax, 32 |
ret |
.yo: |
dec al |
ret |
uni2ansi_str: |
; convert UNICODE zero-terminated string to ASCII-string (codepage 866) |
; in: esi->source, edi->buffer (may be esi=edi) |
; destroys: eax,esi,edi |
lodsw |
call uni2ansi_char |
stosb |
test al, al |
jnz uni2ansi_str |
ret |
uni2ansi_char: |
; convert UNICODE character in ax to ANSI character in al using cp866 encoding |
cmp ax, 0x80 |
355,7 → 332,6 |
.table db 1, 51h, 4, 54h, 7, 57h, 0Eh, 5Eh |
ansi2uni_char: |
; convert ANSI character in al to UNICODE character in ax, using cp866 encoding |
movzx eax, al |
392,25 → 368,85 |
mov al, '_' |
ret |
utf8_to_cp866: |
; in: esi, edi, ecx |
; destroys esi, edi, ecx, eax |
call utf8to16 |
js utf8to16.ret |
call uni2ansi_char |
stosb |
jmp utf8_to_cp866 |
cp866toUTF8_string: |
; in: |
; esi -> cp866 string (could be zero terminated) |
; edi -> buffer for UTF-8 string |
; ecx = buffer size (signed) |
lodsb |
call ansi2uni_char |
push eax |
call UTF16to8 |
pop eax |
js @f |
test eax, eax |
jnz cp866toUTF8_string |
@@: |
ret |
utf8to16: |
; SF=1 -> counter |
; ZF=1 -> zero char |
UTF16to8_string: |
; in: |
; esi -> string |
; ecx = byte counter |
; out: |
; SF=1 -> end |
; ax = UTF-16 char |
; changes esi, ecx |
; esi -> UTF-16 string (could be zero terminated) |
; edi -> buffer for UTF-8 string |
; ecx = buffer size (signed) |
xor eax, eax |
@@: |
lodsw |
push eax |
call UTF16to8 |
pop eax |
js @f |
test eax, eax |
jnz @b |
@@: |
ret |
UTF16to8: |
; in: |
; eax = UTF-16 char |
; edi -> buffer for UTF-8 char (increasing) |
; ecx = byte counter (decreasing) |
dec ecx |
js .ret |
cmp eax, 80h |
jnc @f |
stosb |
test eax, eax ; SF=0 |
.ret: |
ret |
@@: |
dec ecx |
js .ret |
cmp eax, 800h |
jnc @f |
shl eax, 2 |
shr al, 2 |
or eax, 1100000010000000b |
xchg al, ah |
stosw |
ret |
@@: |
dec ecx |
js .ret |
shl eax, 4 |
shr ax, 2 |
shr al, 2 |
or eax, 111000001000000010000000b |
bswap eax |
shr eax, 8 |
stosb |
shr eax, 8 |
stosw |
ret |
utf8to16: |
; in: esi -> UTF-8 char (increasing) |
; out: ax = UTF-16 char |
lodsb |
test al, al |
jns .got |
418,8 → 454,6 |
jnc utf8to16 |
@@: |
shl ax, 8 |
dec ecx |
js .ret |
lodsb |
test al, al |
jns .got |
429,8 → 463,6 |
shl ax, 3 |
jnc @f |
shl eax, 3 |
dec ecx |
js .ret |
lodsb |
test al, al |
jns .got |
445,7 → 477,6 |
.got: |
xor ah, ah |
.ret: |
ret |
strlen: |