diff --git a/kernel/trunk/blkdev/disk.inc b/kernel/trunk/blkdev/disk.inc index 57b8da399d..769dc40a84 100644 --- a/kernel/trunk/blkdev/disk.inc +++ b/kernel/trunk/blkdev/disk.inc @@ -1478,12 +1478,44 @@ dyndisk_handler: mov ecx, [ebx] cmp [edi+4], ecx jbe .unsupported - push edx - push ebp - mov ebp, eax - call dword [edi+8+ecx*4] - pop ebp - pop edx + pushd edx ebp eax [edi+8+ecx*4] + cmp ecx, 10 + jnz .callFS + or ecx, -1 + mov edi, esi + xor eax, eax + repnz scasb + mov edx, edi + dec edi + mov al, '/' + std + repnz scasb + cld + inc edi + mov [edi], ah + mov ebp, [current_slot] + add ebp, APPDATA.cur_dir + pushd ebx esi edx [ebp] ebp edi + sub esi, 2 + mov [ebp], esi + mov edi, edx + mov esi, [ebx+16] + mov eax, [ebx+20] + cmp eax, 4 + jc @f + xor eax, eax +@@: + call getFullPath + pop edi ebp + mov byte [edi], '/' + popd [ebp] edi esi ebx + test eax, eax + jz .errorRename + add edi, 2 +.callFS: + pop eax ebp + call eax + pop ebp edx mov dword [esp+20], ebx .cleanup: mov dword [esp+32], eax @@ -1501,6 +1533,8 @@ dyndisk_handler: movi eax, ERROR_UNSUPPORTED_FS jmp .cleanup +.errorRename: + pop eax eax ebp edx .notfound2: movi eax, ERROR_FILE_NOT_FOUND jmp .cleanup diff --git a/kernel/trunk/docs/sysfuncr.txt b/kernel/trunk/docs/sysfuncr.txt index c590c147b4..5a25b9e3f5 100644 --- a/kernel/trunk/docs/sysfuncr.txt +++ b/kernel/trunk/docs/sysfuncr.txt @@ -4334,6 +4334,26 @@ Architecture Software Developer's Manual, Volume 3, Appendix B); eax - SF_FILE (70) [ebx] - SSF_CREATE_FOLDER (9) ====================================================================== +======= Функция 70, подфункция 10 - переименование/перемещение ======= +====================================================================== +Параметры: + * eax = 70 - номер функции + * ebx = указатель на информационную структуру +Формат информационной структуры: + * +0: dword: 10 = номер подфункции + * +4: dword: 0 (зарезервировано) + * +8: dword: 0 (зарезервировано) + * +12 = +0xC: dword: 0 (зарезервировано) + * +16 = +0x10: dword: указатель на строку с новым именем/путём + * +20 = +0x14: путь, правила формирования имён указаны в общем описании +Возвращаемое значение: + * eax = 0 - успешно, иначе код ошибки файловой системы + * ebx разрушается +Замечания: + * Формирование нового пути отличается от общих правил: + относительный путь относится к папке целевого файла (или папки), + абсолютный путь считается от корня раздела. +====================================================================== ========== Функция 71 - установить заголовок окна программы ========== ====================================================================== Параметры: diff --git a/kernel/trunk/docs/sysfuncs.txt b/kernel/trunk/docs/sysfuncs.txt index 93b2eece25..1e55722f89 100644 --- a/kernel/trunk/docs/sysfuncs.txt +++ b/kernel/trunk/docs/sysfuncs.txt @@ -4290,6 +4290,26 @@ Remarks: eax - SF_FILE (70) [ebx] - SSF_CREATE_FOLDER (9) ====================================================================== +============= Function 70, subfunction 10 - rename/move. ============= +====================================================================== +Parameters: + * eax = 70 - function number + * ebx = pointer to the information structure +Format of the information structure: + * +0: dword: 10 = subfunction number + * +4: dword: 0 (reserved) + * +8: dword: 0 (reserved) + * +12 = +0xC: dword: 0 (reserved) + * +16 = +0x10: dword: pointer to the new name/path string + * +20 = +0x14: path, general rules of names forming +Returned value: + * eax = 0 - success, otherwise file system error code + * ebx destroyed +Remarks: + * New path forming differs from general rules: + relative path relates to the target's parent folder, + absolute path relates to the partition's root folder. +====================================================================== ================== Function 71 - set window caption ================== ====================================================================== Parameters: diff --git a/kernel/trunk/fs/fat.inc b/kernel/trunk/fs/fat.inc index f321469072..ba1b97200e 100644 --- a/kernel/trunk/fs/fat.inc +++ b/kernel/trunk/fs/fat.inc @@ -29,6 +29,7 @@ fat_user_functions: dd 0 dd fat_Delete dd fat_CreateFolder + dd fat_Rename fat_user_functions_end: endg @@ -46,7 +47,8 @@ PUSHAD_EDI equ [esp+0] struct FAT PARTITION fs_type db ? fat_change db ? ; 1=fat has changed - rb 2 +createOption db ? + rb 1 Lock MUTEX ; currently operations with one partition ; can not be executed in parallel since the legacy code is not ready SECTORS_PER_FAT dd ? @@ -1841,16 +1843,16 @@ fat_get_sector: ;---------------------------------------------------------------- fat_CreateFolder: - push 1 + mov [ebp+FAT.createOption], 0 jmp @f fat_CreateFile: - push 0 + mov [ebp+FAT.createOption], 1 @@: call fat_lock - pop eax mov ecx, [ebx+12] mov edx, [ebx+16] +.rename: pushad xor edi, edi push esi @@ -1936,16 +1938,16 @@ fat_CreateFile: add esp, 36 call fat_unlock popad - test al, al - mov eax, ERROR_ACCESS_DENIED + xor eax, eax + cmp [ebp+FAT.createOption], 0 jz @f - mov al, 0 + mov al, ERROR_ACCESS_DENIED @@: xor ebx, ebx ret .exists_file: - cmp byte [esp+36+28], 0 + cmp [ebp+FAT.createOption], 1 jz @f add esp, 36 jmp .noAccess @@ -2091,14 +2093,10 @@ fat_CreateFile: jb .scan_cont ; found! push esi ecx -; If creating a directory, allocate one data cluster now and fail immediately -; if this is impossible. This prevents from creating an invalid directory entry -; on a full disk. -; yup, the argument is quite non-intuitive... but what should I do if -; the entire function uses such arguments? BTW, it refers to al from pushad, -; which in turn is filled with 0 in fat_CreateFile and 1 in fat_CreateFolder. - cmp byte [esp+8+12+8+12+36+28], 0 - jz .no.preallocate.folder.data +; If creating a directory, allocate one data cluster or fail immediately if this is impossible. +; This prevents from creating an invalid directory entry on a full disk. + cmp [ebp+FAT.createOption], 0 + jnz .notFolder call get_free_FAT jnc @f add esp, 8+12+8 @@ -2106,7 +2104,7 @@ fat_CreateFile: @@: mov [esp+8+12+8+12+36+20], eax ; store the cluster somewhere -.no.preallocate.folder.data: ; calculate name checksum +.notFolder: ; calculate name checksum mov esi, [esp+8+12] mov ecx, 11 xor eax, eax @@ -2156,13 +2154,14 @@ fat_CreateFile: loop .writelfn pop eax esi .nolfn: - xchg esi, [esp] + pop esi + add esp, 16 mov ecx, 11 rep movsb + cmp [ebp+FAT.createOption], 2 + jz .copy mov word [edi], 20h ; attributes sub edi, 11 - pop esi ecx - add esp, 12 mov byte [edi+13], 0 ; tenths of a second at file creation time call get_time_for_file mov [edi+14], ax ; creation time @@ -2171,17 +2170,14 @@ fat_CreateFile: mov [edi+16], ax ; creation date mov [edi+24], ax ; last write date mov [edi+18], ax ; last access date - xor ecx, ecx mov word [edi+20], cx ; high word of cluster mov word [edi+26], cx ; low word of cluster - to be filled mov dword [edi+28], ecx ; file size - to be filled - cmp byte [esp+36+28], cl - jz .doit + cmp [ebp+FAT.createOption], 0 + jnz .doit ; create directory mov byte [edi+11], 10h ; attributes: folder mov esi, edi - lea eax, [esp+8] - call dword [eax+16] ; flush directory mov eax, [esp+36+20] ; extract saved cluster mov [esp+36+20], edi ; this is needed for calculating arg of add_disk_free_space! push ecx @@ -2191,6 +2187,13 @@ fat_CreateFile: push edi jmp .doit2 +.copy: + lea esi, [esp+72+11] + mov cl, 21 + rep movsb + sub edi, 32 + jmp .doit + .done1: pop edi call get_time_for_file @@ -2205,10 +2208,10 @@ fat_CreateFile: call dword [eax+16] ; flush directory push ecx mov ecx, [esp+4+36+24] - push ecx - push edi + xor eax, eax test ecx, ecx jz .done + push ecx edi call get_free_FAT jc .diskfull .doit2: @@ -2229,8 +2232,8 @@ fat_CreateFile: add eax, [ebp+FAT.DATA_START] push [ebp+FAT.SECTORS_PER_CLUSTER] .write_sector: - cmp byte [esp+20+36+28], 0 - jnz .writedir + cmp [ebp+FAT.createOption], 0 + jz .writedir mov ecx, 512 cmp dword [esp+12], ecx jb .writeshort @@ -2325,18 +2328,20 @@ fat_CreateFile: .writedone: pop eax eax -.done: xor eax, eax .ret: pop edi ecx + inc ecx +.done: sub esi, [esp+4+36+20] mov [esp+4+36+28], eax mov [esp+4+36+16], esi + jecxz @f lea eax, [esp+12] call dword [eax+8] mov [edi+28], esi call dword [eax+16] - mov [esp+36+16], ebx +@@: lea eax, [esi+511] shr eax, 9 mov ecx, [ebp+FAT.SECTORS_PER_CLUSTER] @@ -2347,8 +2352,11 @@ fat_CreateFile: sub ecx, eax call add_disk_free_space add esp, 36 + cmp [ebp+FAT.createOption], 2 + jz @f call update_disk call fat_unlock +@@: popad ret @@ -3114,3 +3122,38 @@ fat_Delete: call fat_unlock xor eax, eax ret + +;---------------------------------------------------------------- +fat_Rename: +; in: edi -> new path string in UTF-8 + push esi edi + call fat_lock + call hd_find_lfn + pop ebx + jc .error + sub esp, 32 + mov esi, edi + mov edi, esp + mov ecx, 8 + rep movsd + mov [ebp+FAT.createOption], 2 + mov esi, ebx + call fat_CreateFile.rename + add esp, 32 + pop esi + test eax, eax + jnz .ret + push eax + mov [ebp+FAT.longname_sec1], eax + mov [ebp+FAT.longname_sec2], eax + call hd_find_lfn + jc .error + mov byte [edi], 0xE5 + jmp fat_Delete.lfndel + +.error: + push eax + call fat_unlock + pop eax ebx +.ret: + ret