diff --git a/kernel/branches/gfx_kernel/blkdev/rd.inc b/kernel/branches/gfx_kernel/blkdev/rd.inc index ea37c5413f..0a9f876440 100644 --- a/kernel/branches/gfx_kernel/blkdev/rd.inc +++ b/kernel/branches/gfx_kernel/blkdev/rd.inc @@ -1874,11 +1874,7 @@ fs_RamdiskWrite: .l1: ; now edi points to direntry, ebx=start byte to write, ; ecx=number of bytes to write, edx=data pointer - call get_time_for_file - mov [edi+22], ax ; last write time - call get_date_for_file - mov [edi+24], ax ; last write date - mov [edi+18], ax ; last access date + call fat_update_datetime ; extend file if needed add ecx, ebx @@ -1948,7 +1944,7 @@ ramdisk_extend_file.zero_size: ; extends file on ramdisk to given size, new data area is filled by 0 ; in: edi->direntry, ecx=new size -; out: CF=0 => OK, eax destroyed +; out: CF=0 => OK, eax=0 ; CF=1 => error, eax=code (ERROR_FAT_TABLE or ERROR_DISK_FULL) ramdisk_extend_file: push ecx @@ -2036,7 +2032,7 @@ ramdisk_extend_file: .extend_done: mov [edi+28], ecx pop esi edx - clc + xor eax, eax ; CF=0 ret .disk_full: pop edi ecx @@ -2046,6 +2042,120 @@ ramdisk_extend_file: pop eax ret +fat_update_datetime: + call get_time_for_file + mov [edi+22], ax ; last write time + call get_date_for_file + mov [edi+24], ax ; last write date + mov [edi+18], ax ; last access date + ret + +;---------------------------------------------------------------- +; +; fs_RamdiskSetFileEnd - set end of file on ramdisk +; +; esi points to filename +; ebx points to 64-bit number = new file size +; ecx ignored (reserved) +; edx ignored (reserved) +; +; ret eax = 0 ok or other = errormsg +; +;-------------------------------------------------------------- +fs_RamdiskSetFileEnd: + cmp byte [esi], 0 + jnz @f +.access_denied: + push ERROR_ACCESS_DENIED + jmp .ret +@@: + push edi + call rd_find_lfn + jnc @f + pop edi + push ERROR_FILE_NOT_FOUND +.ret: + pop eax + ret +@@: +; must not be directory + test byte [edi+11], 10h + jz @f + pop edi + jmp .access_denied +@@: +; file size must not exceed 4Gb + cmp dword [ebx+4], 0 + jz @f + pop edi + push ERROR_END_OF_FILE + jmp .ret +@@: +; set file modification date/time to current + call fat_update_datetime + mov eax, [ebx] + cmp eax, [edi+28] + jb .truncate + ja .expand + pop edi + xor eax, eax + ret +.expand: + push ecx + mov ecx, eax + call ramdisk_extend_file + pop ecx + pop edi + ret +.truncate: + mov [edi+28], eax + push ecx + movzx ecx, word [edi+26] + test eax, eax + jz .zero_size +; find new last sector +@@: + sub eax, 0x200 + jbe @f + movzx ecx, word [0x280000+ecx*2] + jmp @b +@@: +; zero data at the end of last sector + push ecx + mov edi, ecx + shl edi, 9 + lea edi, [edi+0x100000+31*512+eax+0x200] + mov ecx, eax + neg ecx + xor eax, eax + rep stosb + pop ecx +; terminate FAT chain + lea ecx, [0x280000+ecx+ecx] + push dword [ecx] + mov word [ecx], 0xFFF + pop ecx + and ecx, 0xFFF + jmp .delete +.zero_size: + and word [edi+26], 0 +.delete: +; delete FAT chain starting with ecx +; mark all clusters as free + cmp ecx, 0xFF8 + jae .deleted + lea ecx, [0x280000+ecx+ecx] + push dword [ecx] + and word [ecx], 0 + pop ecx + and ecx, 0xFFF + jmp .delete +.deleted: + pop ecx + pop edi + xor eax, eax + ret + fs_RamdiskGetFileInfo: cmp byte [esi], 0 jnz @f diff --git a/kernel/branches/gfx_kernel/core/newproce.inc b/kernel/branches/gfx_kernel/core/newproce.inc index 5f41898809..0aed83203a 100644 --- a/kernel/branches/gfx_kernel/core/newproce.inc +++ b/kernel/branches/gfx_kernel/core/newproce.inc @@ -138,8 +138,7 @@ new_start_application_floppy: jnz .cleanfailed call get_app_params ;parse header fields - test esi, esi - jz .cleanfailed + jc .cleanfailed mov eax,[new_process_place] inc ecx ; -0x1E = no memory @@ -177,6 +176,7 @@ new_start_application_floppy: mov edx,eax ;read file block to current page mov eax,[esp+4] ;restore pointer to file name mov ecx,8 ;number of blocks read + mov ebp,edx ;save buffer address for .endofimage push ebx mov edi,[esp+16] ; cli @@ -184,17 +184,33 @@ new_start_application_floppy: ;ebx=file size ; sti pop ecx + add ecx,8 + test eax,eax + jnz .endloop1 ;check io errors + mov eax,[app_i_end] + add eax,511 + shr eax,9 + cmp ecx,eax + jg .endofimage ;we have loaded whole program + add ebx,511 shr ebx,9 cmp ecx,ebx jg .endloop1 ;if end of file? mov ebx,ecx - test eax,eax - jnz .endloop1 ;check io errors pop edx - add ebx,8 ;go to next page add edx,4 jmp .loop1 +.endofimage: ;set to zero memory at end of page + mov ecx,[app_i_end] + and ecx,4096-1 + jz .endloop1 + lea edi,[ebp+ecx] + neg ecx + add ecx,4096 + xor eax,eax + cld + rep stosb .endloop1: add esp,8+4 ;pop linear address of page table entry and pointer to file name call new_start_application_fl.add_app_parameters @@ -303,8 +319,7 @@ new_start_application_fl: jnz .cleanfailed call get_app_params ;parse header fields - test esi,esi - jz .cleanfailed + jc .cleanfailed mov eax,[new_process_place] inc ecx ; -0x1E = no memory @@ -342,23 +357,40 @@ new_start_application_fl: mov edx,eax ;read file block to current page mov eax,[esp+4] ;restore pointer to file name mov ecx,8 ;number of blocks read + mov ebp,edx ;save buffer address for .endofimage push ebx cli call fileread ;ebx=file size call safe_sti pop ecx + add ecx,8 + test eax,eax + jnz .endloop1 ;check io errors + mov eax,[app_i_end] + add eax,511 + shr eax,9 + cmp ecx,eax + jg .endofimage ;we have loaded whole program + add ebx,511 shr ebx,9 cmp ecx,ebx jg .endloop1 ;if end of file? mov ebx,ecx - test eax,eax - jnz .endloop1 ;check io errors pop edx - add ebx,8 ;go to next page add edx,4 jmp .loop1 +.endofimage: ;set to zero memory at end of page + mov ecx,[app_i_end] + and ecx,4096-1 + jz .endloop1 + lea edi,[ebp+ecx] + neg ecx + add ecx,4096 + xor eax,eax + cld + rep stosb .endloop1: add esp,8 ;pop linear address of page table entry and pointer to file name call .add_app_parameters @@ -1267,8 +1299,7 @@ new_start_application_hd: rep movsd ;copy first block to 0x90000 address for get_app_params function call get_app_params mov ecx, -0x1F ; not Menuet/Kolibri executable - test esi,esi - jz .cleanfailed + jc .cleanfailed mov eax,[new_process_place] inc ecx ; -0x1E = no memory @@ -1502,8 +1533,12 @@ fs_execute: jnz .cleanfailed call get_app_params mov ecx, -0x1F - test esi, esi - jz .cleanfailed + jc .cleanfailed +; sanity check - because we will load all file, +; file size must be not greater than memory size + mov eax, [esp+8+36] + cmp [app_mem], eax + jb .cleanfailed mov eax, [new_process_place] inc ecx ; -0x1E = no memory diff --git a/kernel/branches/gfx_kernel/core/sys32.inc b/kernel/branches/gfx_kernel/core/sys32.inc index 9ceefc08b6..af0c5b85bd 100644 --- a/kernel/branches/gfx_kernel/core/sys32.inc +++ b/kernel/branches/gfx_kernel/core/sys32.inc @@ -614,6 +614,12 @@ get_app_params: mov [app_i_end],eax mov eax,[0x90000+20] mov [app_mem],eax +; \begin{diamond}[20.08.2006] +; sanity check (functions 19,58 load app_i_end bytes and that must +; fit in allocated memory to prevent kernel faults) + cmp eax,[app_i_end] + jb no_01_header +; \end{diamond}[20.08.2006] shr eax,1 sub eax,0x10 mov [app_esp],eax @@ -622,7 +628,7 @@ get_app_params: mov [app_i_icon],dword 0 pop eax - mov esi,1 + clc ret no_00_header: @@ -637,6 +643,10 @@ get_app_params: mov [app_i_end],eax mov eax,[0x90000+20] mov [app_mem],eax +; \begin{diamond}[20.08.2006] + cmp eax,[app_i_end] + jb no_01_header +; \end{diamond}[20.08.2006] mov eax,[0x90000+24] mov [app_esp],eax mov eax,[0x90000+28] @@ -645,13 +655,13 @@ get_app_params: mov [app_i_icon],eax pop eax - mov esi,1 + clc ret no_01_header: pop eax - mov esi,0 + stc ret diff --git a/kernel/branches/gfx_kernel/fs/fat12.inc b/kernel/branches/gfx_kernel/fs/fat12.inc index 1443ba12df..c11a75f9f1 100644 --- a/kernel/branches/gfx_kernel/fs/fat12.inc +++ b/kernel/branches/gfx_kernel/fs/fat12.inc @@ -49,7 +49,7 @@ floppy_free_space: call read_flp_fat cmp [FDC_Status],0 jne fdc_status_error_2 - mov eax,0x282000 + mov eax,0x282004 xor edi,edi mov ecx,2847 ;1448000/512 rdfs1_1: @@ -1828,8 +1828,7 @@ fs_FloppyRewrite: call dword [eax+12] ; flush directory push ecx push edi - add edi, 26 ; edi points to low word of cluster - push edi + push 0 mov esi, edx jecxz .done mov ecx, 2849 @@ -1846,15 +1845,15 @@ fs_FloppyRewrite: lea eax, [edi-0x282000] shr eax, 1 ; eax = cluster mov word [edi], 0xFFF ; mark as last cluster + xchg edi, [esp+4] cmp dword [esp], 0 jz .first - xchg edi, [esp+4] stosw - mov edi, [esp+4] jmp @f .first: mov [esp], eax @@: + mov edi, [esp+4] inc ecx ; write data push ecx edi @@ -2133,7 +2132,7 @@ floppy_extend_file.zero_size: ; extends file on floppy to given size (new data area is undefined) ; in: edi->direntry, ecx=new size -; out: CF=0 => OK, eax destroyed +; out: CF=0 => OK, eax=0 ; CF=1 => error, eax=code (ERROR_FAT_TABLE or ERROR_DISK_FULL) floppy_extend_file: push ecx @@ -2208,7 +2207,7 @@ floppy_extend_file: .extend_done: mov [edi+28], ecx pop esi edx - clc + xor eax, eax ; CF=0 ret .disk_full: pop edi ecx @@ -2218,6 +2217,213 @@ floppy_extend_file: pop eax ret +;---------------------------------------------------------------- +; +; fs_FloppySetFileEnd - set end of file on floppy +; +; esi points to filename +; ebx points to 64-bit number = new file size +; ecx ignored (reserved) +; edx ignored (reserved) +; +; ret eax = 0 ok or other = errormsg +; +;-------------------------------------------------------------- +fs_FloppySetFileEnd: + call read_flp_fat + cmp [FDC_Status], 0 + jnz ret11 + cmp byte [esi], 0 + jnz @f +.access_denied: + push ERROR_ACCESS_DENIED + jmp .ret +@@: + push edi + call fd_find_lfn + jnc @f + pop edi + push ERROR_FILE_NOT_FOUND +.ret: + pop eax + jmp .doret +@@: +; must not be directory + test byte [edi+11], 10h + jz @f + pop edi + jmp .access_denied +@@: +; file size must not exceed 4 Gb + cmp dword [ebx+4], 0 + jz @f + pop edi + push ERROR_END_OF_FILE + jmp .ret +@@: + push eax +; set file modification date/time to current + call fat_update_datetime + mov eax, [ebx] + cmp eax, [edi+28] + jb .truncate + ja .expand + pop eax + pushad + call save_chs_sector + popad + pop edi + xor eax, eax + cmp [FDC_Status], 0 + jz @f + mov al, 11 +@@: +.doret: + mov [fdc_irq_func], fdc_null + ret +.expand: + push ecx + push dword [edi+28] ; save old size + mov ecx, eax + call floppy_extend_file + push eax ; return code + jnc .expand_ok + cmp al, ERROR_DISK_FULL + jz .disk_full + pop eax ecx ecx edi edi + jmp .doret +.device_err: + pop eax +.device_err2: + pop ecx ecx eax edi + push 11 + jmp .ret +.disk_full: +.expand_ok: +; save directory & FAT + mov eax, [edi+28] + xchg eax, [esp+12] + movzx edi, word [edi+26] + pusha + call save_chs_sector + popa + cmp [FDC_Status], 0 + jnz .device_err + call save_flp_fat + cmp [FDC_Status], 0 + jnz .device_err + call SetUserInterrupts +; now zero new data +; edi = current cluster, [esp+12]=new size, [esp+4]=old size, [esp]=return code +.zero_loop: + sub dword [esp+4], 0x200 + jae .next_cluster + cmp dword [esp+4], -0x200 + jz .noread + lea eax, [edi+31] + pusha + call read_chs_sector + popa + cmp [FDC_Status], 0 + jnz .err_next +.noread: + mov ecx, [esp+4] + neg ecx + push edi + mov edi, 0xD000+0x200 + add edi, [esp+8] + xor eax, eax + mov [esp+8], eax + rep stosb + pop edi + lea eax, [edi+31] + pusha + call save_chs_sector + popa + cmp [FDC_Status], 0 + jz .next_cluster +.err_next: + mov byte [esp], 11 +.next_cluster: + sub dword [esp+12], 0x200 + jbe .expand_done + movzx edi, word [0x282000+edi*2] + jmp .zero_loop +.expand_done: + pop eax ecx ecx edi edi + jmp .doret +.truncate: + mov [edi+28], eax + push ecx + movzx ecx, word [edi+26] + test eax, eax + jz .zero_size +; find new last sector +@@: + sub eax, 0x200 + jbe @f + movzx ecx, word [0x282000+ecx*2] + jmp @b +@@: +; we will zero data at the end of last sector - remember it + push ecx +; terminate FAT chain + lea ecx, [0x282000+ecx+ecx] + push dword [ecx] + mov word [ecx], 0xFFF + pop ecx + and ecx, 0xFFF + jmp .delete +.zero_size: + and word [edi+26], 0 + push 0 +.delete: +; delete FAT chain starting with ecx +; mark all clusters as free + cmp ecx, 0xFF8 + jae .deleted + lea ecx, [0x282000+ecx+ecx] + push dword [ecx] + and word [ecx], 0 + pop ecx + and ecx, 0xFFF + jmp .delete +.deleted: + mov edi, [edi+28] +; save directory & FAT + mov eax, [esp+8] + pusha + call save_chs_sector + popa + cmp [FDC_Status], 0 + jnz .device_err2 + call save_flp_fat + cmp [FDC_Status], 0 + jnz .device_err2 +; zero last sector, ignore errors + pop eax + add eax, 31 + and edi, 0x1FF + jz .truncate_done + call SetUserInterrupts + pusha + call read_chs_sector + popa + add edi, 0xD000 + mov ecx, 0xD000+0x200 + sub ecx, edi + push eax + xor eax, eax + rep stosb + pop eax + pusha + call save_chs_sector + popa +.truncate_done: + pop ecx eax edi + xor eax, eax + jmp .doret + fs_FloppyGetFileInfo: call read_flp_fat cmp [FDC_Status], 0 diff --git a/kernel/branches/gfx_kernel/fs/fat32.inc b/kernel/branches/gfx_kernel/fs/fat32.inc index e99911d75f..dcc04ab67d 100644 --- a/kernel/branches/gfx_kernel/fs/fat32.inc +++ b/kernel/branches/gfx_kernel/fs/fat32.inc @@ -90,6 +90,7 @@ uglobal Sector512: ; label for dev_hdcd.inc buffer: times 512 db 0 deltree_buffer: times 512 db 0 + fsinfo_buffer: times 512 db 0 endg iglobal @@ -1037,7 +1038,7 @@ add_disk_free_space: push eax ebx mov eax,[ADR_FSINFO] - mov ebx,buffer + mov ebx,fsinfo_buffer call hd_read cmp [hd_error],0 jne add_not_fs @@ -1047,8 +1048,8 @@ add_disk_free_space: add [ebx+0x1e8],ecx call hd_write - cmp [hd_error],0 - jne add_not_fs +; cmp [hd_error],0 +; jne add_not_fs add_not_fs: pop ebx eax @@ -1057,368 +1058,6 @@ add_disk_free_space: ret -file_append: -;----------------------------------------------------- -; input : eax = file name -; edx = path -; ecx = pointer to buffer -; ebx = bytes to write (0 = truncate file) -; esi = start position (-1 = end of file) -; output : eax = 0 - ok -; 3 - unknown FS -; 5 - file not found -; 6 - end of file -; 8 - disk full -; 9 - fat table corrupted -; 10 - access denied -; ebx = bytes written -;----------------------------------------------------- - cmp [fat_type],0 - jnz append_fat_ok - mov eax,ERROR_UNKNOWN_FS - ret - - append_fat_ok: -; call reserve_hd1 - - pushad - - mov ebx,edx - call get_cluster_of_a_path - jc append_not_found - - mov ebx,PUSHAD_EAX ; file name - call analyze_directory - jc append_not_found - - mov [sector_tmp],eax - mov [entry_pos],ebx - - test byte [ebx+11],0x10 ; is it directory? - jnz append_access ; yes - - mov ecx,[ebx+28] ; file size - mov edi,PUSHAD_ESI ; write position - cmp edi,-1 ; -1 = eof - jnz append_inside_file - mov edi,ecx ; file size - - append_inside_file: - cmp edi,ecx ; start above old file size? - ja append_eof ; yes - - mov [old_filesize],ecx - mov [new_filepos],edi - - mov ecx,PUSHAD_EBX ; bytes to write - test ecx,ecx ; truncate? - jz append_truncate ; yes - - mov [bytes2write],ecx ; bytes to write - mov esi,PUSHAD_ECX ; pointer to buffer - mov eax,[ebx+20-2] ; FAT entry - mov ax,[ebx+26] - and eax,[fatMASK] - jnz append_find_pos ; first cluster <> 0 - - mov eax,2 - call get_free_FAT - jc append_disk_full - mov ecx,eax ; set files first cluster - mov [ebx+26],cx ; 16 bits low of cluster - shr ecx,16 - mov [ebx+20],cx ; 16 bits high of cluster (=0 fat16) - mov edx,[fatEND] ; new end for cluster chain - call set_FAT - cmp [hd_error],0 - jne append_access - - push eax ; save first cluster - mov eax,[sector_tmp] - mov ebx,buffer - call hd_write ; write new file entry back to disk - cmp [hd_error],0 - jne append_access_1 - - pop eax - - append_remove_free: - mov ecx,-1 ; remove 1 cluster from free disk space - call add_disk_free_space ; Note: uses buffer - cmp [hd_error],0 - jne append_access - - append_found_cluster: - mov [cluster],eax - sub eax,2 - mov ecx,[SECTORS_PER_CLUSTER] - imul eax,ecx - add eax,[DATA_START] - xor edi,edi - - append_new_sector: - cmp [hd_error],0 - jne append_access - push ecx - mov ecx,[bytes2write] ; bytes left in buffer - mov ebx,512 - sub ebx,edi ; bytes left in sector - cmp ecx,ebx - jb append_bytes_ok - mov ecx,ebx - - append_bytes_ok: - cmp ecx,512 ; overwrite full sector? - jz append_full_sector ; yes - mov ebx,buffer ; overwrite part of sector - call hd_read ; read old sector - cmp [hd_error],0 - jne append_access_1 - - append_full_sector: - sub [bytes2write],ecx - add [new_filepos],ecx - add edi,buffer - cld - rep movsb - pop ecx - - mov ebx,buffer - call hd_write - cmp [hd_error],0 - jne append_access - - cmp [bytes2write],0 ; is all done? - jz append_done - xor edi,edi - inc eax - dec ecx - jnz append_new_sector - - mov eax,[cluster] - call get_FAT - cmp [hd_error],0 - jne append_access - - cmp eax,2 - jb append_fat - cmp eax,[LAST_CLUSTER] - jbe append_found_cluster - - append_alloc_cluster: - mov eax,2 ; ToDo: use temp array to keep track - call get_free_FAT ; of last free cluster - jc append_disk_full - push eax ; save new cluster - mov edx,[fatEND] ; new end for cluster chain - call set_FAT - cmp [hd_error],0 - jne append_access_1 - - mov edx,eax - mov eax,[cluster] - call set_FAT ; update previous cluster - cmp [hd_error],0 - jne append_access_1 - - pop eax - jmp append_remove_free - - append_find_pos: - call find_filepos - mov [cluster],ebx - jnc append_new_sector - test edi,edi - jz append_alloc_cluster - - append_fat: - mov eax,ERROR_FAT_TABLE - jmp append_ret_code - - append_disk_full: - cmp [hd_error],0 - jne append_access - mov eax,ERROR_DISK_FULL - jmp append_ret_code - - append_done: - xor eax,eax - - append_ret_code: - mov PUSHAD_EAX,eax ; return code - - mov eax,[sector_tmp] ; update directory entry - mov ebx,buffer - call hd_read - cmp [hd_error],0 - jne append_access - - mov ebx,[entry_pos] - mov ecx,[new_filepos] - cmp ecx,[old_filesize] ; is file pos above old size? - jbe append_size_ok ; no - mov [ebx+28],ecx ; new file size - - append_size_ok: - call set_current_time_for_entry - mov ebx,buffer - call hd_write ; write new file entry back to disk - cmp [hd_error],0 - jne append_access - - sub ecx,PUSHAD_ESI ; start position - mov PUSHAD_EBX,ecx ; bytes written - popad - call update_disk ; write all of cache and fat to hd - cmp [hd_error],0 - jne append_access_2 - - mov [hd1_status],0 - ret - - append_eof: - popad - mov [hd1_status],0 - xor ebx,ebx - mov eax,ERROR_END_OF_FILE - ret - - append_not_found: - cmp [hd_error],0 - jne append_access - popad - mov [hd1_status],0 - xor ebx,ebx - mov eax,ERROR_FILE_NOT_FOUND - ret - append_access_1: - add esp,4 - append_access: - popad - append_access_2: - mov [hd1_status],0 - xor ebx,ebx - mov eax,ERROR_ACCESS_DENIED - ret - - append_truncate: - mov edx,[ebx+20-2] ; FAT entry - mov dx,[ebx+26] - and edx,[fatMASK] - mov [ebx+28],edi ; set new file size - test edi,edi ; 0 length file? - jnz truncate_save_size ; no - mov [ebx+20],di ; FAT entry = 0 - mov [ebx+26],di - - truncate_save_size: - call set_current_time_for_entry - mov ebx,buffer - call hd_write - cmp [hd_error],0 - jne append_access - - mov eax,edx ; first cluster - test edi,edi ; 0 length file? - jz truncate_clear_chain - - imul esi,[SECTORS_PER_CLUSTER],512 ; esi = cluster size in bytes - - truncate_new_cluster: - cmp eax,2 ; incorrect fat chain? - jb truncate_eof ; yes - cmp eax,[fatRESERVED] ; is it end of file? - jnb truncate_eof ; yes - sub edi,esi - jbe truncate_pos_found - call get_FAT ; get next cluster - cmp [hd_error],0 - jne append_access - - jmp truncate_new_cluster - - truncate_pos_found: - mov edx,[fatEND] ; new end for cluster chain - call set_FAT - cmp [hd_error],0 - jne append_access - - mov eax,edx ; clear rest of chain - - truncate_clear_chain: - call clear_cluster_chain - cmp [hd_error],0 - jne append_access - - truncate_eof: - popad - call update_disk ; write all of cache and fat to hd - cmp [hd_error],0 - jne append_access_2 - - mov [hd1_status],0 - xor ebx,ebx - xor eax,eax - ret - - -find_filepos: -;----------------------------------------------------- -; input : eax = first cluster -; edi = bytes to skip over (start position) -; output : if CARRY=0 file position found -; if CARRY=1 end of file found -; eax = current file sector -; ebx = last cluster -; ecx = sector count in last cluster -; edi = bytes to skip over (sector position) -;----------------------------------------------------- - push esi - mov ecx,[SECTORS_PER_CLUSTER] - imul esi,ecx,512 ; esi = cluster size in bytes - mov ebx,eax - - filepos_new_cluster: - cmp eax,2 ; incorrect fat chain? - jb filepos_eof ; yes - cmp eax,[fatRESERVED] ; is it end of file? - jnb filepos_eof ; yes - - mov ebx,eax - cmp edi,esi ; skip over full cluster? - jb filepos_cluster_ok ; no - - sub edi,esi - call get_FAT ; get next cluster - cmp [hd_error],0 - jne filepos_eof - - jmp filepos_new_cluster - - filepos_cluster_ok: - sub eax,2 - imul eax,ecx - add eax,[DATA_START] - - filepos_new_sector: - cmp edi,512 ; skip over full sector? - jb filepos_sector_ok ; no - sub edi,512 - inc eax - dec ecx - jnz filepos_new_sector - - filepos_eof: - pop esi - stc - ret - - filepos_sector_ok: - pop esi - clc - ret - - file_write: ;-------------------------------------------------------------------------- ; INPUT : user-reg register-in-this meaning symbol-in-this-routine @@ -3994,7 +3633,7 @@ hd_extend_file.zero_size: ; extends file on hd to given size (new data area is undefined) ; in: edi->direntry, ecx=new size -; out: CF=0 => OK, eax destroyed +; out: CF=0 => OK, eax=0 ; CF=1 => error, eax=code (ERROR_FAT_TABLE or ERROR_DISK_FULL or 11) hd_extend_file: push ebp @@ -4072,6 +3711,10 @@ hd_extend_file: ror edx, 16 mov [edi+26], dx @@: + push ecx + mov ecx, -1 + call add_disk_free_space + pop ecx mov eax, edx cmp [hd_error], 0 jnz .device_err3 @@ -4080,7 +3723,7 @@ hd_extend_file: .extend_done: mov [edi+28], ecx pop edx ebp - clc + xor eax, eax ; CF=0 ret .device_err3: pop edx @@ -4095,6 +3738,246 @@ hd_extend_file: @@: stc ret +;---------------------------------------------------------------- +; +; fs_HdSetFileEnd - set end of file on hard disk +; +; esi points to filename +; ebx points to 64-bit number = new file size +; ecx ignored (reserved) +; edx ignored (reserved) +; +; ret eax = 0 ok or other = errormsg +; +;-------------------------------------------------------------- +fs_HdSetFileEnd: + cmp [fat_type], 0 + jnz @f + push ERROR_UNKNOWN_FS +.ret: + pop eax + ret +@@: + cmp byte [esi], 0 + jnz @f +.access_denied: + push ERROR_ACCESS_DENIED + jmp .ret +@@: + push edi + call hd_find_lfn + pushfd + cmp [hd_error], 0 + jz @f + popfd + push 11 + jmp .ret +@@: + popfd + jnc @f + pop edi + push ERROR_FILE_NOT_FOUND + jmp .ret +@@: +; must not be directory + test byte [edi+11], 10h + jz @f + pop edi + jmp .access_denied +@@: +; file size must not exceed 4 Gb + cmp dword [ebx+4], 0 + jz @f + pop edi + push ERROR_END_OF_FILE + jmp .ret +@@: + push eax ; save directory sector +; set file modification date/time to current + call fat_update_datetime + mov eax, [ebx] + cmp eax, [edi+28] + jb .truncate + ja .expand + pop eax + mov ebx, buffer + call hd_write + pop edi + xor eax, eax + cmp [hd_error], 0 + jz @f + mov al, 11 +@@: + ret +.expand: + push ebx ebp ecx + push dword [edi+28] ; save old size + mov ecx, eax + call hd_extend_file + push eax ; return code + jnc .expand_ok + cmp al, ERROR_DISK_FULL + jz .disk_full +.pop_ret: + call update_disk + pop eax ecx ebp ebx ecx edi edi + ret +.expand_ok: +.disk_full: +; save directory + mov eax, [edi+28] + xchg eax, [esp+20] + mov ebx, buffer + call hd_write + mov eax, [edi+20-2] + mov ax, [edi+26] + mov edi, eax + cmp [hd_error], 0 + jz @f +.pop_ret11: + mov byte [esp], 11 + jmp .pop_ret +@@: +; now zero new data + xor ebp, ebp +; edi=current cluster, ebp=sector in cluster +; [esp+20]=new size, [esp+4]=old size, [esp]=return code +.zero_loop: + sub dword [esp+4], 0x200 + jae .next_cluster + lea eax, [edi-2] + imul eax, [SECTORS_PER_CLUSTER] + add eax, [DATA_START] + add eax, ebp + cmp dword [esp+4], -0x200 + jz .noread + mov ebx, buffer + call hd_read + cmp [hd_error], 0 + jnz .err_next +.noread: + mov ecx, [esp+4] + neg ecx + push edi + mov edi, buffer+0x200 + add edi, [esp+8] + push eax + xor eax, eax + mov [esp+12], eax + rep stosb + pop eax + pop edi + call hd_write + cmp [hd_error], 0 + jz .next_cluster +.err_next: + mov byte [esp], 11 +.next_cluster: + sub dword [esp+20], 0x200 + jbe .pop_ret + inc ebp + cmp ebp, [SECTORS_PER_CLUSTER] + jb .zero_loop + xor ebp, ebp + mov eax, edi + call get_FAT + mov edi, eax + cmp [hd_error], 0 + jnz .pop_ret11 + jmp .zero_loop +.truncate: + mov [edi+28], eax + push ecx + mov ecx, [edi+20-2] + mov cx, [edi+26] + push eax + test eax, eax + jz .zero_size +; find new last cluster +@@: + mov eax, [SECTORS_PER_CLUSTER] + shl eax, 9 + sub [esp], eax + jbe @f + mov eax, ecx + call get_FAT + mov ecx, eax + cmp [hd_error], 0 + jz @b +.device_err3: + pop eax ecx eax edi + push 11 + pop eax + ret +@@: +; we will zero data at the end of last sector - remember it + push ecx +; terminate FAT chain + push edx + mov eax, ecx + mov edx, [fatEND] + call set_FAT + mov eax, edx + pop edx + cmp [hd_error], 0 + jz @f +.device_err4: + pop ecx + jmp .device_err3 +.zero_size: + and word [edi+20], 0 + and word [edi+26], 0 + push 0 + mov eax, ecx +@@: +; delete FAT chain + call clear_cluster_chain + cmp [hd_error], 0 + jnz .device_err4 +; save directory + mov eax, [esp+12] + push ebx + mov ebx, buffer + call hd_write + pop ebx + cmp [hd_error], 0 + jnz .device_err4 +; zero last sector, ignore errors + pop ecx + pop eax + dec ecx + imul ecx, [SECTORS_PER_CLUSTER] + add ecx, [DATA_START] + push eax + sar eax, 9 + add ecx, eax + pop eax + and eax, 0x1FF + jz .truncate_done + push ebx eax + mov eax, ecx + mov ebx, buffer + call hd_read + pop eax + lea edi, [buffer+eax] + push ecx + mov ecx, 0x200 + sub ecx, eax + xor eax, eax + rep stosb + pop eax + call hd_write + pop ebx +.truncate_done: + pop ecx eax edi + call update_disk + xor eax, eax + cmp [hd_error], 0 + jz @f + mov al, 11 +@@: + ret + fs_HdGetFileInfo: cmp [fat_type], 0 jnz @f diff --git a/kernel/branches/gfx_kernel/fs/fs.inc b/kernel/branches/gfx_kernel/fs/fs.inc index dc1eb8689f..b160f34eb2 100644 --- a/kernel/branches/gfx_kernel/fs/fs.inc +++ b/kernel/branches/gfx_kernel/fs/fs.inc @@ -35,10 +35,9 @@ file_system: ; IN: ; -; eax = 0 ; read file /RamDisk/First 6 /HardDisk/First 30 +; eax = 0 ; read file /RamDisk/First 6 ; eax = 1 ; write file /RamDisk/First 33 /HardDisk/First 56 -; eax = 2 ; delete file /RamDisk/First 32 /HardDisk/First 57 -; eax = 3 ; append to a file /RamDisk/First ?? /HardDisk/First ?? +; eax = 2 ; delete file /RamDisk/First 32 ; eax = 4 ; makedir ; eax = 5 ; rename file/directory ; eax = 8 ; lba read @@ -103,10 +102,7 @@ file_system: jz no_checks_for_kernel mov edx,eax cmp dword [eax+0],1 - jz .check_for_write_op - cmp dword [eax+0],3 jnz .usual_check -.check_for_write_op: mov ebx,[eax+12] add ebx,std_application_base_address mov ecx,[eax+8] @@ -139,13 +135,6 @@ endg mov eax,edx no_checks_for_kernel: - - cmp dword [eax+0],3 ; APPEND - allow write 0 bytes (truncate) - je fs_read - cmp dword [eax+8],0 ; read or write 0 blocks/bytes ? - jne fs_read - and dword [esp+36],0 - ret fs_read: mov ebx,[eax+20] ; program wants root directory ? @@ -602,27 +591,6 @@ hd_err_return: fs_noharddisk_delete: - cmp dword [esp+20],3 ; APPEND - jne fs_noharddisk_append - - mov eax,[esp+0] ; /dirname or /filename - mov byte [eax],0 ; path to asciiz - inc eax ; filename start - mov edx,[esp+4] - add edx,12*2 ; path start - mov ecx,[esp+8] ; buffer - mov ebx,[esp+12] ; count to write - mov esi,[esp+16] ; bytes to skip over - - call file_append - - mov edi,[esp+0] - mov byte [edi],'/' - - jmp file_system_return - - fs_noharddisk_append: - cmp dword [esp+20],4 ; MAKEDIR jne fs_noharddisk_makedir diff --git a/kernel/branches/gfx_kernel/fs/fs_lfn.inc b/kernel/branches/gfx_kernel/fs/fs_lfn.inc index 2fe2a47137..8890209800 100644 --- a/kernel/branches/gfx_kernel/fs/fs_lfn.inc +++ b/kernel/branches/gfx_kernel/fs/fs_lfn.inc @@ -77,8 +77,8 @@ file_system_lfn: ; 0 : read file ; 1 : read folder ; 2 : create/rewrite file -; 3 : write/append to file - not implemented yet -; 4 : set end of file - not implemented yet +; 3 : write/append to file +; 4 : set end of file ; 5 : get file/directory attributes structure ; 6 : set file/directory attributes structure ; 7 : start application @@ -348,7 +348,7 @@ fs_RamdiskServices: dd fs_RamdiskReadFolder dd fs_RamdiskRewrite dd fs_RamdiskWrite - dd fs_NotImplemented + dd fs_RamdiskSetFileEnd dd fs_RamdiskGetFileInfo dd fs_RamdiskSetFileInfo dd fs_RamdiskExecute @@ -377,7 +377,7 @@ fs_FloppyServices: dd fs_FloppyReadFolder dd fs_FloppyRewrite dd fs_FloppyWrite - dd fs_NotImplemented + dd fs_FloppySetFileEnd dd fs_FloppyGetFileInfo dd fs_FloppySetFileInfo dd fs_FloppyExecute @@ -448,7 +448,7 @@ fs_HdServices: dd fs_HdReadFolder dd fs_HdRewrite dd fs_HdWrite - dd fs_NotImplemented + dd fs_HdSetFileEnd dd fs_HdGetFileInfo dd fs_HdSetFileInfo dd fs_HdExecute @@ -484,12 +484,12 @@ fs_OnCd: mov [hdpos], eax cmp ecx, 0x100 jae .nf - push cx bx + push ecx ebx mov cl,al mov bl,[0x40001] shr bl,cl test bl,2 - pop bx cx + pop ebx ecx jnz @f .nf: diff --git a/kernel/branches/gfx_kernel/video/vesa20.inc b/kernel/branches/gfx_kernel/video/vesa20.inc index b5c4b58a29..df83a5ffd3 100644 --- a/kernel/branches/gfx_kernel/video/vesa20.inc +++ b/kernel/branches/gfx_kernel/video/vesa20.inc @@ -127,6 +127,10 @@ vesa20_putimage: ; real_sx = MIN(wnd_sx-image_cx, image_sx); mov ebx, [eax-twdw + WDATA.box.width] ; ebx = wnd_sx +; \begin{diamond}[20.08.2006] +; note that WDATA.box.width is one pixel less than real window x-size + inc ebx +; \end{diamond}[20.08.2006] sub ebx, [putimg.image_cx] ja @f add esp, putimg.stack_data @@ -136,13 +140,14 @@ vesa20_putimage: cmp ebx, [putimg.image_sx] jbe .end_x mov ebx, [putimg.image_sx] - dec ebx .end_x: - inc ebx mov [putimg.real_sx], ebx ; init real_sy mov ebx, [eax-twdw + WDATA.box.height] ; ebx = wnd_sy +; \begin{diamond}[20.08.2006] + inc ebx +; \end{diamond}[20.08.2006] sub ebx, [putimg.image_cy] ja @f add esp, putimg.stack_data @@ -152,9 +157,7 @@ vesa20_putimage: cmp ebx, [putimg.image_sy] jbe .end_y mov ebx, [putimg.image_sy] - dec ebx .end_y: - inc ebx mov [putimg.real_sy], ebx ; line increment @@ -611,6 +614,10 @@ vesa20_drawbar: ; real_sx = MIN(wnd_sx-bar_cx, bar_sx); mov ebx, [edi-twdw + WDATA.box.width] ; ebx = wnd_sx +; \begin{diamond}[20.08.2006] +; note that WDATA.box.width is one pixel less than real window x-size + inc ebx +; \end{diamond}[20.08.2006] sub ebx, [drbar.bar_cx] ja @f .exit: ;// mike.dld, 2005-01-29 @@ -629,6 +636,9 @@ vesa20_drawbar: ; real_sy = MIN(wnd_sy-bar_cy, bar_sy); mov ebx, [edi-twdw + WDATA.box.height] ; ebx = wnd_sy +; \begin{diamond}[20.08.2006] + inc ebx +; \end{diamond} sub ebx, [drbar.bar_cy] ja @f add esp, drbar.stack_data diff --git a/kernel/trunk/blkdev/rd.inc b/kernel/trunk/blkdev/rd.inc index ea37c5413f..0a9f876440 100644 --- a/kernel/trunk/blkdev/rd.inc +++ b/kernel/trunk/blkdev/rd.inc @@ -1874,11 +1874,7 @@ fs_RamdiskWrite: .l1: ; now edi points to direntry, ebx=start byte to write, ; ecx=number of bytes to write, edx=data pointer - call get_time_for_file - mov [edi+22], ax ; last write time - call get_date_for_file - mov [edi+24], ax ; last write date - mov [edi+18], ax ; last access date + call fat_update_datetime ; extend file if needed add ecx, ebx @@ -1948,7 +1944,7 @@ ramdisk_extend_file.zero_size: ; extends file on ramdisk to given size, new data area is filled by 0 ; in: edi->direntry, ecx=new size -; out: CF=0 => OK, eax destroyed +; out: CF=0 => OK, eax=0 ; CF=1 => error, eax=code (ERROR_FAT_TABLE or ERROR_DISK_FULL) ramdisk_extend_file: push ecx @@ -2036,7 +2032,7 @@ ramdisk_extend_file: .extend_done: mov [edi+28], ecx pop esi edx - clc + xor eax, eax ; CF=0 ret .disk_full: pop edi ecx @@ -2046,6 +2042,120 @@ ramdisk_extend_file: pop eax ret +fat_update_datetime: + call get_time_for_file + mov [edi+22], ax ; last write time + call get_date_for_file + mov [edi+24], ax ; last write date + mov [edi+18], ax ; last access date + ret + +;---------------------------------------------------------------- +; +; fs_RamdiskSetFileEnd - set end of file on ramdisk +; +; esi points to filename +; ebx points to 64-bit number = new file size +; ecx ignored (reserved) +; edx ignored (reserved) +; +; ret eax = 0 ok or other = errormsg +; +;-------------------------------------------------------------- +fs_RamdiskSetFileEnd: + cmp byte [esi], 0 + jnz @f +.access_denied: + push ERROR_ACCESS_DENIED + jmp .ret +@@: + push edi + call rd_find_lfn + jnc @f + pop edi + push ERROR_FILE_NOT_FOUND +.ret: + pop eax + ret +@@: +; must not be directory + test byte [edi+11], 10h + jz @f + pop edi + jmp .access_denied +@@: +; file size must not exceed 4Gb + cmp dword [ebx+4], 0 + jz @f + pop edi + push ERROR_END_OF_FILE + jmp .ret +@@: +; set file modification date/time to current + call fat_update_datetime + mov eax, [ebx] + cmp eax, [edi+28] + jb .truncate + ja .expand + pop edi + xor eax, eax + ret +.expand: + push ecx + mov ecx, eax + call ramdisk_extend_file + pop ecx + pop edi + ret +.truncate: + mov [edi+28], eax + push ecx + movzx ecx, word [edi+26] + test eax, eax + jz .zero_size +; find new last sector +@@: + sub eax, 0x200 + jbe @f + movzx ecx, word [0x280000+ecx*2] + jmp @b +@@: +; zero data at the end of last sector + push ecx + mov edi, ecx + shl edi, 9 + lea edi, [edi+0x100000+31*512+eax+0x200] + mov ecx, eax + neg ecx + xor eax, eax + rep stosb + pop ecx +; terminate FAT chain + lea ecx, [0x280000+ecx+ecx] + push dword [ecx] + mov word [ecx], 0xFFF + pop ecx + and ecx, 0xFFF + jmp .delete +.zero_size: + and word [edi+26], 0 +.delete: +; delete FAT chain starting with ecx +; mark all clusters as free + cmp ecx, 0xFF8 + jae .deleted + lea ecx, [0x280000+ecx+ecx] + push dword [ecx] + and word [ecx], 0 + pop ecx + and ecx, 0xFFF + jmp .delete +.deleted: + pop ecx + pop edi + xor eax, eax + ret + fs_RamdiskGetFileInfo: cmp byte [esi], 0 jnz @f diff --git a/kernel/trunk/core/newproce.inc b/kernel/trunk/core/newproce.inc index 7eaab77d37..0aed83203a 100644 --- a/kernel/trunk/core/newproce.inc +++ b/kernel/trunk/core/newproce.inc @@ -138,8 +138,7 @@ new_start_application_floppy: jnz .cleanfailed call get_app_params ;parse header fields - test esi, esi - jz .cleanfailed + jc .cleanfailed mov eax,[new_process_place] inc ecx ; -0x1E = no memory @@ -320,8 +319,7 @@ new_start_application_fl: jnz .cleanfailed call get_app_params ;parse header fields - test esi,esi - jz .cleanfailed + jc .cleanfailed mov eax,[new_process_place] inc ecx ; -0x1E = no memory @@ -1301,8 +1299,7 @@ new_start_application_hd: rep movsd ;copy first block to 0x90000 address for get_app_params function call get_app_params mov ecx, -0x1F ; not Menuet/Kolibri executable - test esi,esi - jz .cleanfailed + jc .cleanfailed mov eax,[new_process_place] inc ecx ; -0x1E = no memory @@ -1536,8 +1533,12 @@ fs_execute: jnz .cleanfailed call get_app_params mov ecx, -0x1F - test esi, esi - jz .cleanfailed + jc .cleanfailed +; sanity check - because we will load all file, +; file size must be not greater than memory size + mov eax, [esp+8+36] + cmp [app_mem], eax + jb .cleanfailed mov eax, [new_process_place] inc ecx ; -0x1E = no memory diff --git a/kernel/trunk/core/sys32.inc b/kernel/trunk/core/sys32.inc index caa29f77b4..abc29fde74 100644 --- a/kernel/trunk/core/sys32.inc +++ b/kernel/trunk/core/sys32.inc @@ -614,6 +614,12 @@ get_app_params: mov [app_i_end],eax mov eax,[0x90000+20] mov [app_mem],eax +; \begin{diamond}[20.08.2006] +; sanity check (functions 19,58 load app_i_end bytes and that must +; fit in allocated memory to prevent kernel faults) + cmp eax,[app_i_end] + jb no_01_header +; \end{diamond}[20.08.2006] shr eax,1 sub eax,0x10 mov [app_esp],eax @@ -622,7 +628,7 @@ get_app_params: mov [app_i_icon],dword 0 pop eax - mov esi,1 + clc ret no_00_header: @@ -637,6 +643,10 @@ get_app_params: mov [app_i_end],eax mov eax,[0x90000+20] mov [app_mem],eax +; \begin{diamond}[20.08.2006] + cmp eax,[app_i_end] + jb no_01_header +; \end{diamond}[20.08.2006] mov eax,[0x90000+24] mov [app_esp],eax mov eax,[0x90000+28] @@ -645,13 +655,13 @@ get_app_params: mov [app_i_icon],eax pop eax - mov esi,1 + clc ret no_01_header: pop eax - mov esi,0 + stc ret diff --git a/kernel/trunk/docs/sysfuncr.txt b/kernel/trunk/docs/sysfuncr.txt index 7b716d0f01..65842c7ebc 100644 --- a/kernel/trunk/docs/sysfuncr.txt +++ b/kernel/trunk/docs/sysfuncr.txt @@ -985,6 +985,7 @@ db 'Kolibri',0 значениях невозможно передвижение мыши на 1 пиксель и курсор будет прыгать на величину установленной скорости (подподфункция 1). Устанавливаемая величина не проверяется кодом ядра. + Величину задержки можно менять в приложении SETUP. * Подподфункция 4 не проверяет переданное значение. Перед вызовом необходимо узнать текущее разрешение экрана (подфункцией 14) и проверить, что устанавливаемое положение не выходит за пределы @@ -1850,6 +1851,8 @@ db 'Kolibri',0 * ecx = [координата начала по оси y]*65536 + [координата конца по оси y] * edx = 0x00RRGGBB - цвет + edx = 0x01xxxxxx - рисовать инверсный отрезок + (младшие 24 бита игнорируются) Возвращаемое значение: * функция не возвращает значения Замечания: @@ -2901,7 +2904,6 @@ dword- * подфункция 0 - чтение файла/папки * подфункция 1 - перезапись файла * подфункция 2 - удаление файла/папки - * подфункция 3 - запись данных в существующий файл * подфункция 4 - создание папки * подфункция 5 - переименование/перемещение файла/папки * подфункция 8 - LBA-чтение с устройства @@ -3016,39 +3018,6 @@ dword- (т.е. рекурсивно со всеми файлами и вложенными папками). Рамдиск папок не поддерживает. -====================================================================== -==== Функция 58, подфункция 3 - запись данных в существующий файл. === -====================================================================== -Параметры: - * eax = 58 - номер функции - * ebx = указатель на информационную структуру -Формат информационной структуры: - * +0: dword: 3 = номер подфункции - * +4: dword: начальная позиция в файле; -1 = дописывать в конец - * +8: dword: число байт для записи - * +12 = +0xC: dword: указатель на данные для записи - * +16 = +0x10: dword: указатель на буфер для работы системы - (4096 байт) - * +20 = +0x14: ASCIIZ-имя файла, правила формирования имён указаны в - общем описании -Возвращаемое значение: - * eax = 0 - успешно, иначе код ошибки файловой системы - * ebx разрушается -Замечания: - * Эта функция устарела, используйте подфункцию 3 функции 70. - * Рамдиск и дискеты не поддерживают эту функцию, она только для - жёстких дисков. - * Файл должен уже существовать (иначе возвращается 5, not found). - Для создания файлов используйте подфункцию 1. - * Если начальная позиция больше размера файла, возвращается - eax=6(EOF). Если конечная позиция больше размера файла, - файл расширяется. - * Код обработки записи данных для жёсткого диска интерпретирует - нулевое значение поля +8 как указание усечения файла до размера, - указанного в поле +4. Однако код обработки 58-й функции блокирует - эту возможность для приложений, сразу возвращая управление - (с eax=0) в случае нулевого размера. - ====================================================================== ============== Функция 58, подфункция 4 - создать папку. ============= ====================================================================== @@ -4139,6 +4108,7 @@ Architecture Software Developer's Manual, Volume 3, Appendix B); * подфункция 1 - чтение папки * подфункция 2 - создание/перезапись файла * подфункция 3 - запись в существующий файл + * подфункция 4 - установка размера файла * подфункция 5 - получение атрибутов файла/папки * подфункция 6 - установка атрибутов файла/папки * подфункция 7 - запуск программы @@ -4329,6 +4299,38 @@ Architecture Software Developer's Manual, Volume 3, Appendix B); * Если начальная и/или конечная позиция выходит за пределы файла (за исключением предыдущего случая), файл расширяется до необходимого размера нулевыми символами. + * Функция не поддерживается для CD (вернётся код ошибки 2). + +====================================================================== +========= Функция 70, подфункция 4 - установка размера файла. ======== +====================================================================== +Параметры: + * eax = 70 - номер функции + * ebx = указатель на информационную структуру +Формат информационной структуры: + * +0: dword: 4 = номер подфункции + * +4: dword: младший dword нового размера файла + * +8: dword: старший dword нового размера файла + (должен быть 0 для FAT) + * +12 = +0xC: dword: 0 (зарезервировано) + * +16 = +0x10: dword: 0 (зарезервировано) + * +20 = +0x14: ASCIIZ-имя файла, правила формирования имён указаны в + общем описании + или + * +20 = +0x14: db 0 + * +21 = +0x15: dd указатель на ASCIIZ-строку с именем файла +Возвращаемое значение: + * eax = 0 - успешно, иначе код ошибки файловой системы + * ebx разрушается +Замечания: + * Если новый размер файла меньше старого, файл усекается. Если + новый размер больше старого, файл расширяется нулевыми символами. + Если новый размер равен старому, единственным результатом вызова + является установка даты/времени модификации и доступа в текущие. + * Если свободного места на диске недостаточно для расширения файла, + то функция расширит насколько возможно, после чего вернёт + код ошибки 8. + * Функция не поддерживается для CD (вернётся код ошибки 2). ====================================================================== === Функция 70, подфункция 5 - получение информации о файле/папке. === diff --git a/kernel/trunk/docs/sysfuncs.txt b/kernel/trunk/docs/sysfuncs.txt index 46374b8498..c065e6a1c7 100644 --- a/kernel/trunk/docs/sysfuncs.txt +++ b/kernel/trunk/docs/sysfuncs.txt @@ -10,8 +10,8 @@ All registers except explicitly declared in the returned value, ============== Function 0 - define and draw the window. ============== ====================================================================== Defines an application window. Draws a frame of the window, header and -working area. For skinned windows defines standard buttons for close -and minimize. +working area. For skinned windows defines standard close and minimize +buttons. Parameters: * eax = 0 - function number * ebx = [coordinate on axis x]*65536 + [size on axis x] @@ -111,7 +111,7 @@ Remarks: rectangle with the left upper corner (5,_skinh) and right lower (xsize-5,ysize-5) with color indicated in edx (taking a gradient into account) - * define two standard buttons: for close and minimize + * define two standard buttons: close and minimize (see function 8) * if A=1 and edi contains (nonzero) pointer to caption string, it is drawn in place in header defined in the skin @@ -982,6 +982,7 @@ Remarks: movement of the mouse on 1 pixel is impossible and the cursor will jump on the value of installed speed (subsubfunction 1). The installed value is not inspected by the kernel code. + Mouse delay can be regulated through the application SETUP. * The subsubfunction 4 does not check the passed value. Before its call find out current screen resolution (with function 14) and check that the value of position is inside the limits of the @@ -1824,6 +1825,8 @@ Parameters: * ecx = [start coordinate on axis y]*65536 + [end coordinate on axis y] * edx = 0x00RRGGBB - color + edx = 0x01xxxxxx - draw inversed line + (low 24 bits are ignored) Returned value: * function does not return value Remarks: @@ -2873,7 +2876,6 @@ Existing subfunctions: * subfunction 0 - read file/folder * subfunction 1 - rewrite file * subfunction 2 - delete file/folder - * subfunction 3 - write to existing file * subfunction 4 - make folder * subfunction 5 - rename/move file/folder * subfunction 8 - LBA-read from device @@ -2989,39 +2991,6 @@ Remarks: correctly (i.e. recursively with all files and nested folders). Function 58 does not support folders on ramdisk. -====================================================================== -==== Function 58, subfunction 3 - write data to the existing file. === -====================================================================== -Parameters: - * eax = 58 - function number - * ebx = pointer to the information structure -Format of the information structure: - * +0: dword: 3 = subfunction number - * +4: dword: starting position in the file; -1 = append to the end - * +8: dword: number of bytes to write - * +12 = +0xC: dword: pointer to data to write - * +16 = +0x10: dword: pointer to buffer for system operations - (4096 bytes) - * +20 = +0x14: ASCIIZ-name of file, the rules of names forming are - given in the general description -Returned value: - * eax = 0 - success, otherwise file system error code - * ebx destroyed -Remarks: - * This function is obsolete, use subfunction 3 of function 70. - * Ramdisk and floppies do not support this function, it is only - for hard disks. - * File must already exist (otherwise function returns 5, not found). - To create files use subfunction 1. - * If the starting position is greater than file size, the function - returns eax=6(EOF). If the end position is greater than file size, - file is extended. - * The code of write processing for hard disk interpretes zero - value of the field +8 as the instruction to truncate the file to - the size, given in the field +4. However the code of processing - 58th function blocks this possibility for applications by - immediate return (with eax=0) in the case of zero size. - ====================================================================== ============== Function 58, subfunction 4 - make folder. ============= ====================================================================== @@ -4100,6 +4069,7 @@ Available subfunctions: * subfunction 1 - read folder * subfunction 2 - create/rewrite file * subfunction 3 - write to existing file + * subfunction 4 - set file size * subfunction 5 - get attributes of file/folder * subfunction 6 - set attributes of file/folder * subfunction 7 - start application @@ -4287,6 +4257,38 @@ Remarks: * If beginning and/or ending position is greater than file size (except for the previous case), the file is expanded to needed size with zero characters. + * The function is not supported for CD (returns error code 2). + +====================================================================== +============ Function 70, subfunction 4 - set end of file. =========== +====================================================================== +Parameters: + * eax = 70 - function number + * ebx = pointer to the information structure +Format of the information structure: + * +0: dword: 4 = subfunction number + * +4: dword: low dword of new file size + * +8: dword: high dword of new file size (must be 0 for FAT) + * +12 = +0xC: dword: 0 (reserved) + * +16 = +0x10: dword: 0 (reserved) + * +20 = +0x14: ASCIIZ-name of file, the rules of names forming are + given in the general description + or + * +20 = +0x14: db 0 + * +21 = +0x15: dd pointer to ASCIIZ-string with file name +Returned value: + * eax = 0 - success, otherwise file system error code + * ebx destroyed +Remarks: + * If the new file size is less than old one, file is truncated. + If the new size is greater than old one, file is expanded with + characters with code 0. If the new size is equal to old one, + the only result of call is set date/time of modification and + access to the current date/time. + * If there is not enough free space on disk for expansion, the + function will expand to maximum possible size and then return + error code 8. + * The function is not supported for CD (returns error code 2). ====================================================================== ==== Function 70, subfunction 5 - get information on file/folder. ==== diff --git a/kernel/trunk/fs/fat12.inc b/kernel/trunk/fs/fat12.inc index 1443ba12df..c11a75f9f1 100644 --- a/kernel/trunk/fs/fat12.inc +++ b/kernel/trunk/fs/fat12.inc @@ -49,7 +49,7 @@ floppy_free_space: call read_flp_fat cmp [FDC_Status],0 jne fdc_status_error_2 - mov eax,0x282000 + mov eax,0x282004 xor edi,edi mov ecx,2847 ;1448000/512 rdfs1_1: @@ -1828,8 +1828,7 @@ fs_FloppyRewrite: call dword [eax+12] ; flush directory push ecx push edi - add edi, 26 ; edi points to low word of cluster - push edi + push 0 mov esi, edx jecxz .done mov ecx, 2849 @@ -1846,15 +1845,15 @@ fs_FloppyRewrite: lea eax, [edi-0x282000] shr eax, 1 ; eax = cluster mov word [edi], 0xFFF ; mark as last cluster + xchg edi, [esp+4] cmp dword [esp], 0 jz .first - xchg edi, [esp+4] stosw - mov edi, [esp+4] jmp @f .first: mov [esp], eax @@: + mov edi, [esp+4] inc ecx ; write data push ecx edi @@ -2133,7 +2132,7 @@ floppy_extend_file.zero_size: ; extends file on floppy to given size (new data area is undefined) ; in: edi->direntry, ecx=new size -; out: CF=0 => OK, eax destroyed +; out: CF=0 => OK, eax=0 ; CF=1 => error, eax=code (ERROR_FAT_TABLE or ERROR_DISK_FULL) floppy_extend_file: push ecx @@ -2208,7 +2207,7 @@ floppy_extend_file: .extend_done: mov [edi+28], ecx pop esi edx - clc + xor eax, eax ; CF=0 ret .disk_full: pop edi ecx @@ -2218,6 +2217,213 @@ floppy_extend_file: pop eax ret +;---------------------------------------------------------------- +; +; fs_FloppySetFileEnd - set end of file on floppy +; +; esi points to filename +; ebx points to 64-bit number = new file size +; ecx ignored (reserved) +; edx ignored (reserved) +; +; ret eax = 0 ok or other = errormsg +; +;-------------------------------------------------------------- +fs_FloppySetFileEnd: + call read_flp_fat + cmp [FDC_Status], 0 + jnz ret11 + cmp byte [esi], 0 + jnz @f +.access_denied: + push ERROR_ACCESS_DENIED + jmp .ret +@@: + push edi + call fd_find_lfn + jnc @f + pop edi + push ERROR_FILE_NOT_FOUND +.ret: + pop eax + jmp .doret +@@: +; must not be directory + test byte [edi+11], 10h + jz @f + pop edi + jmp .access_denied +@@: +; file size must not exceed 4 Gb + cmp dword [ebx+4], 0 + jz @f + pop edi + push ERROR_END_OF_FILE + jmp .ret +@@: + push eax +; set file modification date/time to current + call fat_update_datetime + mov eax, [ebx] + cmp eax, [edi+28] + jb .truncate + ja .expand + pop eax + pushad + call save_chs_sector + popad + pop edi + xor eax, eax + cmp [FDC_Status], 0 + jz @f + mov al, 11 +@@: +.doret: + mov [fdc_irq_func], fdc_null + ret +.expand: + push ecx + push dword [edi+28] ; save old size + mov ecx, eax + call floppy_extend_file + push eax ; return code + jnc .expand_ok + cmp al, ERROR_DISK_FULL + jz .disk_full + pop eax ecx ecx edi edi + jmp .doret +.device_err: + pop eax +.device_err2: + pop ecx ecx eax edi + push 11 + jmp .ret +.disk_full: +.expand_ok: +; save directory & FAT + mov eax, [edi+28] + xchg eax, [esp+12] + movzx edi, word [edi+26] + pusha + call save_chs_sector + popa + cmp [FDC_Status], 0 + jnz .device_err + call save_flp_fat + cmp [FDC_Status], 0 + jnz .device_err + call SetUserInterrupts +; now zero new data +; edi = current cluster, [esp+12]=new size, [esp+4]=old size, [esp]=return code +.zero_loop: + sub dword [esp+4], 0x200 + jae .next_cluster + cmp dword [esp+4], -0x200 + jz .noread + lea eax, [edi+31] + pusha + call read_chs_sector + popa + cmp [FDC_Status], 0 + jnz .err_next +.noread: + mov ecx, [esp+4] + neg ecx + push edi + mov edi, 0xD000+0x200 + add edi, [esp+8] + xor eax, eax + mov [esp+8], eax + rep stosb + pop edi + lea eax, [edi+31] + pusha + call save_chs_sector + popa + cmp [FDC_Status], 0 + jz .next_cluster +.err_next: + mov byte [esp], 11 +.next_cluster: + sub dword [esp+12], 0x200 + jbe .expand_done + movzx edi, word [0x282000+edi*2] + jmp .zero_loop +.expand_done: + pop eax ecx ecx edi edi + jmp .doret +.truncate: + mov [edi+28], eax + push ecx + movzx ecx, word [edi+26] + test eax, eax + jz .zero_size +; find new last sector +@@: + sub eax, 0x200 + jbe @f + movzx ecx, word [0x282000+ecx*2] + jmp @b +@@: +; we will zero data at the end of last sector - remember it + push ecx +; terminate FAT chain + lea ecx, [0x282000+ecx+ecx] + push dword [ecx] + mov word [ecx], 0xFFF + pop ecx + and ecx, 0xFFF + jmp .delete +.zero_size: + and word [edi+26], 0 + push 0 +.delete: +; delete FAT chain starting with ecx +; mark all clusters as free + cmp ecx, 0xFF8 + jae .deleted + lea ecx, [0x282000+ecx+ecx] + push dword [ecx] + and word [ecx], 0 + pop ecx + and ecx, 0xFFF + jmp .delete +.deleted: + mov edi, [edi+28] +; save directory & FAT + mov eax, [esp+8] + pusha + call save_chs_sector + popa + cmp [FDC_Status], 0 + jnz .device_err2 + call save_flp_fat + cmp [FDC_Status], 0 + jnz .device_err2 +; zero last sector, ignore errors + pop eax + add eax, 31 + and edi, 0x1FF + jz .truncate_done + call SetUserInterrupts + pusha + call read_chs_sector + popa + add edi, 0xD000 + mov ecx, 0xD000+0x200 + sub ecx, edi + push eax + xor eax, eax + rep stosb + pop eax + pusha + call save_chs_sector + popa +.truncate_done: + pop ecx eax edi + xor eax, eax + jmp .doret + fs_FloppyGetFileInfo: call read_flp_fat cmp [FDC_Status], 0 diff --git a/kernel/trunk/fs/fat32.inc b/kernel/trunk/fs/fat32.inc index e99911d75f..dcc04ab67d 100644 --- a/kernel/trunk/fs/fat32.inc +++ b/kernel/trunk/fs/fat32.inc @@ -90,6 +90,7 @@ uglobal Sector512: ; label for dev_hdcd.inc buffer: times 512 db 0 deltree_buffer: times 512 db 0 + fsinfo_buffer: times 512 db 0 endg iglobal @@ -1037,7 +1038,7 @@ add_disk_free_space: push eax ebx mov eax,[ADR_FSINFO] - mov ebx,buffer + mov ebx,fsinfo_buffer call hd_read cmp [hd_error],0 jne add_not_fs @@ -1047,8 +1048,8 @@ add_disk_free_space: add [ebx+0x1e8],ecx call hd_write - cmp [hd_error],0 - jne add_not_fs +; cmp [hd_error],0 +; jne add_not_fs add_not_fs: pop ebx eax @@ -1057,368 +1058,6 @@ add_disk_free_space: ret -file_append: -;----------------------------------------------------- -; input : eax = file name -; edx = path -; ecx = pointer to buffer -; ebx = bytes to write (0 = truncate file) -; esi = start position (-1 = end of file) -; output : eax = 0 - ok -; 3 - unknown FS -; 5 - file not found -; 6 - end of file -; 8 - disk full -; 9 - fat table corrupted -; 10 - access denied -; ebx = bytes written -;----------------------------------------------------- - cmp [fat_type],0 - jnz append_fat_ok - mov eax,ERROR_UNKNOWN_FS - ret - - append_fat_ok: -; call reserve_hd1 - - pushad - - mov ebx,edx - call get_cluster_of_a_path - jc append_not_found - - mov ebx,PUSHAD_EAX ; file name - call analyze_directory - jc append_not_found - - mov [sector_tmp],eax - mov [entry_pos],ebx - - test byte [ebx+11],0x10 ; is it directory? - jnz append_access ; yes - - mov ecx,[ebx+28] ; file size - mov edi,PUSHAD_ESI ; write position - cmp edi,-1 ; -1 = eof - jnz append_inside_file - mov edi,ecx ; file size - - append_inside_file: - cmp edi,ecx ; start above old file size? - ja append_eof ; yes - - mov [old_filesize],ecx - mov [new_filepos],edi - - mov ecx,PUSHAD_EBX ; bytes to write - test ecx,ecx ; truncate? - jz append_truncate ; yes - - mov [bytes2write],ecx ; bytes to write - mov esi,PUSHAD_ECX ; pointer to buffer - mov eax,[ebx+20-2] ; FAT entry - mov ax,[ebx+26] - and eax,[fatMASK] - jnz append_find_pos ; first cluster <> 0 - - mov eax,2 - call get_free_FAT - jc append_disk_full - mov ecx,eax ; set files first cluster - mov [ebx+26],cx ; 16 bits low of cluster - shr ecx,16 - mov [ebx+20],cx ; 16 bits high of cluster (=0 fat16) - mov edx,[fatEND] ; new end for cluster chain - call set_FAT - cmp [hd_error],0 - jne append_access - - push eax ; save first cluster - mov eax,[sector_tmp] - mov ebx,buffer - call hd_write ; write new file entry back to disk - cmp [hd_error],0 - jne append_access_1 - - pop eax - - append_remove_free: - mov ecx,-1 ; remove 1 cluster from free disk space - call add_disk_free_space ; Note: uses buffer - cmp [hd_error],0 - jne append_access - - append_found_cluster: - mov [cluster],eax - sub eax,2 - mov ecx,[SECTORS_PER_CLUSTER] - imul eax,ecx - add eax,[DATA_START] - xor edi,edi - - append_new_sector: - cmp [hd_error],0 - jne append_access - push ecx - mov ecx,[bytes2write] ; bytes left in buffer - mov ebx,512 - sub ebx,edi ; bytes left in sector - cmp ecx,ebx - jb append_bytes_ok - mov ecx,ebx - - append_bytes_ok: - cmp ecx,512 ; overwrite full sector? - jz append_full_sector ; yes - mov ebx,buffer ; overwrite part of sector - call hd_read ; read old sector - cmp [hd_error],0 - jne append_access_1 - - append_full_sector: - sub [bytes2write],ecx - add [new_filepos],ecx - add edi,buffer - cld - rep movsb - pop ecx - - mov ebx,buffer - call hd_write - cmp [hd_error],0 - jne append_access - - cmp [bytes2write],0 ; is all done? - jz append_done - xor edi,edi - inc eax - dec ecx - jnz append_new_sector - - mov eax,[cluster] - call get_FAT - cmp [hd_error],0 - jne append_access - - cmp eax,2 - jb append_fat - cmp eax,[LAST_CLUSTER] - jbe append_found_cluster - - append_alloc_cluster: - mov eax,2 ; ToDo: use temp array to keep track - call get_free_FAT ; of last free cluster - jc append_disk_full - push eax ; save new cluster - mov edx,[fatEND] ; new end for cluster chain - call set_FAT - cmp [hd_error],0 - jne append_access_1 - - mov edx,eax - mov eax,[cluster] - call set_FAT ; update previous cluster - cmp [hd_error],0 - jne append_access_1 - - pop eax - jmp append_remove_free - - append_find_pos: - call find_filepos - mov [cluster],ebx - jnc append_new_sector - test edi,edi - jz append_alloc_cluster - - append_fat: - mov eax,ERROR_FAT_TABLE - jmp append_ret_code - - append_disk_full: - cmp [hd_error],0 - jne append_access - mov eax,ERROR_DISK_FULL - jmp append_ret_code - - append_done: - xor eax,eax - - append_ret_code: - mov PUSHAD_EAX,eax ; return code - - mov eax,[sector_tmp] ; update directory entry - mov ebx,buffer - call hd_read - cmp [hd_error],0 - jne append_access - - mov ebx,[entry_pos] - mov ecx,[new_filepos] - cmp ecx,[old_filesize] ; is file pos above old size? - jbe append_size_ok ; no - mov [ebx+28],ecx ; new file size - - append_size_ok: - call set_current_time_for_entry - mov ebx,buffer - call hd_write ; write new file entry back to disk - cmp [hd_error],0 - jne append_access - - sub ecx,PUSHAD_ESI ; start position - mov PUSHAD_EBX,ecx ; bytes written - popad - call update_disk ; write all of cache and fat to hd - cmp [hd_error],0 - jne append_access_2 - - mov [hd1_status],0 - ret - - append_eof: - popad - mov [hd1_status],0 - xor ebx,ebx - mov eax,ERROR_END_OF_FILE - ret - - append_not_found: - cmp [hd_error],0 - jne append_access - popad - mov [hd1_status],0 - xor ebx,ebx - mov eax,ERROR_FILE_NOT_FOUND - ret - append_access_1: - add esp,4 - append_access: - popad - append_access_2: - mov [hd1_status],0 - xor ebx,ebx - mov eax,ERROR_ACCESS_DENIED - ret - - append_truncate: - mov edx,[ebx+20-2] ; FAT entry - mov dx,[ebx+26] - and edx,[fatMASK] - mov [ebx+28],edi ; set new file size - test edi,edi ; 0 length file? - jnz truncate_save_size ; no - mov [ebx+20],di ; FAT entry = 0 - mov [ebx+26],di - - truncate_save_size: - call set_current_time_for_entry - mov ebx,buffer - call hd_write - cmp [hd_error],0 - jne append_access - - mov eax,edx ; first cluster - test edi,edi ; 0 length file? - jz truncate_clear_chain - - imul esi,[SECTORS_PER_CLUSTER],512 ; esi = cluster size in bytes - - truncate_new_cluster: - cmp eax,2 ; incorrect fat chain? - jb truncate_eof ; yes - cmp eax,[fatRESERVED] ; is it end of file? - jnb truncate_eof ; yes - sub edi,esi - jbe truncate_pos_found - call get_FAT ; get next cluster - cmp [hd_error],0 - jne append_access - - jmp truncate_new_cluster - - truncate_pos_found: - mov edx,[fatEND] ; new end for cluster chain - call set_FAT - cmp [hd_error],0 - jne append_access - - mov eax,edx ; clear rest of chain - - truncate_clear_chain: - call clear_cluster_chain - cmp [hd_error],0 - jne append_access - - truncate_eof: - popad - call update_disk ; write all of cache and fat to hd - cmp [hd_error],0 - jne append_access_2 - - mov [hd1_status],0 - xor ebx,ebx - xor eax,eax - ret - - -find_filepos: -;----------------------------------------------------- -; input : eax = first cluster -; edi = bytes to skip over (start position) -; output : if CARRY=0 file position found -; if CARRY=1 end of file found -; eax = current file sector -; ebx = last cluster -; ecx = sector count in last cluster -; edi = bytes to skip over (sector position) -;----------------------------------------------------- - push esi - mov ecx,[SECTORS_PER_CLUSTER] - imul esi,ecx,512 ; esi = cluster size in bytes - mov ebx,eax - - filepos_new_cluster: - cmp eax,2 ; incorrect fat chain? - jb filepos_eof ; yes - cmp eax,[fatRESERVED] ; is it end of file? - jnb filepos_eof ; yes - - mov ebx,eax - cmp edi,esi ; skip over full cluster? - jb filepos_cluster_ok ; no - - sub edi,esi - call get_FAT ; get next cluster - cmp [hd_error],0 - jne filepos_eof - - jmp filepos_new_cluster - - filepos_cluster_ok: - sub eax,2 - imul eax,ecx - add eax,[DATA_START] - - filepos_new_sector: - cmp edi,512 ; skip over full sector? - jb filepos_sector_ok ; no - sub edi,512 - inc eax - dec ecx - jnz filepos_new_sector - - filepos_eof: - pop esi - stc - ret - - filepos_sector_ok: - pop esi - clc - ret - - file_write: ;-------------------------------------------------------------------------- ; INPUT : user-reg register-in-this meaning symbol-in-this-routine @@ -3994,7 +3633,7 @@ hd_extend_file.zero_size: ; extends file on hd to given size (new data area is undefined) ; in: edi->direntry, ecx=new size -; out: CF=0 => OK, eax destroyed +; out: CF=0 => OK, eax=0 ; CF=1 => error, eax=code (ERROR_FAT_TABLE or ERROR_DISK_FULL or 11) hd_extend_file: push ebp @@ -4072,6 +3711,10 @@ hd_extend_file: ror edx, 16 mov [edi+26], dx @@: + push ecx + mov ecx, -1 + call add_disk_free_space + pop ecx mov eax, edx cmp [hd_error], 0 jnz .device_err3 @@ -4080,7 +3723,7 @@ hd_extend_file: .extend_done: mov [edi+28], ecx pop edx ebp - clc + xor eax, eax ; CF=0 ret .device_err3: pop edx @@ -4095,6 +3738,246 @@ hd_extend_file: @@: stc ret +;---------------------------------------------------------------- +; +; fs_HdSetFileEnd - set end of file on hard disk +; +; esi points to filename +; ebx points to 64-bit number = new file size +; ecx ignored (reserved) +; edx ignored (reserved) +; +; ret eax = 0 ok or other = errormsg +; +;-------------------------------------------------------------- +fs_HdSetFileEnd: + cmp [fat_type], 0 + jnz @f + push ERROR_UNKNOWN_FS +.ret: + pop eax + ret +@@: + cmp byte [esi], 0 + jnz @f +.access_denied: + push ERROR_ACCESS_DENIED + jmp .ret +@@: + push edi + call hd_find_lfn + pushfd + cmp [hd_error], 0 + jz @f + popfd + push 11 + jmp .ret +@@: + popfd + jnc @f + pop edi + push ERROR_FILE_NOT_FOUND + jmp .ret +@@: +; must not be directory + test byte [edi+11], 10h + jz @f + pop edi + jmp .access_denied +@@: +; file size must not exceed 4 Gb + cmp dword [ebx+4], 0 + jz @f + pop edi + push ERROR_END_OF_FILE + jmp .ret +@@: + push eax ; save directory sector +; set file modification date/time to current + call fat_update_datetime + mov eax, [ebx] + cmp eax, [edi+28] + jb .truncate + ja .expand + pop eax + mov ebx, buffer + call hd_write + pop edi + xor eax, eax + cmp [hd_error], 0 + jz @f + mov al, 11 +@@: + ret +.expand: + push ebx ebp ecx + push dword [edi+28] ; save old size + mov ecx, eax + call hd_extend_file + push eax ; return code + jnc .expand_ok + cmp al, ERROR_DISK_FULL + jz .disk_full +.pop_ret: + call update_disk + pop eax ecx ebp ebx ecx edi edi + ret +.expand_ok: +.disk_full: +; save directory + mov eax, [edi+28] + xchg eax, [esp+20] + mov ebx, buffer + call hd_write + mov eax, [edi+20-2] + mov ax, [edi+26] + mov edi, eax + cmp [hd_error], 0 + jz @f +.pop_ret11: + mov byte [esp], 11 + jmp .pop_ret +@@: +; now zero new data + xor ebp, ebp +; edi=current cluster, ebp=sector in cluster +; [esp+20]=new size, [esp+4]=old size, [esp]=return code +.zero_loop: + sub dword [esp+4], 0x200 + jae .next_cluster + lea eax, [edi-2] + imul eax, [SECTORS_PER_CLUSTER] + add eax, [DATA_START] + add eax, ebp + cmp dword [esp+4], -0x200 + jz .noread + mov ebx, buffer + call hd_read + cmp [hd_error], 0 + jnz .err_next +.noread: + mov ecx, [esp+4] + neg ecx + push edi + mov edi, buffer+0x200 + add edi, [esp+8] + push eax + xor eax, eax + mov [esp+12], eax + rep stosb + pop eax + pop edi + call hd_write + cmp [hd_error], 0 + jz .next_cluster +.err_next: + mov byte [esp], 11 +.next_cluster: + sub dword [esp+20], 0x200 + jbe .pop_ret + inc ebp + cmp ebp, [SECTORS_PER_CLUSTER] + jb .zero_loop + xor ebp, ebp + mov eax, edi + call get_FAT + mov edi, eax + cmp [hd_error], 0 + jnz .pop_ret11 + jmp .zero_loop +.truncate: + mov [edi+28], eax + push ecx + mov ecx, [edi+20-2] + mov cx, [edi+26] + push eax + test eax, eax + jz .zero_size +; find new last cluster +@@: + mov eax, [SECTORS_PER_CLUSTER] + shl eax, 9 + sub [esp], eax + jbe @f + mov eax, ecx + call get_FAT + mov ecx, eax + cmp [hd_error], 0 + jz @b +.device_err3: + pop eax ecx eax edi + push 11 + pop eax + ret +@@: +; we will zero data at the end of last sector - remember it + push ecx +; terminate FAT chain + push edx + mov eax, ecx + mov edx, [fatEND] + call set_FAT + mov eax, edx + pop edx + cmp [hd_error], 0 + jz @f +.device_err4: + pop ecx + jmp .device_err3 +.zero_size: + and word [edi+20], 0 + and word [edi+26], 0 + push 0 + mov eax, ecx +@@: +; delete FAT chain + call clear_cluster_chain + cmp [hd_error], 0 + jnz .device_err4 +; save directory + mov eax, [esp+12] + push ebx + mov ebx, buffer + call hd_write + pop ebx + cmp [hd_error], 0 + jnz .device_err4 +; zero last sector, ignore errors + pop ecx + pop eax + dec ecx + imul ecx, [SECTORS_PER_CLUSTER] + add ecx, [DATA_START] + push eax + sar eax, 9 + add ecx, eax + pop eax + and eax, 0x1FF + jz .truncate_done + push ebx eax + mov eax, ecx + mov ebx, buffer + call hd_read + pop eax + lea edi, [buffer+eax] + push ecx + mov ecx, 0x200 + sub ecx, eax + xor eax, eax + rep stosb + pop eax + call hd_write + pop ebx +.truncate_done: + pop ecx eax edi + call update_disk + xor eax, eax + cmp [hd_error], 0 + jz @f + mov al, 11 +@@: + ret + fs_HdGetFileInfo: cmp [fat_type], 0 jnz @f diff --git a/kernel/trunk/fs/fs.inc b/kernel/trunk/fs/fs.inc index dc1eb8689f..b160f34eb2 100644 --- a/kernel/trunk/fs/fs.inc +++ b/kernel/trunk/fs/fs.inc @@ -35,10 +35,9 @@ file_system: ; IN: ; -; eax = 0 ; read file /RamDisk/First 6 /HardDisk/First 30 +; eax = 0 ; read file /RamDisk/First 6 ; eax = 1 ; write file /RamDisk/First 33 /HardDisk/First 56 -; eax = 2 ; delete file /RamDisk/First 32 /HardDisk/First 57 -; eax = 3 ; append to a file /RamDisk/First ?? /HardDisk/First ?? +; eax = 2 ; delete file /RamDisk/First 32 ; eax = 4 ; makedir ; eax = 5 ; rename file/directory ; eax = 8 ; lba read @@ -103,10 +102,7 @@ file_system: jz no_checks_for_kernel mov edx,eax cmp dword [eax+0],1 - jz .check_for_write_op - cmp dword [eax+0],3 jnz .usual_check -.check_for_write_op: mov ebx,[eax+12] add ebx,std_application_base_address mov ecx,[eax+8] @@ -139,13 +135,6 @@ endg mov eax,edx no_checks_for_kernel: - - cmp dword [eax+0],3 ; APPEND - allow write 0 bytes (truncate) - je fs_read - cmp dword [eax+8],0 ; read or write 0 blocks/bytes ? - jne fs_read - and dword [esp+36],0 - ret fs_read: mov ebx,[eax+20] ; program wants root directory ? @@ -602,27 +591,6 @@ hd_err_return: fs_noharddisk_delete: - cmp dword [esp+20],3 ; APPEND - jne fs_noharddisk_append - - mov eax,[esp+0] ; /dirname or /filename - mov byte [eax],0 ; path to asciiz - inc eax ; filename start - mov edx,[esp+4] - add edx,12*2 ; path start - mov ecx,[esp+8] ; buffer - mov ebx,[esp+12] ; count to write - mov esi,[esp+16] ; bytes to skip over - - call file_append - - mov edi,[esp+0] - mov byte [edi],'/' - - jmp file_system_return - - fs_noharddisk_append: - cmp dword [esp+20],4 ; MAKEDIR jne fs_noharddisk_makedir diff --git a/kernel/trunk/fs/fs_lfn.inc b/kernel/trunk/fs/fs_lfn.inc index 2fe2a47137..8890209800 100644 --- a/kernel/trunk/fs/fs_lfn.inc +++ b/kernel/trunk/fs/fs_lfn.inc @@ -77,8 +77,8 @@ file_system_lfn: ; 0 : read file ; 1 : read folder ; 2 : create/rewrite file -; 3 : write/append to file - not implemented yet -; 4 : set end of file - not implemented yet +; 3 : write/append to file +; 4 : set end of file ; 5 : get file/directory attributes structure ; 6 : set file/directory attributes structure ; 7 : start application @@ -348,7 +348,7 @@ fs_RamdiskServices: dd fs_RamdiskReadFolder dd fs_RamdiskRewrite dd fs_RamdiskWrite - dd fs_NotImplemented + dd fs_RamdiskSetFileEnd dd fs_RamdiskGetFileInfo dd fs_RamdiskSetFileInfo dd fs_RamdiskExecute @@ -377,7 +377,7 @@ fs_FloppyServices: dd fs_FloppyReadFolder dd fs_FloppyRewrite dd fs_FloppyWrite - dd fs_NotImplemented + dd fs_FloppySetFileEnd dd fs_FloppyGetFileInfo dd fs_FloppySetFileInfo dd fs_FloppyExecute @@ -448,7 +448,7 @@ fs_HdServices: dd fs_HdReadFolder dd fs_HdRewrite dd fs_HdWrite - dd fs_NotImplemented + dd fs_HdSetFileEnd dd fs_HdGetFileInfo dd fs_HdSetFileInfo dd fs_HdExecute @@ -484,12 +484,12 @@ fs_OnCd: mov [hdpos], eax cmp ecx, 0x100 jae .nf - push cx bx + push ecx ebx mov cl,al mov bl,[0x40001] shr bl,cl test bl,2 - pop bx cx + pop ebx ecx jnz @f .nf: diff --git a/kernel/trunk/video/vesa20.inc b/kernel/trunk/video/vesa20.inc index 87734024d3..c962808d34 100644 --- a/kernel/trunk/video/vesa20.inc +++ b/kernel/trunk/video/vesa20.inc @@ -127,6 +127,10 @@ vesa20_putimage: ; real_sx = MIN(wnd_sx-image_cx, image_sx); mov ebx, [eax-twdw + WDATA.box.width] ; ebx = wnd_sx +; \begin{diamond}[20.08.2006] +; note that WDATA.box.width is one pixel less than real window x-size + inc ebx +; \end{diamond}[20.08.2006] sub ebx, [putimg.image_cx] ja @f add esp, putimg.stack_data @@ -136,13 +140,14 @@ vesa20_putimage: cmp ebx, [putimg.image_sx] jbe .end_x mov ebx, [putimg.image_sx] - dec ebx .end_x: - inc ebx mov [putimg.real_sx], ebx ; init real_sy mov ebx, [eax-twdw + WDATA.box.height] ; ebx = wnd_sy +; \begin{diamond}[20.08.2006] + inc ebx +; \end{diamond}[20.08.2006] sub ebx, [putimg.image_cy] ja @f add esp, putimg.stack_data @@ -152,9 +157,7 @@ vesa20_putimage: cmp ebx, [putimg.image_sy] jbe .end_y mov ebx, [putimg.image_sy] - dec ebx .end_y: - inc ebx mov [putimg.real_sy], ebx ; line increment @@ -611,6 +614,10 @@ vesa20_drawbar: ; real_sx = MIN(wnd_sx-bar_cx, bar_sx); mov ebx, [edi-twdw + WDATA.box.width] ; ebx = wnd_sx +; \begin{diamond}[20.08.2006] +; note that WDATA.box.width is one pixel less than real window x-size + inc ebx +; \end{diamond}[20.08.2006] sub ebx, [drbar.bar_cx] ja @f .exit: ;// mike.dld, 2005-01-29 @@ -629,6 +636,9 @@ vesa20_drawbar: ; real_sy = MIN(wnd_sy-bar_cy, bar_sy); mov ebx, [edi-twdw + WDATA.box.height] ; ebx = wnd_sy +; \begin{diamond}[20.08.2006] + inc ebx +; \end{diamond} sub ebx, [drbar.bar_cy] ja @f add esp, drbar.stack_data diff --git a/programs/demos/eyes/trunk/eyes.asm b/programs/demos/eyes/trunk/eyes.asm index 6efba894ea..e3b1454fc4 100644 --- a/programs/demos/eyes/trunk/eyes.asm +++ b/programs/demos/eyes/trunk/eyes.asm @@ -20,7 +20,7 @@ use32 db "MENUET01" dd 0x01 dd ENTRANCE - dd EYES_END + dd I_END dd 0x3000 dd 0x3000 dd 0x0 @@ -30,280 +30,9 @@ include 'macros.inc' ENTRANCE: ; start of code ; ==== main ==== - -call prepare_eyes - -call shape_window - -still: - -call draw_eyes ; draw those funny "eyes" - -mov eax,23 ; wait for event with timeout -mov ebx,TIMEOUT -int 0x40 - -cmp eax,1 ; redraw ? -jnz no_draw -call redraw_overlap -no_draw: - -cmp eax,2 ; key ? -jz key - -cmp eax,3 ; button ? -jz button - -jmp still ; loop - -; EVENTS - -key: -mov eax,2 ; just read and ignore -int 0x40 -jmp still - -button: ; analyze button -mov eax,-1 ; this is button 1 - we have only one button :-) -int 0x40 -jmp still - -; -====- declarations -====- - -imagedata equ EYES_END -skindata equ EYES_END+925 -winref equ EYES_END+6325 - -; -====- shape -====- - -shape_window: - -mov eax,50 ; set up shape reference area -mov ebx,0 -mov ecx,winref -int 0x40 - -ret - -; -====- redrawing -====- - -draw_eyes: ; check mousepos to disable blinking - -mov eax,37 -xor ebx,ebx -int 0x40 -cmp dword [mouse],eax -jne redraw_ok -ret -redraw_ok: -mov [mouse],eax - -redraw_overlap: ; label for redraw event (without checkmouse) - -mov eax,12 -mov ebx,1 -int 0x40 - -xor eax,eax ; define window -mov ebx,[win_ebx] -mov ecx,[win_ecx] -xor edx,edx -xor esi,esi -xor edi,edi -int 0x40 - -mov eax,8 ; define closebutton -mov ebx,60 -mov ecx,45 -mov edx,1 -int 0x40 - -mov eax,7 -mov ebx,skindata -mov ecx,60*65536+30 -mov edx,15 -int 0x40 - -mov eax,15 -mov ebx,30 -call draw_eye_point -add eax,30 -call draw_eye_point - -mov eax,12 -mov ebx,2 -int 0x40 - -ret - -draw_eye_point: ; draw eye point (EAX=X, EBX=Y) -pusha - -mov ecx, [mouse] ; ecx = mousex, edx = mousey -mov edx,ecx -shr ecx,16 -and edx,0xFFFF - -; ===> calculate position - -push eax -push ebx -mov byte [sign1],0 -mov esi, [win_ebx] -shr esi,16 -add eax,esi -sub ecx,eax ; ECX=ECX-EAX (signed) , ECX=|ECX| -jnc abs_ok_1 -neg ecx -mov byte [sign1],1 -abs_ok_1: -mov [temp1],ecx -mov byte [sign2],0 -mov esi,[win_ecx] -shr esi,16 -add ebx,esi -sub edx,ebx ; EDX=EDX-EBX (signed) , EDX=|EDX| -jnc abs_ok_2 -neg edx -mov byte [sign2],1 -abs_ok_2: -mov [temp2],edx -pop ebx -pop eax - -push eax ; ECX*=ECX -push edx -xor eax,eax -xor edx,edx -mov ax,cx -mul cx -shl edx,16 -or eax,edx -mov ecx,eax -pop edx -pop eax - -push eax ; EDX*=EDX -push ecx -mov ecx,edx -xor eax,eax -xor edx,edx -mov ax,cx -mul cx -shl edx,16 -or eax,edx -mov edx,eax -pop ecx -pop eax - -push ebx -push ecx -push edx -push eax -mov ebx,ecx ; EBX=ECX+EDX -add ebx,edx -xor edi,edi ; ESI=SQRT(EBX) -mov ecx,edi -mov edx,edi -inc edi -mov eax,edi -inc edi -sqrt_loop: -add ecx,eax -add eax,edi -inc edx -cmp ecx,ebx -jbe sqrt_loop -dec edx -mov esi,edx -mov ax,si ; ESI=ESI/7 -mov dl,7 -div dl -and ax,0xFF -mov si,ax ; ESI ? 0 : ESI=1 -jnz nozeroflag1 -mov si,1 -nozeroflag1: - -pop eax -pop edx -pop ecx -pop ebx - -push eax ; ECX=[temp1]/ESI -push edx -mov eax,[temp1] -mov dx,si -div dl -mov cl,al -and ecx,0xFF -pop edx -pop eax - -cmp byte [sign1],1 -je subtract_1 -add eax,ecx ; EAX=EAX+ECX -jmp calc_ok_1 -subtract_1: -sub eax,ecx ; EAX=EAX-ECX -calc_ok_1: - -push eax ; EDX=[temp2]/ESI -push ecx -mov eax,[temp2] -mov dx,si -div dl -mov dl,al -and dx,0xFF -pop ecx -pop eax - -cmp byte [sign2],1 -je subtract_2 -add ebx,edx ; EBX=EBX+EDX -jmp calc_ok_2 -subtract_2: -sub ebx,edx ; EBX=EBX-EDX -calc_ok_2: - -; <=== - -mov ecx,ebx ; draw point -mov ebx,eax -mov eax,13 -dec ecx -dec ecx -dec ebx -dec ebx -shl ecx,16 -add ecx,4 -shl ebx,16 -add ebx,4 -mov eax,13 -xor edx,edx -int 0x40 - -popa -ret - -; -====- working on images and window -====- - prepare_eyes: -;mov eax,6 ; load EYES.RAW -;mov ebx,graphix -;mov ecx,0x00000000 -;mov edx,0xFFFFFFFF -;mov esi,imagedata -;int 0x40 -;cmp eax,0xFFFFFFFF -;jnz filefound - -;mov eax,-1 ; file not exists... -;int 0x40 - -;filefound: -mov esi,imagedata+25 ; transform grayscale to putimage format +mov esi,imagedata ; transform grayscale to putimage format mov edi,skindata mov ecx,30 transform_loop: @@ -334,7 +63,7 @@ sub eax,30*65536 mov [win_ebx],eax mov [win_ecx],dword 10*65536+44 -mov esi,imagedata+25 ; calculate shape reference area +mov esi,imagedata ; calculate shape reference area mov edi,winref mov ecx,900 ; disable drag bar mov al,0 @@ -351,19 +80,203 @@ call copy_line pop ecx loop shape_loop +; -====- shape -====- + +shape_window: + +mov eax,50 ; set up shape reference area +xor ebx,ebx +mov ecx,winref +int 0x40 + +call draw_window + +still: + +call draw_eyes ; draw those funny "eyes" + +_wait: +mov eax,23 ; wait for event with timeout +mov ebx,TIMEOUT +int 0x40 + dec eax + jz redraw + dec eax + jz key + dec eax + jnz still +button: + or eax, -1 + int 0x40 +key: + mov al, 2 + int 0x40 + jmp still +redraw: + call draw_window + call redraw_eyes + jmp _wait + +; -====- redrawing -====- + +draw_eyes: ; check mousepos to disable blinking + +mov eax,37 +xor ebx,ebx +int 0x40 +cmp dword [mouse],eax +jne redraw_ok ret +redraw_ok: +mov [mouse],eax + +redraw_eyes: +mov eax,7 +mov ebx,skindata +mov ecx,60*65536+30 +mov edx,15 +int 0x40 + +mov eax,15 +mov ebx,30 +call draw_eye_point +add eax,30 +call draw_eye_point +ret + +draw_window: + +mov eax,12 +mov ebx,1 +int 0x40 + +xor eax,eax ; define window +mov ebx,[win_ebx] +mov ecx,[win_ecx] +xor edx,edx +xor esi,esi +xor edi,edi +int 0x40 + +mov eax,8 ; define closebutton +mov ebx,60 +mov ecx,45 +mov edx,1 +int 0x40 + +mov eax,12 +mov ebx,2 +int 0x40 + +ret + +draw_eye_point: ; draw eye point (EAX=X, EBX=Y) +pusha + + movzx ecx, word [mouse+2] ; ecx = mousex, esi = mousey + movzx esi, word [mouse] + +; ===> calculate position + +push eax +push ebx +mov byte [sign1],0 +mov edx, [win_ebx] +shr edx,16 +add eax,edx +sub ecx,eax ; ECX=ECX-EAX (signed) , ECX=|ECX| +jnc abs_ok_1 +neg ecx +mov byte [sign1],1 +abs_ok_1: + push ecx ; save x distance +mov byte [sign2],0 +mov edx,[win_ecx] +shr edx,16 +add ebx,edx +sub esi,ebx ; EDX=EDX-EBX (signed) , EDX=|EDX| +jnc abs_ok_2 +neg esi +mov byte [sign2],1 +abs_ok_2: +mov [temp2],esi + +; ESI = ECX*ECX+ESI*ESI + imul ecx, ecx + imul esi, esi + add esi, ecx + +xor ecx,ecx ; EDX=SQRT(EBX) +xor edx,edx +mov eax,1 +sqrt_loop: +; in this moment ecx=edx*edx, eax=1+2*edx +add ecx,eax +inc eax +inc eax +inc edx +cmp ecx,esi +jbe sqrt_loop +dec edx +mov eax,edx ; EDX=EDX/7 +mov dl,7 +div dl +and eax,0xFF +mov edx,eax ; EDX ? 0 : EDX=1 +jnz nozeroflag1 +inc edx +nozeroflag1: + + pop eax ; EAX = x distance + ; ECX=EAX/EDX +div dl +movzx ecx,al +pop ebx +pop eax + + cmp byte [sign1], 0 + jz @f + neg ecx +@@: + add eax, ecx + +push eax ; ESI=[temp2]/EDX +mov eax,[temp2] +div dl +movzx esi,al +pop eax + + cmp byte [sign2], 0 + jz @f + neg esi +@@: + add ebx, esi + +; <=== + +; draw point + lea ecx, [ebx-2] + lea ebx, [eax-2] +shl ecx,16 +add ecx,4 +shl ebx,16 +add ebx,4 +mov eax,13 +xor edx,edx +int 0x40 + +popa +ret + +; -====- working on images and window -====- copy_line: ; copy single line to shape reference area mov ecx,30 cpl_loop: lodsb -cmp al,0xFF -jnz set_one -mov al,0 -jmp cpl_ok -set_one: -mov al,1 -cpl_ok: +; input is image: 0xFF = white pixel, 0 = black pixel +; output is membership boolean: 0 = pixel no, 1 = pixel ok +inc eax stosb loop cpl_loop ret @@ -375,14 +288,19 @@ ret win_ebx dd 0x0 win_ecx dd 0x0 mouse dd 0xFFFFFFFF -;graphix db "EYES.RAW " + +EYES_END: ; end of code +imagedata: +; texture is 900 bytes starting from 25th +file "eyes.raw":25,900 +I_END: ; temporary storage for math routines -temp1 dd 0 -temp2 dd 0 -sign1 db 0 -sign2 db 0 +sign1 db ? +sign2 db ? +align 4 +temp2 dd ? -EYES_END: ; end of code -file "EYES.RAW" +skindata rb 60*30*3 +winref rb 45*60