Subversion Repositories Kolibri OS

Rev

Rev 431 | Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. $Revision: 578 $
  2. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  3. ;;                                                              ;;
  4. ;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
  5. ;; Distributed under terms of the GNU General Public License    ;;
  6. ;;                                                              ;;
  7. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  8.  
  9. ;*************************************************************
  10. ;* 12.07.2007 Check all 4 entry of MBR and EMBR
  11. ;* 29.04.2006 Elimination of hangup after the
  12. ;*             expiration hd_wait_timeout -  Mario79
  13. ;* 28.01.2006 find all Fat16/32 partition in all input point
  14. ;*            to MBR - Mario79
  15. ;*************************************************************
  16.  
  17. uglobal
  18. align 4
  19.  
  20. ;******************************************************
  21. ; Please do not change this place - variables  in text
  22. ; Mario79
  23. ; START place
  24. ;******************************************************
  25. PARTITION_START      dd 0x3f
  26. PARTITION_END        dd 0
  27. fs_type              db 0       ; 0=none, 1=NTFS, 16=FAT16, 32=FAT32
  28. align 4
  29.  
  30. fs_dependent_data_start:
  31. ; FATxx data
  32.  
  33. SECTORS_PER_FAT      dd 0x1f3a
  34. NUMBER_OF_FATS       dd 0x2
  35. SECTORS_PER_CLUSTER  dd 0x8
  36. BYTES_PER_SECTOR     dd 0x200   ; Note: if BPS <> 512 need lots of changes
  37. ROOT_CLUSTER         dd 2       ; first rootdir cluster
  38. FAT_START            dd 0       ; start of fat table
  39. ROOT_START           dd 0       ; start of rootdir (only fat16)
  40. ROOT_SECTORS         dd 0       ; count of rootdir sectors (only fat16)
  41. DATA_START           dd 0       ; start of data area (=first cluster 2)
  42. LAST_CLUSTER         dd 0       ; last availabe cluster
  43. ADR_FSINFO           dd 0       ; used only by fat32
  44.  
  45. fatRESERVED          dd 0x0FFFFFF6
  46. fatBAD               dd 0x0FFFFFF7
  47. fatEND               dd 0x0FFFFFF8
  48. fatMASK              dd 0x0FFFFFFF
  49.  
  50. fs_dependent_data_end:
  51. file_system_data_size = $ - PARTITION_START
  52. if file_system_data_size > 96
  53. ERROR: sizeof(file system data) too big!
  54. end if
  55.  
  56. virtual at fs_dependent_data_start
  57. ; NTFS data
  58. ntfs_data:
  59. .sectors_per_cluster    dd      ?
  60. .mft_cluster            dd      ?
  61. .mftmirr_cluster        dd      ?
  62. .frs_size               dd      ?       ; FRS size in bytes
  63. .iab_size               dd      ?       ; IndexAllocationBuffer size in bytes
  64. .frs_buffer             dd      ?
  65. .iab_buffer             dd      ?
  66. .mft_retrieval          dd      ?
  67. .mft_retrieval_size     dd      ?
  68. .mft_retrieval_alloc    dd      ?
  69. .mft_retrieval_end      dd      ?
  70. .cur_index_size         dd      ?
  71. .cur_index_buf          dd      ?
  72. if $ > fs_dependent_data_end
  73. ERROR: increase sizeof(fs_dependent_data)!
  74. end if
  75. end virtual
  76.  
  77. ;***************************************************************************
  78. ; End place
  79. ; Mario79
  80. ;***************************************************************************
  81. endg
  82. iglobal
  83.  
  84.   partition_types:              ; list of fat16/32 partitions
  85.     db    0x04                  ; DOS: fat16 <32M
  86.     db    0x06                  ; DOS: fat16 >32M
  87.     db    0x0b                  ; WIN95: fat32
  88.     db    0x0c                  ; WIN95: fat32, LBA-mapped
  89.     db    0x0e                  ; WIN95: fat16, LBA-mapped
  90.     db    0x14                  ; Hidden DOS: fat16 <32M
  91.     db    0x16                  ; Hidden DOS: fat16 >32M
  92.     db    0x1b                  ; Hidden WIN95: fat32
  93.     db    0x1c                  ; Hidden WIN95: fat32, LBA-mapped
  94.     db    0x1e                  ; Hidden WIN95: fat16, LBA-mapped
  95.     db    0xc4                  ; DRDOS/secured: fat16 <32M
  96.     db    0xc6                  ; DRDOS/secured: fat16 >32M
  97.     db    0xcb                  ; DRDOS/secured: fat32
  98.     db    0xcc                  ; DRDOS/secured: fat32, LBA-mapped
  99.     db    0xce                  ; DRDOS/secured: fat16, LBA-mapped
  100.     db    0xd4                  ; Old Multiuser DOS secured: fat16 <32M
  101.     db    0xd6                  ; Old Multiuser DOS secured: fat16 >32M
  102.     db    0x07                  ; NTFS
  103.   partition_types_end:
  104.  
  105.  
  106.   extended_types:               ; list of extended partitions
  107.     db    0x05                  ; DOS: extended partition
  108.     db    0x0f                  ; WIN95: extended partition, LBA-mapped
  109.     db    0xc5                  ; DRDOS/secured: extended partition
  110.     db    0xd5                  ; Old Multiuser DOS secured: extended partition
  111.   extended_types_end:
  112.  
  113. endg
  114.  
  115. ; Partition chain used:
  116. ; MBR        ;   PARTITION2 ;   PARTITION3 ;   PARTITION4
  117. ;==========================================================
  118. ; fat16/32   +-- fat16/32   +-- fat16/32   +-- fat16/32   +--
  119. ; extended --+   extended --+   extended --+   extended --+
  120. ; 0              0              0              0
  121. ; 0              0              0              0
  122. ; Notes:
  123. ; - extended partition need to be in second entry on table
  124. ; - it will skip over removed partitions
  125.  
  126. set_FAT32_variables:
  127.     mov   [problem_partition],0
  128.     call  reserve_hd1
  129.     call  reserve_hd_channel
  130.  
  131.     cmp   dword [hdpos],0
  132.     je    problem_hd
  133.  
  134.     pushad
  135.     xor   ecx,ecx               ; partition count
  136.     mov   edx,-1                ; flag for partition
  137.     xor   eax,eax               ; read MBR
  138.     xor   ebp,ebp               ; extended partition start
  139.  
  140. new_partition:
  141.     test  ebp,ebp               ; is there extended partition?
  142.     jnz   extended_already_set  ; yes
  143.     xchg  ebp,eax               ; no. set it now
  144.  
  145. extended_already_set:
  146.     add   eax,ebp               ; mbr=mbr+0, ext_part=ext_start+relat_start
  147.     mov   ebx,buffer
  148.     call  hd_read
  149.     cmp  [hd_error],0
  150.     jne  problem_hd
  151.  
  152.     cmp   word [ebx+0x1fe],0xaa55 ; is it valid boot sector?
  153.     jnz   end_partition_chain
  154.     cmp   dword [ebx+0x1be+0xc],0 ; skip over empty partition
  155. ;    jz    next_partition
  156.     jnz    .next_primary_partition
  157.     cmp   dword [ebx+0x1be+0xc+16],0
  158.     jnz    next_primary_partition
  159.     cmp   dword [ebx+0x1be+0xc+16+16],0
  160.     jnz    next_primary_partition_1
  161.     cmp   dword [ebx+0x1be+0xc+16+16+16],0
  162.     jnz    next_primary_partition_2
  163.     jmp   next_partition
  164.    
  165. .next_primary_partition:
  166.     push  eax
  167.     mov   al,[ebx+0x1be+4]      ; get primary partition type
  168.     call  scan_partition_types
  169.     pop   eax
  170.     jnz   next_primary_partition        ; no. skip over
  171.  
  172.     inc   ecx
  173.     cmp   ecx,[fat32part]       ; is it wanted partition?
  174.     jnz   next_primary_partition        ; no
  175.  
  176.         mov     edx, eax                ; start sector
  177.         add     edx, [ebx+0x1be+8]      ; add relative start
  178.         push    edx
  179.         add     edx, [ebx+0x1be+12]     ; add length
  180.         dec     edx                     ; PARTITION_END is inclusive
  181.         mov     [PARTITION_END], edx    ; note that this can be changed
  182.                                         ; when file system data will be available
  183.         mov     dl, [ebx+0x1be+4]
  184.         mov     [fs_type], dl           ; save for FS recognizer (separate FAT vs NTFS)
  185.         pop     edx
  186.  
  187. next_primary_partition:
  188.     push  eax
  189.     mov   al,[ebx+0x1be+4+16]      ; get primary partition type
  190.     call  scan_partition_types
  191.     pop   eax
  192.     jnz   next_primary_partition_1        ; no. skip over
  193.  
  194.     inc   ecx
  195.     cmp   ecx,[fat32part]       ; is it wanted partition?
  196.     jnz   next_primary_partition_1        ; no
  197.  
  198.         mov     edx, eax
  199.         add     edx, [ebx+0x1be+8+16]
  200.         push    edx
  201.         add     edx, [ebx+0x1be+12+16]
  202.         dec     edx
  203.         mov     [PARTITION_END], edx
  204.         mov     dl, [ebx+0x1be+4+16]
  205.         mov     [fs_type], dl
  206.         pop     edx
  207.  
  208. next_primary_partition_1:
  209.     push  eax
  210.     mov   al,[ebx+0x1be+4+16+16]      ; get primary partition type
  211.     call  scan_partition_types
  212.     pop   eax
  213.     jnz   next_primary_partition_2        ; no. skip over
  214.  
  215.     inc   ecx
  216.     cmp   ecx,[fat32part]       ; is it wanted partition?
  217.     jnz   next_primary_partition_2        ; no
  218.  
  219.         mov     edx, eax
  220.         add     edx, [ebx+0x1be+8+16+16]
  221.         push    edx
  222.         add     edx, [ebx+0x1be+12+16+16]
  223.         dec     edx
  224.         mov     [PARTITION_END], edx
  225.         mov     dl, [ebx+0x1be+4+16+16]
  226.         mov     [fs_type], dl
  227.         pop     edx
  228.  
  229. next_primary_partition_2:
  230.     push  eax
  231.     mov   al,[ebx+0x1be+4+16+16+16]      ; get primary partition type
  232.     call  scan_partition_types
  233.     pop   eax
  234.     jnz   next_partition        ; no. skip over
  235.  
  236.     inc   ecx
  237.     cmp   ecx,[fat32part]       ; is it wanted partition?
  238.     jnz   next_partition        ; no
  239.  
  240.         mov     edx, eax
  241.         add     edx, [ebx+0x1be+8+16+16+16]
  242.         push    edx
  243.         add     edx, [ebx+0x1be+12+16+16+16]
  244.         dec     edx
  245.         mov     [PARTITION_END], edx
  246.         mov     dl, [ebx+0x1be+4+16+16+16]
  247.         mov     [fs_type], dl
  248.         pop     edx
  249.  
  250. next_partition:
  251.     push  eax
  252.     mov   al,[ebx+0x1be+4]   ; get extended partition type
  253.     call  scan_extended_types
  254.     pop   eax
  255.     jnz   next_partition_1
  256.  
  257.     mov   eax,[ebx+0x1be+8]     ; add relative start
  258.     test  eax,eax               ; is there extended partition?
  259.     jnz   new_partition         ; yes. read it
  260.  
  261. next_partition_1:
  262.     push  eax
  263.     mov   al,[ebx+0x1be+4+16]   ; get extended partition type
  264.     call  scan_extended_types
  265.     pop   eax
  266.     jnz   next_partition_2
  267.  
  268.     mov   eax,[ebx+0x1be+8+16]     ; add relative start
  269.     test  eax,eax               ; is there extended partition?
  270.     jnz   new_partition         ; yes. read it
  271.  
  272. next_partition_2:
  273.     push  eax
  274.     mov   al,[ebx+0x1be+4+16+16]   ; get extended partition type
  275.     call  scan_extended_types
  276.     pop   eax
  277.     jnz   next_partition_3
  278.  
  279.     mov   eax,[ebx+0x1be+8+16+16]     ; add relative start
  280.     test  eax,eax               ; is there extended partition?
  281.     jnz   new_partition         ; yes. read it
  282.    
  283. next_partition_3:
  284.     push  eax
  285.     mov   al,[ebx+0x1be+4+16+16+16]   ; get extended partition type
  286.     call  scan_extended_types
  287.     pop   eax
  288.     jnz   end_partition_chain   ; no. end chain
  289.  
  290.     mov   eax,[ebx+0x1be+8+16+16+16]  ; get start of extended partition
  291.     test  eax,eax               ; is there extended partition?
  292.     jnz   new_partition         ; yes. read it
  293.    
  294. end_partition_chain:
  295.     mov   [partition_count],ecx
  296.  
  297.     cmp   edx,-1                ; found wanted partition?
  298.     jnz   hd_and_partition_ok   ; yes. install it
  299.     jmp   problem_partition_or_fat
  300.  
  301. scan_partition_types:
  302.     push  ecx
  303.     mov   edi,partition_types
  304.     mov   ecx,partition_types_end-partition_types
  305.     cld
  306.     repne scasb                 ; is partition type ok?
  307.     pop   ecx
  308.     ret
  309.  
  310. scan_extended_types:
  311.     push  ecx
  312.     mov   edi,extended_types
  313.     mov   ecx,extended_types_end-extended_types
  314.     cld
  315.     repne scasb                 ; is it extended partition?
  316.     pop   ecx
  317.     ret
  318.  
  319. problem_fat_dec_count:          ; bootsector is missing or another problem
  320.     dec   [partition_count]     ; remove it from partition_count
  321.  
  322. problem_partition_or_fat:
  323.     popad
  324.  
  325. problem_hd:
  326.     mov   [fs_type],0
  327.     call  free_hd_channel
  328.     mov   [hd1_status],0        ; free
  329.     mov   [problem_partition],1
  330.     ret
  331.  
  332. hd_and_partition_ok:
  333.     mov   eax,edx
  334.     mov   [PARTITION_START],eax
  335.         mov     edx, [PARTITION_END]
  336.         sub     edx, eax
  337.         inc     edx     ; edx = length of partition
  338.  
  339. ;    mov   [hd_setup],1
  340.     mov   ebx,buffer
  341.     call  hd_read               ; read boot sector of partition
  342.         cmp     [hd_error], 0
  343.         jz      boot_read_ok
  344.         cmp     [fs_type], 7
  345.         jnz     problem_fat_dec_count
  346. ; NTFS duplicates bootsector:
  347. ; NT4/2k/XP+ saves bootsector copy in the end of disk
  348. ; NT 3.51 saves bootsector copy in the middle of disk
  349.         and     [hd_error], 0
  350.         mov     eax, [PARTITION_END]
  351.         call    hd_read
  352.         cmp     [hd_error], 0
  353.         jnz     @f
  354.         call    ntfs_test_bootsec
  355.         jnc     boot_read_ok
  356. @@:
  357.         and     [hd_error], 0
  358.         mov     eax, edx
  359.         shr     eax, 1
  360.         add     eax, [PARTITION_START]
  361.         call    hd_read
  362.         cmp     [hd_error], 0
  363.         jnz     problem_fat_dec_count   ; ­¥ áã¤ì¡ ...
  364. boot_read_ok:
  365. ;        mov     [hd_setup], 0
  366. ; if we are running on NTFS, check bootsector
  367.         cmp     [fs_type], 7
  368.         jz      ntfs_setup
  369.  
  370.     cmp   word [ebx+0x1fe],0xaa55 ; is it valid boot sector?
  371.     jnz   problem_fat_dec_count
  372.  
  373.     movzx eax,word [ebx+0xe]    ; sectors reserved
  374.     add   eax,[PARTITION_START]
  375.     mov   [FAT_START],eax       ; fat_start = partition_start + reserved
  376.  
  377.     movzx eax,byte [ebx+0xd]    ; sectors per cluster
  378.     mov   [SECTORS_PER_CLUSTER],eax
  379.  
  380.     movzx ecx,word [ebx+0xb]    ; bytes per sector
  381.     mov   [BYTES_PER_SECTOR],ecx
  382.  
  383.     movzx eax,word [ebx+0x11]   ; count of rootdir entries (=0 fat32)
  384.     mov   edx,32
  385.     mul   edx
  386.     dec   ecx
  387.     add   eax,ecx               ; round up if not equal count
  388.     inc   ecx                   ; bytes per sector
  389.     div   ecx
  390.     mov   [ROOT_SECTORS],eax    ; count of rootdir sectors
  391.  
  392.     movzx eax,word [ebx+0x16]   ; sectors per fat <65536
  393.     test  eax,eax
  394.     jnz   fat16_fatsize
  395.     mov   eax,[ebx+0x24]        ; sectors per fat
  396.   fat16_fatsize:
  397.     mov   [SECTORS_PER_FAT],eax
  398.  
  399.     movzx eax,byte [ebx+0x10]   ; number of fats
  400.     test  eax,eax               ; if 0 it's not fat partition
  401.     jz    problem_fat_dec_count
  402.     mov   [NUMBER_OF_FATS],eax
  403.     imul  eax,[SECTORS_PER_FAT]
  404.     add   eax,[FAT_START]
  405.     mov   [ROOT_START],eax      ; rootdir = fat_start + fat_size * fat_count
  406.     add   eax,[ROOT_SECTORS]    ; rootdir sectors should be 0 on fat32
  407.     mov   [DATA_START],eax      ; data area = rootdir + rootdir_size
  408.  
  409.     movzx eax,word [ebx+0x13]   ; total sector count <65536
  410.     test  eax,eax
  411.     jnz   fat16_total
  412.     mov   eax,[ebx+0x20]        ; total sector count
  413.   fat16_total:
  414.     add   eax,[PARTITION_START]
  415.     dec   eax
  416.     mov   [PARTITION_END],eax
  417.     inc   eax
  418.     sub   eax,[DATA_START]      ; eax = count of data sectors
  419.     xor   edx,edx
  420.     div   dword [SECTORS_PER_CLUSTER]
  421.     inc   eax
  422.     mov   [LAST_CLUSTER],eax
  423.     dec   eax                   ; cluster count
  424.  
  425.     ; limits by Microsoft Hardware White Paper v1.03
  426.     cmp   eax,4085              ; 0xff5
  427.     jb    problem_fat_dec_count ; fat12 not supported
  428.     cmp   eax,65525             ; 0xfff5
  429.     jb    fat16_partition
  430.  
  431. fat32_partition:
  432.     mov   eax,[ebx+0x2c]        ; rootdir cluster
  433.     mov   [ROOT_CLUSTER],eax
  434.     movzx eax,word [ebx+0x30]   ; fs info sector
  435.     add   eax,[PARTITION_START]
  436.     mov   [ADR_FSINFO],eax
  437.  
  438.     popad
  439.  
  440.     mov   [fatRESERVED],0x0FFFFFF6
  441.     mov   [fatBAD],0x0FFFFFF7
  442.     mov   [fatEND],0x0FFFFFF8
  443.     mov   [fatMASK],0x0FFFFFFF
  444.     mov   [fs_type],32         ; Fat32
  445.     call  free_hd_channel
  446.     mov   [hd1_status],0        ; free
  447.     ret
  448.  
  449. fat16_partition:
  450.     xor   eax,eax
  451.     mov   [ROOT_CLUSTER],eax
  452.  
  453.     popad
  454.  
  455.     mov   [fatRESERVED],0x0000FFF6
  456.     mov   [fatBAD],0x0000FFF7
  457.     mov   [fatEND],0x0000FFF8
  458.     mov   [fatMASK],0x0000FFFF
  459.     mov   [fs_type],16         ; Fat16
  460.     call  free_hd_channel
  461.     mov   [hd1_status],0        ; free
  462.     ret
  463.