From b308bbdde722f9ac1083694899f6dac6a4742fdb Mon Sep 17 00:00:00 2001 From: "Evgeny Grechnikov (Diamond)" Date: Fri, 29 Dec 2006 15:42:36 +0000 Subject: [PATCH] NTFS reader, part 1: read root directory git-svn-id: svn://kolibrios.org@256 a494cfbc-eb01-0410-851d-a64ba20cac60 --- kernel/trunk/blkdev/hd_drv.inc | 1 + kernel/trunk/fs/fat32.inc | 157 ++-- kernel/trunk/fs/fs_lfn.inc | 2 +- kernel/trunk/fs/ntfs.inc | 1274 ++++++++++++++++++++++++++++++++ kernel/trunk/fs/part_set.inc | 122 ++- kernel/trunk/kernel.asm | 9 +- kernel/trunk/kernel32.inc | 1 + 7 files changed, 1492 insertions(+), 74 deletions(-) create mode 100755 kernel/trunk/fs/ntfs.inc diff --git a/kernel/trunk/blkdev/hd_drv.inc b/kernel/trunk/blkdev/hd_drv.inc index 170c4e438e..9edc8b3854 100755 --- a/kernel/trunk/blkdev/hd_drv.inc +++ b/kernel/trunk/blkdev/hd_drv.inc @@ -21,6 +21,7 @@ hd_read: ; input : eax = block to read ; ebx = destination ;----------------------------------------------------------- + and [hd_error], 0 push ecx esi edi ; scan cache mov ecx,cache_max ; entries in cache diff --git a/kernel/trunk/fs/fat32.inc b/kernel/trunk/fs/fat32.inc index 4be80235dc..2fe2cdb409 100644 --- a/kernel/trunk/fs/fat32.inc +++ b/kernel/trunk/fs/fat32.inc @@ -189,7 +189,7 @@ set_FAT: jb sfc_error cmp eax,[LAST_CLUSTER] ja sfc_error - cmp [fat_type],16 + cmp [fs_type],16 je sfc_1 add eax,eax sfc_1: @@ -217,7 +217,7 @@ set_FAT: sfc_in_cache: - cmp [fat_type],16 + cmp [fs_type],16 jne sfc_test32 sfc_set16: @@ -253,7 +253,7 @@ get_FAT: ;-------------------------------- push ebx esi - cmp [fat_type],16 + cmp [fs_type],16 je gfc_1 add eax,eax gfc_1: @@ -381,7 +381,7 @@ analyze_directory: jnb adr_data_cluster mov eax,[ROOT_CLUSTER] ; if cluster < 2 then read rootdir - cmp [fat_type],16 + cmp [fs_type],16 jne adr_data_cluster mov eax,[ROOT_START] mov edx,[ROOT_SECTORS] @@ -476,7 +476,7 @@ analyze_directory_to_write: jnb adw_data_cluster mov eax,[ROOT_CLUSTER] ; if cluster < 2 then read rootdir - cmp [fat_type],16 + cmp [fs_type],16 jne adw_data_cluster mov eax,[ROOT_START] mov edx,[ROOT_SECTORS] @@ -599,7 +599,7 @@ get_data_cluster: jnb gdc_cluster mov eax,[ROOT_CLUSTER] ; if cluster < 2 then read rootdir - cmp [fat_type],16 + cmp [fs_type],16 jne gdc_cluster mov eax,[ROOT_START] mov ecx,[ROOT_SECTORS] ; Note: not cluster size @@ -817,10 +817,13 @@ makedir: ; 10 - access denied ; Note : can only make one directory at time ;----------------------------------------------------- - cmp [fat_type],0 - jnz make_dir_fat_ok - mov eax,ERROR_UNKNOWN_FS - ret + cmp [fs_type], 16 + jz make_dir_fat_ok + cmp [fs_type], 32 + jz make_dir_fat_ok + push ERROR_UNKNOWN_FS + pop eax + ret make_dir_fat_ok: ; call reserve_hd1 @@ -995,7 +998,7 @@ add_disk_free_space: ;----------------------------------------------------- test ecx,ecx ; no change je add_dfs_no - cmp [fat_type],32 ; free disk space only used by fat32 + cmp [fs_type],32 ; free disk space only used by fat32 jne add_dfs_no push eax ebx @@ -1036,10 +1039,13 @@ file_write: ; 8 - disk full ; 10 - access denied ;-------------------------------------------------------------------------- - cmp [fat_type],0 - jnz fat_ok_for_writing - mov eax,ERROR_UNKNOWN_FS - ret + cmp [fs_type], 16 + jz fat_ok_for_writing + cmp [fs_type], 32 + jz fat_ok_for_writing + push ERROR_UNKNOWN_FS + pop eax + ret fat_ok_for_writing: ; call reserve_hd1 @@ -1222,8 +1228,10 @@ file_read: ; 10 - access denied ; ebx = size of file/directory ;-------------------------------------------------------------------------- - cmp [fat_type],0 - jnz fat_ok_for_reading + cmp [fs_type], 16 + jz fat_ok_for_reading + cmp [fs_type], 32 + jz fat_ok_for_reading xor ebx,ebx mov eax,ERROR_UNKNOWN_FS mov [hd1_status], ebx @@ -1344,7 +1352,7 @@ get_dir_size: mov eax,[ROOT_SECTORS] shl eax,9 ; fat16 rootdir size in bytes - cmp [fat_type],16 + cmp [fs_type],16 je dir_size_ret mov eax,[ROOT_CLUSTER] @@ -1379,10 +1387,13 @@ file_delete: ; 5 - file not found ; 10 - access denied ;----------------------------------------------------- - cmp [fat_type],0 - jnz file_del_fat_ok - mov eax,ERROR_UNKNOWN_FS - ret + cmp [fs_type], 16 + jz file_del_fat_ok + cmp [fs_type], 32 + jz file_del_fat_ok + push ERROR_UNKNOWN_FS + pop eax + ret file_del_fat_ok: pushad @@ -1665,10 +1676,13 @@ rename: ; 8 - disk full ; 10 - access denied ;----------------------------------------------------------- - cmp [fat_type],0 - jnz fat_ok_for_rename - mov eax,ERROR_UNKNOWN_FS - ret + cmp [fs_type], 16 + jz fat_ok_for_rename + cmp [fs_type], 32 + jz fat_ok_for_rename + push ERROR_UNKNOWN_FS + pop eax + ret fat_ok_for_rename: ; call reserve_hd1 @@ -1825,8 +1839,10 @@ get_hd_info: ; ebx = total clusters on disk ; ecx = free clusters on disk ;----------------------------------------------------------- - cmp [fat_type],0 - jnz info_fat_ok + cmp [fs_type], 16 + jz info_fat_ok + cmp [fs_type], 32 + jz info_fat_ok xor edx,edx xor ebx,ebx xor ecx,ecx @@ -1949,7 +1965,7 @@ hd_find_lfn: push fat16_root_first push fat16_root_next mov eax, [ROOT_CLUSTER] - cmp [fat_type], 32 + cmp [fs_type], 32 jz .fat32 .loop: call fat_find_lfn @@ -2000,11 +2016,15 @@ hd_find_lfn: ; ;-------------------------------------------------------------- fs_HdRead: - cmp [fat_type], 0 - jnz @f - or ebx, -1 - mov eax, ERROR_UNKNOWN_FS - ret + cmp [fs_type], 16 + jz @f + cmp [fs_type], 32 + jz @f + cmp [fs_type], 1 + jz ntfs_HdRead + or ebx, -1 + mov eax, ERROR_UNKNOWN_FS + ret @@: push edi cmp byte [esi], 0 @@ -2155,6 +2175,17 @@ fs_HdRead: ; ;-------------------------------------------------------------- fs_HdReadFolder: + cmp [fs_type], 1 + jz ntfs_HdReadFolder + cmp [fs_type], 16 + jz @f + cmp [fs_type], 32 + jz @f + push ERROR_UNSUPPORTED_FS + pop eax + or ebx, -1 + ret +@@: mov eax, [ROOT_CLUSTER] push edi cmp byte [esi], 0 @@ -2195,7 +2226,7 @@ fs_HdReadFolder: mov [cluster_tmp], eax test eax, eax jnz @f - cmp [fat_type], 32 + cmp [fs_type], 32 jz .notfound mov eax, [ROOT_START] push [ROOT_SECTORS] @@ -2525,8 +2556,13 @@ fshrfs: ret fs_HdRewrite: - cmp [fat_type], 0 - jz fshrfs + cmp [fs_type], 1 + jz ntfs_HdRewrite + cmp [fs_type], 16 + jz @f + cmp [fs_type], 32 + jnz fshrfs +@@: cmp byte [esi], 0 jz fshrad pushad @@ -2545,7 +2581,7 @@ fs_HdRewrite: test ebp, ebp jnz .noroot mov ebp, [ROOT_CLUSTER] - cmp [fat_type], 32 + cmp [fs_type], 32 jz .pushnotroot push fat16_root_extend_dir push fat16_root_end_write @@ -2944,7 +2980,7 @@ fs_HdRewrite: ;---------------------------------------------------------------- ; -; fs_HdWrite - LFN variant for writing to floppy +; fs_HdWrite - LFN variant for writing to hard disk ; ; esi points to filename ; ebx pointer to 64-bit number = first wanted byte, 0+ @@ -2968,8 +3004,12 @@ fs_HdWrite.ret11: jmp fs_HdWrite.ret0 fs_HdWrite: - cmp [fat_type], 0 - jnz @f + cmp [fs_type], 1 + jz ntfs_HdWrite + cmp [fs_type], 16 + jz @f + cmp [fs_type], 32 + jz @f push ERROR_UNKNOWN_FS jmp .ret0 @@: @@ -3301,8 +3341,12 @@ hd_extend_file: ; ;-------------------------------------------------------------- fs_HdSetFileEnd: - cmp [fat_type], 0 - jnz @f + cmp [fs_type], 1 + jz ntfs_HdSetFileEnd + cmp [fs_type], 16 + jz @f + cmp [fs_type], 32 + jz @f push ERROR_UNKNOWN_FS .ret: pop eax @@ -3529,8 +3573,12 @@ fs_HdSetFileEnd: ret fs_HdGetFileInfo: - cmp [fat_type], 0 - jnz @f + cmp [fs_type], 1 + jz ntfs_HdGetFileInfo + cmp [fs_type], 16 + jz @f + cmp [fs_type], 32 + jz @f mov eax, ERROR_UNKNOWN_FS ret @@: @@ -3553,8 +3601,12 @@ fs_HdGetFileInfo: jmp fs_GetFileInfo_finish fs_HdSetFileInfo: - cmp [fat_type], 0 - jnz @f + cmp [fs_type], 1 + jz ntfs_HdSetFileInfo + cmp [fs_type], 16 + jz @f + cmp [fs_type], 32 + jz @f mov eax, ERROR_UNKNOWN_FS ret @@: @@ -3589,6 +3641,8 @@ fs_HdSetFileInfo: xor eax, eax ret +if 0 ; starting from revision 237 execute is implemented in taskman.inc + ; through fs_XxxGetFileInfo and fs_XxxRead ;---------------------------------------------------------------- ; ; fs_HdExecute - LFN variant for executing from harddisk @@ -3708,6 +3762,7 @@ fs_HdExecute: popad mov eax, 11 ret +end if ;---------------------------------------------------------------- ; @@ -3719,8 +3774,12 @@ fs_HdExecute: ; ;-------------------------------------------------------------- fs_HdDelete: - cmp [fat_type], 0 - jnz @f + cmp [fs_type], 1 + jz ntfs_HdDelete + cmp [fs_type], 16 + jz @f + cmp [fs_type], 32 + jz @f push ERROR_UNKNOWN_FS .pop_ret: pop eax diff --git a/kernel/trunk/fs/fs_lfn.inc b/kernel/trunk/fs/fs_lfn.inc index 9694eb6f69..bb46383f35 100644 --- a/kernel/trunk/fs/fs_lfn.inc +++ b/kernel/trunk/fs/fs_lfn.inc @@ -464,7 +464,7 @@ fs_HdServices: dd fs_HdSetFileEnd dd fs_HdGetFileInfo dd fs_HdSetFileInfo - dd fs_HdExecute + dd 0 ;fs_HdExecute dd fs_HdDelete fs_NumHdServices = ($ - fs_HdServices)/4 diff --git a/kernel/trunk/fs/ntfs.inc b/kernel/trunk/fs/ntfs.inc new file mode 100755 index 0000000000..67022f5086 --- /dev/null +++ b/kernel/trunk/fs/ntfs.inc @@ -0,0 +1,1274 @@ +ntfs_test_bootsec: +; in: ebx->buffer, edx=size of partition +; out: CF set <=> invalid +; 1. Name=='NTFS ' + cmp dword [ebx+3], 'NTFS' + jnz .no + cmp dword [ebx+7], ' ' + jnz .no +; 2. Number of bytes per sector is the same as for physical device +; (that is, 0x200 for hard disk) + cmp word [ebx+11], 0x200 + jnz .no +; 3. Number of sectors per cluster must be power of 2 + movzx eax, byte [ebx+13] + dec eax + js .no + test al, [ebx+13] + jnz .no +; 4. FAT parameters must be zero + cmp word [ebx+14], 0 + jnz .no + cmp dword [ebx+16], 0 + jnz .no + cmp byte [ebx+20], 0 + jnz .no + cmp word [ebx+22], 0 + jnz .no + cmp dword [ebx+32], 0 + jnz .no +; 5. Number of sectors <= partition size + cmp dword [ebx+0x2C], 0 + ja .no + cmp [ebx+0x28], edx + ja .no +; 6. $MFT and $MFTMirr clusters must be within partition + cmp dword [ebx+0x34], 0 + ja .no + push edx + movzx eax, byte [ebx+13] + mul dword [ebx+0x30] + test edx, edx + pop edx + jnz .no + cmp eax, edx + ja .no + cmp dword [ebx+0x3C], 0 + ja .no + push edx + movzx eax, byte [ebx+13] + mul dword [ebx+0x38] + test edx, edx + pop edx + jnz .no + cmp eax, edx + ja .no +; 7. Clusters per FRS must be either negative and in [-31,-9] or positive and power of 2 + movsx eax, byte [ebx+0x40] + cmp al, -31 + jl .no + cmp al, -9 + jle @f + dec eax + js .no + test [ebx+0x40], al + jnz .no +@@: +; 8. Same for clusters per IndexAllocationBuffer + movsx eax, byte [ebx+0x44] + cmp al, -31 + jl .no + cmp al, -9 + jle @f + dec eax + js .no + test [ebx+0x44], al + jnz .no +@@: +; OK, this is correct NTFS bootsector + clc + ret +.no: +; No, this bootsector isn't NTFS + stc + ret + +ntfs_setup: ; CODE XREF: part_set.inc +; By given bootsector, initialize some NTFS variables + call ntfs_test_bootsec + jc problem_fat_dec_count + movzx eax, byte [ebx+13] + mov [ntfs_data.sectors_per_cluster], eax + mov eax, [ebx+0x28] + add eax, [PARTITION_START] + dec eax + mov [PARTITION_END], eax + mov [fs_type], 1 + mov eax, [ebx+0x30] + mov [ntfs_data.mft_cluster], eax + mov eax, [ebx+0x38] + mov [ntfs_data.mftmirr_cluster], eax + movsx eax, byte [ebx+0x40] + test eax, eax + js .1 + mul [ntfs_data.sectors_per_cluster] + shl eax, 9 + jmp .2 +.1: + neg eax + mov ecx, eax + mov eax, 1 + shl eax, cl +.2: + mov [ntfs_data.frs_size], eax + movsx eax, byte [ebx+0x44] + test eax, eax + js .3 + mul [ntfs_data.sectors_per_cluster] + shl eax, 9 + jmp .4 +.3: + neg eax + mov ecx, eax + mov eax, 1 + shl eax, cl +.4: + mov [ntfs_data.iab_size], eax +; allocate space for buffers + add eax, [ntfs_data.frs_size] + push eax + call kernel_alloc + test eax, eax + jz problem_fat_dec_count + mov [ntfs_data.frs_buffer], eax + add eax, [ntfs_data.frs_size] + mov [ntfs_data.iab_buffer], eax +; read $MFT disposition + mov eax, [ntfs_data.mft_cluster] + mul [ntfs_data.sectors_per_cluster] + call ntfs_read_frs_sector + cmp [hd_error], 0 + jnz .usemirr + cmp dword [ebx], 'FILE' + jnz .usemirr + call ntfs_restore_usa_frs + jnc .mftok +.usemirr: + and [hd_error], 0 + mov eax, [ntfs_data.mftmirr_cluster] + mul [ntfs_data.sectors_per_cluster] + call ntfs_read_frs_sector + cmp [hd_error], 0 + jnz @f + cmp dword [ebx], 'FILE' + jnz @f + call ntfs_restore_usa_frs + jnc .mftok +@@: +; $MFT and $MFTMirr invalid! +.fail_free_frs: + push [ntfs_data.frs_buffer] + call kernel_free + jmp problem_fat_dec_count +.fail_free_mft: + push [ntfs_data.mft_retrieval] + call kernel_free + jmp .fail_free_frs +.mftok: +; read $MFT table retrieval information +; start with one page, increase if not enough (when MFT too fragmented) + push ebx + push 0x1000 + call kernel_alloc + pop ebx + test eax, eax + jz .fail_free_frs + mov [ntfs_data.mft_retrieval], eax + and [ntfs_data.mft_retrieval_size], 0 + mov [ntfs_data.mft_retrieval_alloc], 0x1000/8 +; $MFT base record must contain unnamed non-resident $DATA attribute + movzx eax, word [ebx+14h] + add eax, ebx +.scandata: + cmp dword [eax], -1 + jz .fail_free_mft + cmp dword [eax], 0x80 + jnz @f + cmp byte [eax+9], 0 + jz .founddata +@@: + add eax, [eax+4] + jmp .scandata +.founddata: + cmp byte [eax+8], 0 + jz .fail_free_mft +; load first portion of $DATA attribute retrieval information + mov edx, [eax+0x18] + mov [ntfs_data.mft_retrieval_end], edx + mov esi, eax + movzx eax, word [eax+0x20] + add esi, eax + sub esp, 10h +.scanmcb: + call ntfs_decode_mcb_entry + jnc .scanmcbend + call .get_mft_retrieval_ptr + mov edx, [esp] ; block length + mov [eax], edx + mov edx, [esp+8] ; block addr (relative) + mov [eax+4], edx + inc [ntfs_data.mft_retrieval_size] + jmp .scanmcb +.scanmcbend: + add esp, 10h +; there may be other portions of $DATA attribute in auxiliary records; +; if they will be needed, they will be loaded later + + mov [ntfs_data.cur_index_size], 0x1000/0x200 + push 0x1000 + call kernel_alloc + test eax, eax + jz .fail_free_mft + mov [ntfs_data.cur_index_buf], eax + + popad + and [hd1_status], 0 + ret + +.get_mft_retrieval_ptr: + pushad + mov eax, [ntfs_data.mft_retrieval_size] + cmp eax, [ntfs_data.mft_retrieval_alloc] + jnz .ok + add eax, 0x1000/8 + mov [ntfs_data.mft_retrieval_alloc], eax + shl eax, 3 + push eax + call kernel_alloc + test eax, eax + jnz @f + popad + add esp, 14h + jmp .fail_free_mft +@@: + mov esi, [ntfs_data.mft_retrieval] + mov edi, eax + mov ecx, [ntfs_data.mft_retrieval_size] + add ecx, ecx + rep movsd + push [ntfs_data.mft_retrieval] + mov [ntfs_data.mft_retrieval], eax + call kernel_free + mov eax, [ntfs_data.mft_retrieval_size] +.ok: + shl eax, 3 + add eax, [ntfs_data.mft_retrieval] + mov [esp+28], eax + popad + ret + +ntfs_read_frs_sector: + push eax ecx + add eax, [PARTITION_START] + mov ecx, [ntfs_data.frs_size] + shr ecx, 9 + mov ebx, [ntfs_data.frs_buffer] + push ebx +@@: + call hd_read + cmp [hd_error], 0 + jnz .fail + add ebx, 0x200 + inc eax + loop @b +.fail: + pop ebx + pop ecx eax + ret + +uglobal +align 4 +ntfs_cur_attr dd ? +ntfs_cur_iRecord dd ? +ntfs_cur_offs dd ? ; in sectors +ntfs_cur_size dd ? ; in sectors +ntfs_cur_buf dd ? +ntfs_cur_read dd ? ; [output] + +ntfs_attrlist_buf rb 0x400 +ntfs_bitmap_buf rb 0x400 + +ntfs_attr_iRecord dd ? +ntfs_attr_iBaseRecord dd ? +ntfs_attr_offs dd ? +ntfs_attr_list dd ? +endg + +ntfs_read_attr: +; in: global variables +; out: [ntfs_cur_read] + pushad + and [ntfs_cur_read], 0 + cmp [ntfs_cur_iRecord], 0 + jnz .nomft + cmp [ntfs_cur_attr], 0x80 + jnz .nomft + mov eax, [ntfs_data.mft_retrieval_end] + inc eax + mul [ntfs_data.sectors_per_cluster] + cmp eax, [ntfs_cur_offs] + jbe .nomft +; precalculated part of $Mft $DATA + mov esi, [ntfs_data.mft_retrieval] + mov eax, [ntfs_cur_offs] + xor edx, edx + div [ntfs_data.sectors_per_cluster] +; eax = VCN, edx = offset in sectors from beginning of cluster + xor ecx, ecx ; ecx will contain LCN +.mftscan: + add ecx, [esi+4] + sub eax, [esi] + jb @f + add esi, 8 + push eax + mov eax, [ntfs_data.mft_retrieval_end] + shl eax, 3 + add eax, [ntfs_data.mft_retrieval] + cmp eax, esi + pop eax + jnz .mftscan + jmp .nomft +@@: + push ecx + add ecx, eax + add ecx, [esi] + push eax + push edx + mov eax, [ntfs_data.sectors_per_cluster] + mul ecx +; eax = sector on partition + add eax, [PARTITION_START] + pop edx + add eax, edx + mov ebx, [ntfs_cur_buf] + pop ecx + neg ecx + imul ecx, [ntfs_data.sectors_per_cluster] + sub ecx, edx + cmp ecx, [ntfs_cur_size] + jb @f + mov ecx, [ntfs_cur_size] +@@: +; ecx = number of sequential sectors to read + call hd_read + cmp [hd_error], 0 + jnz .errread + add [ntfs_cur_read], 0x200 + dec [ntfs_cur_size] + inc [ntfs_cur_offs] + add ebx, 0x200 + mov [ntfs_cur_buf], ebx + inc eax + loop @b + pop ecx + xor eax, eax + xor edx, edx + cmp [ntfs_cur_size], eax + jz @f + add esi, 8 + push eax + mov eax, [ntfs_data.mft_retrieval_end] + shl eax, 3 + add eax, [ntfs_data.mft_retrieval] + cmp eax, esi + pop eax + jz .nomft + jmp .mftscan +@@: + popad + ret +.errread: + pop ecx +.errret: + stc + popad + ret +.nomft: +; 1. Read file record. +; N.B. This will do recursive call of read_attr for $MFT::$Data. + mov eax, [ntfs_cur_iRecord] + mov [ntfs_attr_iRecord], eax + and [ntfs_attr_list], 0 + or [ntfs_attr_iBaseRecord], -1 + call ntfs_read_file_record + test eax, eax + jz .errret +; 2. Find required attribute. + mov eax, [ntfs_data.frs_buffer] +; a) For auxiliary records, read base record +; N.B. If base record is present, +; base iRecord may be 0 (for $Mft), but SequenceNumber is nonzero + cmp dword [eax+24h], 0 + jz @f + mov eax, [eax+20h] +; test eax, eax +; jz @f +.beginfindattr: + mov [ntfs_attr_iRecord], eax + call ntfs_read_file_record + test eax, eax + jz .errret +@@: +; b) Scan for required attribute and for $ATTR_LIST + mov eax, [ntfs_data.frs_buffer] + movzx ecx, word [eax+14h] + add eax, ecx + mov ecx, [ntfs_cur_attr] + and [ntfs_attr_offs], 0 +.scanattr: + cmp dword [eax], -1 + jz .scandone + cmp dword [eax], ecx + jz .okattr + cmp [ntfs_attr_iBaseRecord], -1 + jnz .scancont + cmp dword [eax], 0x20 ; $ATTR_LIST + jnz .scancont + mov [ntfs_attr_list], eax + jmp .scancont +.okattr: + mov [ntfs_attr_offs], eax +.scancont: + add eax, [eax+4] + jmp .scanattr +.scandone: +; c) Check for required offset and length + mov ecx, [ntfs_attr_offs] + jecxz .noattr + call .doreadattr + jc @f + cmp [ntfs_cur_size], 0 + jnz .not_in_cur +@@: + popad + ret +.noattr: +.not_in_cur: + cmp [ntfs_cur_attr], 0x20 + jz @f + mov ecx, [ntfs_attr_list] + test ecx, ecx + jnz .lookattr +.ret_is_attr: + cmp [ntfs_attr_offs], 1 ; CF set <=> ntfs_attr_offs == 0 + popad + ret +.lookattr: +; required attribute or required offset was not found in base record; +; it may be present in auxiliary records; +; scan $ATTR_LIST + mov eax, [ntfs_attr_iBaseRecord] + cmp eax, -1 + jz @f + call ntfs_read_file_record + test eax, eax + jz .errret + or [ntfs_attr_iBaseRecord], -1 +@@: + push [ntfs_cur_offs] + push [ntfs_cur_size] + push [ntfs_cur_read] + push [ntfs_cur_buf] + xor edx, edx + mov [ntfs_cur_offs], edx + mov [ntfs_cur_size], 2 + and [ntfs_cur_read], 0 + mov [ntfs_cur_buf], ntfs_attrlist_buf + push edx + call .doreadattr + pop edx + mov ebp, [ntfs_cur_read] + pop [ntfs_cur_buf] + pop [ntfs_cur_read] + pop [ntfs_cur_size] + pop [ntfs_cur_offs] + jc .errret + mov esi, ntfs_attrlist_buf + or edi, -1 +.scanliststart: + lea ebp, [ebp+esi-1Ah] + mov eax, [ntfs_cur_attr] +.scanlist: + cmp esi, ebp + jae .scanlistdone + cmp eax, [esi] + jz @f +.scanlistcont: + movzx ecx, word [esi+4] + add esi, ecx + jmp .scanlist +@@: + push eax + mov eax, [esi+8] + imul eax, [ntfs_data.sectors_per_cluster] + cmp eax, [ntfs_cur_offs] + pop eax + ja @f + mov edi, [esi+10h] ; keep previous iRecord + jmp .scanlistcont +@@: + cmp edi, -1 + jnz @f + popad + ret +@@: + mov eax, [ntfs_cur_iRecord] + mov [ntfs_attr_iBaseRecord], eax + mov eax, edi + jmp .beginfindattr +.scanlistdone: + sub ebp, ntfs_attrlist_buf-1Ah + test ebp, 1FFh + jnz .ret_is_attr + test edx, edx + jnz @f + inc edx + cmp ebp, 0x400 + jnz .ret_is_attr +@@: + inc edx + push esi edi + mov esi, ntfs_attrlist_buf+0x200 + mov edi, ntfs_attrlist_buf + mov ecx, 0x200/4 + rep movsd + pop edi esi + sub esi, 0x200 + push [ntfs_cur_offs] + push [ntfs_cur_size] + push [ntfs_cur_read] + push [ntfs_cur_buf] + mov [ntfs_cur_offs], edx + mov [ntfs_cur_size], 1 + and [ntfs_cur_read], 0 + mov [ntfs_cur_buf], ntfs_attrlist_buf+0x200 + push esi edx + call .doreadattr + pop edx esi + mov ebp, [ntfs_cur_read] + pop [ntfs_cur_buf] + pop [ntfs_cur_read] + pop [ntfs_cur_size] + pop [ntfs_cur_offs] + jc .errret + jmp .scanliststart + +.doreadattr: + cmp byte [ecx+8], 0 + jnz .nonresident + mov eax, [ecx+10h] ; length + mov esi, eax + mov edx, [ntfs_cur_offs] + shr eax, 9 + cmp eax, edx + jb .okret + shl edx, 9 + sub esi, edx + movzx eax, word [ecx+14h] + add edx, eax + add edx, ecx ; edx -> data + mov eax, [ntfs_cur_size] + cmp eax, (0xFFFFFFFF shr 9)+1 + jbe @f + mov eax, (0xFFFFFFFF shr 9)+1 +@@: + shl eax, 9 + cmp eax, esi + jbe @f + mov eax, esi +@@: +; eax = length, edx -> data + mov [ntfs_cur_read], eax + mov ecx, eax + mov eax, edx + mov ebx, [ntfs_cur_buf] + call memmove + clc + ret +.nonresident: + mov eax, [ecx+30h] ; FileSize + mov edx, [ecx+34h] + add eax, 0x1FF + adc edx, 0 + shrd eax, edx, 9 + sub eax, [ntfs_cur_offs] + ja @f +; return with nothing read +.okret: + clc + ret +@@: +; reduce read length + cmp [ntfs_cur_size], eax + jb @f + mov [ntfs_cur_size], eax +@@: + cmp [ntfs_cur_size], 0 + jz .okret + mov eax, [ntfs_cur_offs] + xor edx, edx + div [ntfs_data.sectors_per_cluster] + sub eax, [ecx+10h] ; first_vbo + jb .okret +; eax = cluster, edx = starting sector + sub esp, 10h + movzx esi, word [ecx+20h] ; mcb_info_ofs + add esi, ecx + xor ebp, ebp +.readloop: + call ntfs_decode_mcb_entry + jnc .break + add ebp, [esp+8] + sub eax, [esp] + jae .readloop + push ecx + push eax + add eax, [esp+8] + add eax, ebp + imul eax, [ntfs_data.sectors_per_cluster] + add eax, edx + add eax, [PARTITION_START] + pop ecx + neg ecx + imul ecx, [ntfs_data.sectors_per_cluster] + sub ecx, edx + cmp ecx, [ntfs_cur_size] + jb @f + mov ecx, [ntfs_cur_size] +@@: + mov ebx, [ntfs_cur_buf] +@@: + call hd_read + cmp [hd_error], 0 + jnz .errread2 + add ebx, 0x200 + mov [ntfs_cur_buf], ebx + inc eax + add [ntfs_cur_read], 0x200 + dec [ntfs_cur_size] + inc [ntfs_cur_offs] + loop @b + pop ecx + cmp [ntfs_cur_size], 0 + jnz .readloop + add esp, 10h + jmp .okret +.errread2: + pop ecx + add esp, 10h + jmp .errret +.break: + add esp, 10h ; CF=0 + ret + +ntfs_read_file_record: +; in: eax=iRecord +; out: [ntfs_data.frs_buffer] contains information +; eax=0 - failed, eax=1 - success +; Read attr $DATA of $Mft, starting from eax*[ntfs_data.frs_size] + push ecx edx + mov ecx, [ntfs_data.frs_size] + mul ecx + shrd eax, edx, 9 + shr edx, 9 + jnz .err + push [ntfs_cur_iRecord] + push [ntfs_cur_attr] + push [ntfs_cur_offs] + push [ntfs_cur_size] + push [ntfs_cur_buf] + push [ntfs_cur_read] + mov [ntfs_cur_attr], 0x80 ; $DATA + and [ntfs_cur_iRecord], 0 ; $Mft + mov [ntfs_cur_offs], eax + shr ecx, 9 + mov [ntfs_cur_size], ecx + mov eax, [ntfs_data.frs_buffer] + mov [ntfs_cur_buf], eax + call ntfs_read_attr + mov eax, [ntfs_cur_read] + pop [ntfs_cur_read] + pop [ntfs_cur_buf] + pop [ntfs_cur_size] + pop [ntfs_cur_offs] + pop [ntfs_cur_attr] + pop [ntfs_cur_iRecord] + pop edx ecx + jc .errret + cmp eax, [ntfs_data.frs_size] + jnz .errret + mov eax, [ntfs_data.frs_buffer] + cmp dword [eax], 'FILE' + jnz .errret + push ebx + mov ebx, eax + call ntfs_restore_usa_frs + pop ebx + setnc al + movzx eax, al +.ret: + ret +.err: + pop edx ecx +.errret: + xor eax, eax + ret + +ntfs_restore_usa_frs: + mov eax, [ntfs_data.frs_size] +ntfs_restore_usa: + pushad + shr eax, 9 + mov ecx, eax + inc eax + cmp [ebx+6], ax + jnz .err + movzx eax, word [ebx+4] + lea esi, [eax+ebx] + lodsw + mov edx, eax + lea edi, [ebx+0x1FE] +@@: + cmp [edi], dx + jnz .err + lodsw + stosw + add edi, 0x1FE + loop @b + popad + clc + ret +.err: + popad + stc + ret + +ntfs_decode_mcb_entry: + push eax ecx edi + lea edi, [esp+16] + xor eax, eax + lodsb + test al, al + jz .end + mov ecx, eax + and ecx, 0xF + cmp ecx, 8 + ja .end + push ecx + rep movsb + pop ecx + sub ecx, 8 + neg ecx + cmp byte [esi-1], 80h + jae .end + push eax + xor eax, eax + rep stosb + pop ecx + shr ecx, 4 + cmp ecx, 8 + ja .end + push ecx + rep movsb + pop ecx + sub ecx, 8 + neg ecx + cmp byte [esi-1], 80h + sbb eax, eax + inc eax + rep stosb + stc +.end: + pop edi ecx eax + ret + +;---------------------------------------------------------------- +; +; ntfs_HdRead - read NTFS hard disk +; +; esi points to filename +; ebx pointer to 64-bit number = first wanted byte, 0+ +; may be ebx=0 - start from first byte +; ecx number of bytes to read, 0+ +; edx mem location to return data +; +; ret ebx = bytes read or 0xffffffff file not found +; eax = 0 ok read or other = errormsg +; +;-------------------------------------------------------------- +ntfs_HdRead: + or ebx, -1 + mov eax, ERROR_UNSUPPORTED_FS + ret + +;---------------------------------------------------------------- +; +; ntfs_HdReadFolder - read NTFS hard disk folder +; +; esi points to filename +; ebx pointer to structure 32-bit number = first wanted block, 0+ +; & flags (bitfields) +; flags: bit 0: 0=ANSI names, 1=UNICODE names +; ecx number of blocks to read, 0+ +; edx mem location to return data +; +; ret ebx = blocks read or 0xffffffff folder not found +; eax = 0 ok read or other = errormsg +; +;-------------------------------------------------------------- +ntfs_HdReadFolder: + mov eax, 5 ; root cluster + cmp byte [esi], 0 + jz .doit +; call ntfs_find_lfn +; jnc .doit +.notfound: + or ebx, -1 + push ERROR_FILE_NOT_FOUND +.pop_ret: + pop eax + ret +.doit: + mov [ntfs_cur_iRecord], eax +.doit2: + mov [ntfs_cur_attr], 0x90 ; $INDEX_ROOT + and [ntfs_cur_offs], 0 + mov eax, [ntfs_data.cur_index_size] + mov [ntfs_cur_size], eax + mov eax, [ntfs_data.cur_index_buf] + mov [ntfs_cur_buf], eax + call ntfs_read_attr + jnc .ok + cmp [hd_error], 0 + jz .notfound + or ebx, -1 + push 11 + jmp .pop_ret +.ok: + cmp [ntfs_cur_read], 0x20 + jae @f + or ebx, -1 +.fserr: + push ERROR_FAT_TABLE + jmp .pop_ret +@@: + pushad + mov esi, [ntfs_data.cur_index_buf] + mov eax, [esi+14h] + add eax, 10h + cmp [ntfs_cur_read], eax + jae .readok1 + add eax, 1FFh + shr eax, 9 + cmp eax, [ntfs_data.cur_index_size] + ja @f + popad + jmp .fserr +@@: +; reallocate + push eax + push [ntfs_data.cur_index_buf] + call kernel_free + pop eax + mov [ntfs_data.cur_index_size], eax + push eax + call kernel_alloc + test eax, eax + jnz @f + and [ntfs_data.cur_index_size], 0 + and [ntfs_data.cur_index_buf], 0 +.nomem: + popad + or ebx, -1 + push 12 + pop eax + ret +@@: + mov [ntfs_data.cur_index_buf], eax + popad + jmp .doit2 +.readok1: + mov ebp, [esi+8] ; subnode_size + shr ebp, 9 + cmp ebp, [ntfs_data.cur_index_size] + jbe .ok2 + push esi ebp + push ebp + call kernel_alloc + pop ebp esi + test eax, eax + jz .nomem + mov edi, eax + mov ecx, [ntfs_data.cur_index_size] + shl ecx, 9-2 + rep movsd + mov esi, eax + mov [ntfs_data.cur_index_size], ebp + push esi ebp + push [ntfs_data.cur_index_buf] + call kernel_free + pop ebp esi + mov [ntfs_data.cur_index_buf], esi +.ok2: + add esi, 10h + mov ebx, [esp+10h] + mov edx, [esp+14h] + push dword [ebx+4] ; read ANSI/UNICODE name + mov ebx, [ebx] +; init header + mov edi, edx + mov ecx, 32/4 + xor eax, eax + rep stosd + mov byte [edx], 1 ; version + mov ecx, [esp+4+18h] + push edx + mov edx, esp +; edi -> BDFE, esi -> current index data, ebp = subnode size, ebx = first wanted block, +; ecx = number of blocks to read +; edx -> parameters block: dd , dd +; at first, dump index root + add esi, [esi] +.dump_root: + test byte [esi+0Ch], 2 + jnz .dump_root_done + call .add_entry + movzx eax, word [esi+8] + add esi, eax + jmp .dump_root +.dump_root_done: +; now dump all subnodes + push ecx edi + mov edi, ntfs_bitmap_buf + mov [ntfs_cur_buf], edi + mov ecx, 0x400/4 + xor eax, eax + rep stosd + mov [ntfs_cur_attr], 0xB0 ; $BITMAP + and [ntfs_cur_offs], 0 + mov [ntfs_cur_size], 2 + call ntfs_read_attr + pop edi ecx + push 0 ; save offset in $BITMAP attribute + and [ntfs_cur_offs], 0 +.dumploop: + mov [ntfs_cur_attr], 0xA0 + mov [ntfs_cur_size], ebp + mov eax, [ntfs_data.cur_index_buf] + mov esi, eax + mov [ntfs_cur_buf], eax + push [ntfs_cur_offs] + call ntfs_read_attr + pop [ntfs_cur_offs] + mov eax, ebp + shl eax, 9 + cmp [ntfs_cur_read], eax + jnz .done + push eax + mov eax, [ntfs_cur_offs] + and eax, 0x400*8-1 + bt dword [ntfs_bitmap_buf], eax + pop eax + jnc .dump_subnode_done + cmp dword [esi], 'INDX' + jnz .dump_subnode_done + push ebx + mov ebx, esi + call ntfs_restore_usa + pop ebx + jc .dump_subnode_done + add esi, 0x18 + add esi, [esi] +.dump_subnode: + test byte [esi+0Ch], 2 + jnz .dump_subnode_done + call .add_entry + movzx eax, word [esi+8] + add esi, eax + jmp .dump_subnode +.dump_subnode_done: + inc [ntfs_cur_offs] + test [ntfs_cur_offs], 0x400*8-1 + jnz .dumploop + mov [ntfs_cur_attr], 0xB0 + push ecx edi + mov edi, ntfs_bitmap_buf + mov [ntfs_cur_buf], edi + mov ecx, 0x400/4 + xor eax, eax + rep stosd + pop edi ecx + pop eax + push [ntfs_cur_offs] + inc eax + mov [ntfs_cur_offs], eax + mov [ntfs_cur_size], 2 + push eax + call ntfs_read_attr + pop eax + pop [ntfs_cur_offs] + push eax + jmp .dumploop +.done: + pop eax + pop edx + mov ebx, [edx+4] + pop edx + xor eax, eax + dec ecx + js @f + mov al, ERROR_END_OF_FILE +@@: + mov [esp+1Ch], eax + mov [esp+10h], ebx + popad + ret + +.add_entry: +; do not return DOS 8.3 names + cmp byte [esi+0x51], 2 + jz .ret +; do not return system files +; ... note that there will be no bad effects if system files also were reported ... + cmp dword [esi], 0x10 + jb .ret + mov eax, [edx] + inc dword [eax+8] ; new file found + dec ebx + jns .ret + dec ecx + js .ret + inc dword [eax+4] ; new file block copied + mov eax, [edx+4] ; flags + call ntfs_direntry_to_bdfe +.ret: + ret + +ntfs_direntry_to_bdfe: + mov [edi+4], eax ; ANSI/UNICODE name + mov eax, [esi+48h] + test eax, 0x10000000 + jz @f + and eax, not 0x10000000 + or al, 0x10 +@@: + stosd + scasd + push edx + mov eax, [esi+0x18] + mov edx, [esi+0x1C] + call ntfs_datetime_to_bdfe + mov eax, [esi+0x30] + mov edx, [esi+0x34] + call ntfs_datetime_to_bdfe + mov eax, [esi+0x20] + mov edx, [esi+0x24] + call ntfs_datetime_to_bdfe + pop edx + mov eax, [esi+0x40] + stosd + mov eax, [esi+0x44] + stosd + push ecx esi edi + movzx ecx, byte [esi+0x50] + add esi, 0x52 + test byte [edi-0x24], 1 + jz .ansi + shr ecx, 1 + rep movsd + adc ecx, ecx + rep movsw + and word [edi], 0 + pop edi + add edi, 520 + pop esi ecx + ret +.ansi: + jecxz .skip +@@: + lodsw + call uni2ansi_char + stosb + loop @b +.skip: + xor al, al + stosb + pop edi + add edi, 264 + pop esi ecx + ret + +iglobal +_24 dd 24 +_60 dd 60 +_10000000 dd 10000000 +days400year dd 365*400+100-4+1 +days100year dd 365*100+25-1 +days4year dd 365*4+1 +days1year dd 365 +months dd 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 +months2 dd 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 +_400 dd 400 +_100 dd 100 +endg + +ntfs_datetime_to_bdfe: +; edx:eax = number of 100-nanosecond intervals since January 1, 1601, in UTC + push eax + mov eax, edx + xor edx, edx + div [_10000000] + xchg eax, [esp] + div [_10000000] + pop edx +; edx:eax = number of seconds since January 1, 1601 + push eax + mov eax, edx + xor edx, edx + div [_60] + xchg eax, [esp] + div [_60] + mov [edi], dl + pop edx +; edx:eax = number of minutes + div [_60] + mov [edi+1], dl +; eax = number of hours (note that 2^64/(10^7*60*60) < 2^32) + xor edx, edx + div [_24] + mov [edi+2], dl + mov [edi+3], byte 0 +; eax = number of days since January 1, 1601 + xor edx, edx + div [days400year] + imul eax, 400 + add eax, 1601 + mov [edi+6], ax + mov eax, edx + xor edx, edx + div [days100year] + cmp al, 4 + jnz @f + dec eax + add edx, [days100year] +@@: + imul eax, 100 + add [edi+6], ax + mov eax, edx + xor edx, edx + div [days4year] + shl eax, 2 + add [edi+6], ax + mov eax, edx + xor edx, edx + div [days1year] + cmp al, 4 + jnz @f + dec eax + add edx, [days1year] +@@: + add [edi+6], ax + push esi edx + mov esi, months + movzx eax, word [edi+6] + test al, 3 + jnz .noleap + xor edx, edx + push eax + div [_400] + pop eax + test edx, edx + jz .leap + xor edx, edx + div [_100] + test edx, edx + jz .noleap +.leap: + mov esi, months2 +.noleap: + pop edx + xor eax, eax + inc eax +@@: + sub edx, [esi] + jb @f + add esi, 4 + inc eax + jmp @b +@@: + add edx, [esi] + pop esi + inc edx + mov [edi+4], dl + mov [edi+5], al + add edi, 8 + ret + +;---------------------------------------------------------------- +; +; ntfs_HdRewrite - write to NTFS hard disk +; +; esi points to filename +; ebx ignored (reserved) +; ecx number of bytes to write, 0+ +; edx mem location to data +; +; ret ebx = number of written bytes +; eax = 0 ok read or other = errormsg +; +;-------------------------------------------------------------- +ntfs_HdRewrite: + xor ebx, ebx + mov eax, ERROR_UNSUPPORTED_FS + ret + +;---------------------------------------------------------------- +; +; ntfs_HdWrite - write to NTFS hard disk +; +; esi points to filename +; ebx pointer to 64-bit number = first wanted byte, 0+ +; may be ebx=0 - start from first byte +; ecx number of bytes to write, 0+ +; edx mem location to data +; +; ret ebx = bytes written (maybe 0) +; eax = 0 ok write or other = errormsg +; +;-------------------------------------------------------------- +ntfs_HdWrite: + xor ebx, ebx + mov eax, ERROR_UNSUPPORTED_FS + ret + +;---------------------------------------------------------------- +; +; ntfs_HdSetFileEnd - set end of file on NTFS 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 +; +;-------------------------------------------------------------- +ntfs_HdSetFileEnd: +ntfs_HdSetFileInfo: +;---------------------------------------------------------------- +; +; ntfs_HdDelete - delete file or empty folder from NTFS hard disk +; +; esi points to filename +; +; ret eax = 0 ok or other = errormsg +; +;-------------------------------------------------------------- +ntfs_HdDelete: + mov eax, ERROR_UNSUPPORTED_FS + ret + +ntfs_HdGetFileInfo: + mov eax, ERROR_UNSUPPORTED_FS + ret + diff --git a/kernel/trunk/fs/part_set.inc b/kernel/trunk/fs/part_set.inc index aa9fea0134..11e3158478 100644 --- a/kernel/trunk/fs/part_set.inc +++ b/kernel/trunk/fs/part_set.inc @@ -6,6 +6,8 @@ ;************************************************************* align 4 + +iglobal ;****************************************************** ; Please do not change this place - variables in text ; Mario79 @@ -13,6 +15,11 @@ align 4 ;****************************************************** PARTITION_START dd 0x3f PARTITION_END dd 0 +fs_type db 0 ; 0=none, 1=NTFS, 16=FAT16, 32=FAT32 + +fs_dependent_data_start: +; FATxx data + SECTORS_PER_FAT dd 0x1f3a NUMBER_OF_FATS dd 0x2 SECTORS_PER_CLUSTER dd 0x8 @@ -30,13 +37,34 @@ fatBAD dd 0x0FFFFFF7 fatEND dd 0x0FFFFFF8 fatMASK dd 0x0FFFFFFF -fat_type db 0 ; 0=none, 16=fat16, 32=fat32 +fs_dependent_data_end: + +virtual at fs_dependent_data_start +; NTFS data +ntfs_data: +.sectors_per_cluster dd ? +.mft_cluster dd ? +.mftmirr_cluster dd ? +.frs_size dd ? ; FRS size in bytes +.iab_size dd ? ; IndexAllocationBuffer size in bytes +.frs_buffer dd ? +.iab_buffer dd ? +.mft_retrieval dd ? +.mft_retrieval_size dd ? +.mft_retrieval_alloc dd ? +.mft_retrieval_end dd ? +.cur_index_size dd ? +.cur_index_buf dd ? +if $ > fs_dependent_data_end +ERROR: increase sizeof(fs_dependent_data)! +end if +end virtual + ;*************************************************************************** ; End place ; Mario79 ;*************************************************************************** -iglobal partition_types: ; list of fat16/32 partitions db 0x04 ; DOS: fat16 <32M db 0x06 ; DOS: fat16 >32M @@ -55,6 +83,7 @@ iglobal db 0xce ; DRDOS/secured: fat16, LBA-mapped db 0xd4 ; Old Multiuser DOS secured: fat16 <32M db 0xd6 ; Old Multiuser DOS secured: fat16 >32M + db 0x07 ; NTFS partition_types_end: @@ -120,9 +149,17 @@ extended_already_set: cmp ecx,[fat32part] ; is it wanted partition? jnz next_primary_partition ; no - mov edx,eax ; start sector - add edx,[ebx+0x1be+8] ; add relative start - + mov edx, eax ; start sector + add edx, [ebx+0x1be+8] ; add relative start + push edx + add edx, [ebx+0x1be+12] ; add length + dec edx ; PARTITION_END is inclusive + mov [PARTITION_END], edx ; note that this can be changed + ; when file system data will be available + mov dl, [ebx+0x1be+4] + mov [fs_type], dl ; save for FS recognizer (separate FAT vs NTFS) + pop edx + next_primary_partition: push eax mov al,[ebx+0x1be+4+16] ; get primary partition type @@ -134,8 +171,15 @@ next_primary_partition: cmp ecx,[fat32part] ; is it wanted partition? jnz next_primary_partition_1 ; no - mov edx,eax ; start sector - add edx,[ebx+0x1be+8+16] ; add relative start + mov edx, eax + add edx, [ebx+0x1be+8+16] + push edx + add edx, [ebx+0x1be+12+16] + dec edx + mov [PARTITION_END], edx + mov dl, [ebx+0x1be+4+16] + mov [fs_type], dl + pop edx next_primary_partition_1: push eax @@ -148,8 +192,15 @@ next_primary_partition_1: cmp ecx,[fat32part] ; is it wanted partition? jnz next_primary_partition_2 ; no - mov edx,eax ; start sector - add edx,[ebx+0x1be+8+16+16] ; add relative start + mov edx, eax + add edx, [ebx+0x1be+8+16+16] + push edx + add edx, [ebx+0x1be+12+16+16] + dec edx + mov [PARTITION_END], edx + mov dl, [ebx+0x1be+4+16+16] + mov [fs_type], dl + pop edx next_primary_partition_2: push eax @@ -162,8 +213,15 @@ next_primary_partition_2: cmp ecx,[fat32part] ; is it wanted partition? jnz next_partition ; no - mov edx,eax ; start sector - add edx,[ebx+0x1be+8+16+16+16] ; add relative start + mov edx, eax + add edx, [ebx+0x1be+8+16+16+16] + push edx + add edx, [ebx+0x1be+12+16+16+16] + dec edx + mov [PARTITION_END], edx + mov dl, [ebx+0x1be+4+16+16+16] + mov [fs_type], dl + pop edx next_partition: push eax @@ -241,7 +299,7 @@ problem_partition_or_fat: popad problem_hd: - mov [fat_type],0 + mov [fs_type],0 mov [hd1_status],0 ; free mov [problem_partition],1 ret @@ -249,14 +307,40 @@ problem_hd: hd_and_partition_ok: mov eax,edx mov [PARTITION_START],eax + mov edx, [PARTITION_END] + sub edx, eax + inc edx ; edx = length of partition - mov [hd_setup],1 +; mov [hd_setup],1 mov ebx,buffer call hd_read ; read boot sector of partition - cmp [hd_error],0 - jne problem_fat_dec_count - - mov [hd_setup],0 + cmp [hd_error], 0 + jz boot_read_ok + cmp [fs_type], 7 + jnz problem_fat_dec_count +; NTFS duplicates bootsector: +; NT4/2k/XP+ saves bootsector copy in the end of disk +; NT 3.51 saves bootsector copy in the middle of disk + and [hd_error], 0 + mov eax, [PARTITION_END] + call hd_read + cmp [hd_error], 0 + jnz @f + call ntfs_test_bootsec + jnc boot_read_ok +@@: + and [hd_error], 0 + mov eax, edx + shr eax, 1 + add eax, [PARTITION_START] + call hd_read + cmp [hd_error], 0 + jnz problem_fat_dec_count ; не судьба... +boot_read_ok: +; mov [hd_setup], 0 +; if we are running on NTFS, check bootsector + cmp [fs_type], 7 + jz ntfs_setup cmp word [ebx+0x1fe],0xaa55 ; is it valid boot sector? jnz problem_fat_dec_count @@ -332,7 +416,7 @@ fat32_partition: mov [fatBAD],0x0FFFFFF7 mov [fatEND],0x0FFFFFF8 mov [fatMASK],0x0FFFFFFF - mov [fat_type],32 ; Fat32 + mov [fs_type],32 ; Fat32 mov [hd1_status],0 ; free ret @@ -346,6 +430,6 @@ fat16_partition: mov [fatBAD],0x0000FFF7 mov [fatEND],0x0000FFF8 mov [fatMASK],0x0000FFFF - mov [fat_type],16 ; Fat16 + mov [fs_type],16 ; Fat16 mov [hd1_status],0 ; free ret diff --git a/kernel/trunk/kernel.asm b/kernel/trunk/kernel.asm index b098d7d266..6791a2b6d2 100644 --- a/kernel/trunk/kernel.asm +++ b/kernel/trunk/kernel.asm @@ -378,11 +378,6 @@ B32: @@: mov [pg_data.kernel_tables], edx -;!!!!!!!!!!!!!!!!!!!!!!!!!! -include 'detect/disks.inc' -;!!!!!!!!!!!!!!!!!!!!!!!!!! - -; CHECK EXTRA REGION ; ENABLE PAGING call test_cpu @@ -462,6 +457,10 @@ include 'detect/disks.inc' mov [graph_data_l+4],al mov [graph_data_l+7],ah +;!!!!!!!!!!!!!!!!!!!!!!!!!! +include 'detect/disks.inc' +;!!!!!!!!!!!!!!!!!!!!!!!!!! + ; READ RAMDISK IMAGE FROM HD ;!!!!!!!!!!!!!!!!!!!!!!! diff --git a/kernel/trunk/kernel32.inc b/kernel/trunk/kernel32.inc index f95e908d1a..4ea6a81297 100644 --- a/kernel/trunk/kernel32.inc +++ b/kernel/trunk/kernel32.inc @@ -241,6 +241,7 @@ include "boot/shutdown.inc" ; shutdown or restart include "fs/fs.inc" ; syscall include "fs/fat32.inc" ; read / write for fat32 filesystem +include "fs/ntfs.inc" ; read / write for ntfs filesystem include "fs/fat12.inc" ; read / write for fat12 filesystem include "blkdev/rd.inc" ; ramdisk read /write include "fs/fs_lfn.inc" ; syscall, version 2