From b3a457d97d8e396b44773f53d91247ac44857246 Mon Sep 17 00:00:00 2001 From: "Evgeny Grechnikov (Diamond)" Date: Thu, 15 Jun 2006 13:13:03 +0000 Subject: [PATCH] File system addition: get/set file/folder attributes git-svn-id: svn://kolibrios.org@86 a494cfbc-eb01-0410-851d-a64ba20cac60 --- kernel/trunk/blkdev/rd.inc | 157 ++++++++++++++++++++++++++------- kernel/trunk/docs/sysfuncr.txt | 75 ++++++++++++++++ kernel/trunk/fs/fat12.inc | 57 +++++++++++- kernel/trunk/fs/fat32.inc | 87 ++++++++++++++++-- kernel/trunk/fs/fs_lfn.inc | 27 ++++-- 5 files changed, 358 insertions(+), 45 deletions(-) diff --git a/kernel/trunk/blkdev/rd.inc b/kernel/trunk/blkdev/rd.inc index 010579a92a..ee17cdffda 100644 --- a/kernel/trunk/blkdev/rd.inc +++ b/kernel/trunk/blkdev/rd.inc @@ -834,13 +834,42 @@ fat_date_to_bdfe: pop edx ecx ret +bdfe_to_fat_time: + push edx + mov edx, eax + shr eax, 16 + and dh, 0x3F + shl eax, 6 + or al, dh + shr dl, 1 + and dl, 0x1F + shl eax, 5 + or al, dl + pop edx + ret + +bdfe_to_fat_date: + push edx + mov edx, eax + shr eax, 16 + sub ax, 1980 + and dh, 0xF + shl eax, 4 + or al, dh + and dl, 0x1F + shl eax, 5 + or al, dl + pop edx + ret + fat_entry_to_bdfe: ; convert FAT entry at edi to BDFE (block of data of folder entry) at esi, advance esi ; destroys eax - movzx eax, byte [edi+11] - mov [esi], eax ; attributes mov eax, [ebp-4] mov [esi+4], eax ; ASCII/UNICODE name +fat_entry_to_bdfe2: + movzx eax, byte [edi+11] + mov [esi], eax ; attributes movzx eax, word [edi+14] call fat_time_to_bdfe mov [esi+8], eax ; creation time @@ -861,6 +890,8 @@ fat_entry_to_bdfe: mov [esi+32], eax ; file size (low dword) xor eax, eax mov [esi+36], eax ; file size (high dword) + test ebp, ebp + jz .ret push ecx edi lea edi, [esi+40] mov esi, ebp @@ -872,6 +903,7 @@ fat_entry_to_bdfe: @@: mov esi, edi pop edi ecx +.ret: ret .ansi: mov ecx, 264/4 @@ -879,41 +911,62 @@ fat_entry_to_bdfe: mov [edi-1], al jmp @b +bdfe_to_fat_entry: +; convert BDFE at edx to FAT entry at edi +; destroys eax +; attributes byte + test byte [edi+11], 8 ; volume label? + jnz @f + mov al, [edx] + and al, 0x27 + and byte [edi+11], 0x10 + or byte [edi+11], al +@@: + mov eax, [edx+8] + call bdfe_to_fat_time + mov [edi+14], ax ; creation time + mov eax, [edx+12] + call bdfe_to_fat_date + mov [edi+16], ax ; creation date + mov eax, [edx+20] + call bdfe_to_fat_date + mov [edi+18], ax ; last access date + mov eax, [edx+24] + call bdfe_to_fat_time + mov [edi+22], ax ; last write time + mov eax, [edx+28] + call bdfe_to_fat_date + mov [edi+24], ax ; last write date + ret + +ramdisk_root_first: + mov edi, 0x100000+512*19 + clc + ret +ramdisk_root_next: + add edi, 0x20 + cmp edi, 0x100000+512*33 + cmc + ret + rd_find_lfn: ; in: esi->name ; out: CF=1 - file not found ; else CF=0 and edi->direntry - push esi ebp edi - sub esp, 262*2 ; allocate space for LFN - mov ebp, esp ; ebp points to buffer - push 0 ; for fat_get_name: read ASCII name - mov edi, 0x100000+512*19 ; to root dir -.l1: - call fat_get_name - jc .l2 - call fat_compare_name - jz .found -.l2: - add edi, 0x20 - cmp edi, 0x100000+512*33 - jb .l1 -.notfound: - add esp, 262*2+4 - pop edi ebp esi - stc - ret -.found: -; found -; if this is LFN entry, advance to true entry - cmp byte [edi+11], 0xF - jnz @f - add edi, 0x20 -@@: -; folders are not supported + push esi edi + push ramdisk_root_first + push ramdisk_root_next + call fat_find_lfn + jc .notfound cmp byte [esi], 0 jnz .notfound - add esp, 262*2+4+4 ; CF=0 - pop ebp esi + add esp, 12 + pop esi + ret ; CF=0 +.notfound: + add esp, 8 + pop edi esi + stc ret ;---------------------------------------------------------------- @@ -1594,4 +1647,46 @@ fs_RamdiskRewrite: loop .read_symbols ret +fs_RamdiskGetFileInfo: + cmp byte [esi], 0 + jnz @f + mov eax, 2 ; unsupported + ret +@@: + push edi + call rd_find_lfn +fs_GetFileInfo_finish: + jnc @f + pop edi + mov eax, ERROR_FILE_NOT_FOUND + ret +@@: + push esi ebp + xor ebp, ebp + mov esi, edx + and dword [esi+4], 0 + call fat_entry_to_bdfe2 + pop ebp esi + pop edi + xor eax, eax + ret + +fs_RamdiskSetFileInfo: + cmp byte [esi], 0 + jnz @f + mov eax, 2 ; unsupported + ret +@@: + push edi + call rd_find_lfn + jnc @f + pop edi + mov eax, ERROR_FILE_NOT_FOUND + ret +@@: + call bdfe_to_fat_entry + pop edi + xor eax, eax + ret + ; \end{diamond} diff --git a/kernel/trunk/docs/sysfuncr.txt b/kernel/trunk/docs/sysfuncr.txt index 30688f75f7..78c372f070 100644 --- a/kernel/trunk/docs/sysfuncr.txt +++ b/kernel/trunk/docs/sysfuncr.txt @@ -3131,6 +3131,7 @@ dword- * ebx = размер файла (в байтах) или 0 для HD, -1 для RD, если файл не найден Замечания: + * Эта функция устарела, используйте подфункцию 5 функции 70. * Функция не поддерживается для дискет. * Текущая реализация позволяет также определять размер папки (по цепочке кластеров в FAT), но не следует на это полагаться. @@ -3167,6 +3168,7 @@ dword- для автоматического создания backup-архивов, ибо при записи бит обычно устанавливается (не в Kolibri, правда) Замечания: + * Эта функция устарела, используйте подфункцию 5 функции 70. * Функция не поддерживается для дискет. ====================================================================== @@ -3198,6 +3200,7 @@ dword- * следующие 4 бита = месяц, 1<=m<=12 * старшие 7 бит = год относительно 1980 Замечания: + * Эта функция устарела, используйте подфункцию 5 функции 70. * Функция не поддерживается для дискет. * Создание файла/папки считается модификацией. @@ -4052,6 +4055,9 @@ Architecture Software Developer's Manual, Volume 3, Appendix B); * +12 = +0xC: dword: размер * +16 = +0x10: dword: указатель на данные * +20 = +0x14: n db: ASCIIZ-строка с именем файла + или + * +20 = +0x14: db 0 + * +21 = +0x15: dd указатель на ASCIIZ-строку с именем файла Уточнения - в документации на соответствующую подфункцию. Имя файла нечувствительно к регистру букв. Русские буквы должны быть записаны в кодировке cp866 (DOS). @@ -4076,6 +4082,8 @@ Architecture Software Developer's Manual, Volume 3, Appendix B); * подфункция 0 - чтение файла * подфункция 1 - чтение папки * подфункция 2 - создание/перезапись файла + * подфункция 5 - получение атрибутов файла/папки + * подфункция 6 - установка атрибутов файла/папки ====================================================================== = Функция 70, подфункция 0 - чтение файла с поддержкой длинных имён. = @@ -4091,6 +4099,9 @@ Architecture Software Developer's Manual, Volume 3, Appendix B); * +16 = +0x10: dword: указатель на буфер, куда будут записаны данные * +20 = +0x14: ASCIIZ-имя файла, правила формирования имён указаны в общем описании + или + * +20 = +0x14: db 0 + * +21 = +0x15: dd указатель на ASCIIZ-строку с именем файла Возвращаемое значение: * eax = 0 - успешно, иначе код ошибки файловой системы * ebx = число прочитанных байт или @@ -4121,6 +4132,9 @@ Architecture Software Developer's Manual, Volume 3, Appendix B); данные, размер буфера должен быть не меньше 32 + [+12]*560 байт * +20 = +0x14: ASCIIZ-имя папки, правила формирования имён указаны в общем описании + или + * +20 = +0x14: db 0 + * +21 = +0x15: dd указатель на ASCIIZ-строку с именем файла Возвращаемое значение: * eax = 0 - успешно, иначе код ошибки файловой системы * ebx = число файлов, информация о которых была записана в буфер, @@ -4213,6 +4227,9 @@ Architecture Software Developer's Manual, Volume 3, Appendix B); * +16 = +0x10: dword: указатель на данные * +20 = +0x14: ASCIIZ-имя файла, правила формирования имён указаны в общем описании + или + * +20 = +0x14: db 0 + * +21 = +0x15: dd указатель на ASCIIZ-строку с именем файла Возвращаемое значение: * eax = 0 - успешно, иначе код ошибки файловой системы * ebx = число записанных байт (возможно, 0) @@ -4222,6 +4239,64 @@ Architecture Software Developer's Manual, Volume 3, Appendix B); * Если свободного места на диске недостаточно, то функция запишет, сколько сможет, после чего вернёт код ошибки 8. +====================================================================== +=== Функция 70, подфункция 5 - получение информации о файле/папке. === +====================================================================== +Параметры: + * eax = 70 - номер функции + * ebx = указатель на информационную структуру +Формат информационной структуры: + * +0: dword: 5 = номер подфункции + * +4: dword: 0 (зарезервировано) + * +8: dword: 0 (зарезервировано) + * +12 = +0xC: dword: 0 (зарезервировано) + * +16 = +0x10: dword: указатель на буфер, куда будут записаны данные + (40 байт) + * +20 = +0x14: ASCIIZ-имя файла, правила формирования имён указаны в + общем описании + или + * +20 = +0x14: db 0 + * +21 = +0x15: dd указатель на ASCIIZ-строку с именем файла +Возвращаемое значение: + * eax = 0 - успешно, иначе код ошибки файловой системы + * ebx разрушается +Информация о файле возвращается в формате БДВК +(блока данных входа каталога), указанном в описании +подфункции 1, но без имени файла +(то есть первые 40 = 0x28 байт). +Замечания: + * Функция не поддерживает виртуальные папки типа /, /rd и + корневые папки типа /rd/1. + +====================================================================== +===== Функция 70, подфункция 6 - установка атрибутов файла/папки. ==== +====================================================================== +Параметры: + * eax = 70 - номер функции + * ebx = указатель на информационную структуру +Формат информационной структуры: + * +0: dword: 6 = номер подфункции + * +4: dword: 0 (зарезервировано) + * +8: dword: 0 (зарезервировано) + * +12 = +0xC: dword: 0 (зарезервировано) + * +16 = +0x10: dword: указатель на буфер с атрибутами (32 байта) + * +20 = +0x14: ASCIIZ-имя файла, правила формирования имён указаны в + общем описании + или + * +20 = +0x14: db 0 + * +21 = +0x15: dd указатель на ASCIIZ-строку с именем файла +Возвращаемое значение: + * eax = 0 - успешно, иначе код ошибки файловой системы + * ebx разрушается +Атрибуты файла - первые 32 байта в БДВК (блоке данных входа каталога), +формат которого указан в описании подфункции 1 +(то есть без имени и размера файла). Атрибут файл/папка/метка тома +(биты 3,4 в dword'е +0) не меняется. +Байт +4 (формат имени) игнорируется. +Замечания: + * Функция не поддерживает виртуальные папки типа /, /rd и + корневые папки типа /rd/1. + ====================================================================== ========== Функция -1 - завершить выполнение потока/процесса ========= ====================================================================== diff --git a/kernel/trunk/fs/fat12.inc b/kernel/trunk/fs/fat12.inc index b04ad77bce..a035bd1bf1 100644 --- a/kernel/trunk/fs/fat12.inc +++ b/kernel/trunk/fs/fat12.inc @@ -1241,7 +1241,7 @@ flp_notroot_extend_dir: fd_find_lfn: ; in: esi->name ; out: CF=1 - file not found -; else CF=0 and edi->direntry +; else CF=0 and edi->direntry, eax=directory cluster (0 for root) push esi edi push 0 push flp_root_first @@ -1264,6 +1264,7 @@ fd_find_lfn: stc ret .found: + mov eax, [esp+8] add esp, 16 ; CF=0 pop esi ret @@ -1905,4 +1906,58 @@ fs_FloppyRewrite: pop edi ecx jmp .ret +fs_FloppyGetFileInfo: + call read_flp_fat + cmp [FDC_Status], 0 + jnz ret11 + cmp byte [esi], 0 + jnz @f + mov eax, 2 ; unsupported + ret +@@: + push edi + call fd_find_lfn + jmp fs_GetFileInfo_finish + +ret11: + mov eax, 11 + ret + +fs_FloppySetFileInfo: + call read_flp_fat + cmp [FDC_Status], 0 + jnz ret11 + cmp byte [esi], 0 + jnz @f + mov eax, 2 ; unsupported + ret +@@: + push edi + call fd_find_lfn + jnc @f + pop edi + mov eax, ERROR_FILE_NOT_FOUND + ret +@@: + push eax + call bdfe_to_fat_entry + pop eax + test eax, eax + jz .root + add eax, 31 + pusha + call save_chs_sector + popa + jmp .cmn +.root: + call save_flp_root +.cmn: + pop edi + xor eax, eax + cmp [FDC_Status], 0 + jz @f + mov al, 11 +@@: + ret + ; \end{diamond} diff --git a/kernel/trunk/fs/fat32.inc b/kernel/trunk/fs/fat32.inc index e99811c3db..d50d22dac0 100644 --- a/kernel/trunk/fs/fat32.inc +++ b/kernel/trunk/fs/fat32.inc @@ -7,6 +7,7 @@ ;; Copyright 2002 Paolo Minazzi, paolo.minazzi@inwind.it ;; ;; ;; ;; See file COPYING for details ;; +;; 15.06.2006 LFN get/set file/folder info - diamond ;; ;; 27.05.2006 LFN create/rewrite file - diamond ;; ;; 04.05.2006 LFN read folder - diamond ;; ;; 29.04.2006 Elimination of hangup after the ;; @@ -2512,28 +2513,28 @@ hd_read: xor eax,eax mov edx,[hdbase] inc edx - out dx,al ; ATAFeatures аегЁбва "обобеннобвей" + out dx,al ; ATAFeatures регистр "особенностей" inc edx inc eax - out dx,al ; ATASectorCount бзевзЁк беквоаов + out dx,al ; ATASectorCount счетчик секторов inc edx mov eax,[esp+4] - out dx,al ; ATASectorNumber аегЁбва номеаа беквоаа + out dx,al ; ATASectorNumber регистр номера сектора shr eax,8 inc edx - out dx,al ; ATACylinder номеа жЁлЁндаа (младиЁй байв) + out dx,al ; ATACylinder номер цилиндра (младший байт) shr eax,8 inc edx - out dx,al ; номеа жЁлЁндаа (бвааиЁй байв) + out dx,al ; номер цилиндра (старший байт) shr eax,8 inc edx and al,1+2+4+8 add al,byte [hdid] add al,128+64+32 - out dx,al ; номеа головкЁ/номеа дЁбка + out dx,al ; номер головки/номер диска inc edx mov al,20h - out dx,al ; ATACommand аегЁбва команд + out dx,al ; ATACommand регистр команд sti call wait_for_sector_buffer @@ -2934,7 +2935,7 @@ read_hd_file: hd_find_lfn: ; in: esi->name ; out: CF=1 - file not found -; else CF=0 and edi->direntry +; else CF=0 and edi->direntry, eax=sector ; destroys eax push esi edi push 0 @@ -2964,6 +2965,15 @@ hd_find_lfn: stc ret .found: + lea eax, [esp+8] + cmp dword [eax], 0 + jz .root + call fat_get_sector + jmp .cmn +.root: + mov eax, [eax+4] + add eax, [ROOT_START] +.cmn: add esp, 20 ; CF=0 pop esi ret @@ -3907,4 +3917,65 @@ fs_HdRewrite: popad ret +fs_HdGetFileInfo: + cmp [fat_type], 0 + jnz @f + mov eax, ERROR_UNKNOWN_FS + ret +@@: + cmp byte [esi], 0 + jnz @f + mov eax, 2 + ret +@@: + push edi + call hd_find_lfn + pushfd + cmp [hd_error], 0 + jz @f + popfd + pop edi + mov eax, 11 + ret +@@: + popfd + jmp fs_GetFileInfo_finish + +fs_HdSetFileInfo: + cmp [fat_type], 0 + jnz @f + mov eax, ERROR_UNKNOWN_FS + ret +@@: + cmp byte [esi], 0 + jnz @f + mov eax, 2 + ret +@@: + push edi + call hd_find_lfn + pushfd + cmp [hd_error], 0 + jz @f + popfd + pop edi + mov eax, 11 + ret +@@: + popfd + jnc @f + pop edi + mov eax, ERROR_FILE_NOT_FOUND + ret +@@: + push eax + call bdfe_to_fat_entry + pop eax + mov ebx, buffer + call hd_write + call update_disk + pop edi + xor eax, eax + ret + ; \end{diamond} diff --git a/kernel/trunk/fs/fs_lfn.inc b/kernel/trunk/fs/fs_lfn.inc index 324d2487cf..53929923c6 100644 --- a/kernel/trunk/fs/fs_lfn.inc +++ b/kernel/trunk/fs/fs_lfn.inc @@ -54,11 +54,12 @@ file_system_lfn: ; 2 : create/rewrite file ; 3 : write/append to file - not implemented yet ; 4 : set end of file - not implemented yet -; 5 : get file attributes structure - not implemented yet -; 6 : start application - not implemented yet -; 7 : delete file - not implemented yet -; 8 : create directory - not implemented yet -; 9 : rename file/directory - not implemented yet +; 5 : get file/directory attributes structure +; 6 : set file/directory attributes structure +; 7 : start application - not implemented yet +; 8 : delete file - not implemented yet +; 9 : create directory - not implemented yet +; 10: rename file/directory - not implemented yet add eax, std_application_base_address ; parse file name @@ -311,10 +312,18 @@ fs_OnRamdisk: mov dword [esp+36], 2 ; not implemented ret +fs_NotImplemented: + mov eax, 2 + ret + fs_RamdiskServices: dd fs_RamdiskRead dd fs_RamdiskReadFolder dd fs_RamdiskRewrite + dd fs_NotImplemented + dd fs_NotImplemented + dd fs_RamdiskGetFileInfo + dd fs_RamdiskSetFileInfo fs_NumRamdiskServices = ($ - fs_RamdiskServices)/4 fs_OnFloppy: @@ -339,6 +348,10 @@ fs_FloppyServices: dd fs_FloppyRead dd fs_FloppyReadFolder dd fs_FloppyRewrite + dd fs_NotImplemented + dd fs_NotImplemented + dd fs_FloppyGetFileInfo + dd fs_FloppySetFileInfo fs_NumFloppyServices = ($ - fs_FloppyServices)/4 fs_OnHd0: @@ -401,6 +414,10 @@ fs_HdServices: dd fs_HdRead dd fs_HdReadFolder dd fs_HdRewrite + dd fs_NotImplemented + dd fs_NotImplemented + dd fs_HdGetFileInfo + dd fs_HdSetFileInfo fs_NumHdServices = ($ - fs_HdServices)/4 fs_HasRamdisk: