Subversion Repositories Kolibri OS

Rev

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