Subversion Repositories Kolibri OS

Rev

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

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