Subversion Repositories Kolibri OS

Rev

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

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