Subversion Repositories Kolibri OS

Rev

Rev 649 | 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: 709 $
  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, 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. ;***************************************************************************
  82. ; End place
  83. ; Mario79
  84. ;***************************************************************************
  85. endg
  86. iglobal
  87.  
  88.   partition_types:              ; list of fat16/32 partitions
  89.     db    0x04                  ; DOS: fat16 <32M
  90.     db    0x06                  ; DOS: fat16 >32M
  91.     db    0x0b                  ; WIN95: fat32
  92.     db    0x0c                  ; WIN95: fat32, LBA-mapped
  93.     db    0x0e                  ; WIN95: fat16, LBA-mapped
  94.     db    0x14                  ; Hidden DOS: fat16 <32M
  95.     db    0x16                  ; Hidden DOS: fat16 >32M
  96.     db    0x1b                  ; Hidden WIN95: fat32
  97.     db    0x1c                  ; Hidden WIN95: fat32, LBA-mapped
  98.     db    0x1e                  ; Hidden WIN95: fat16, LBA-mapped
  99.     db    0xc4                  ; DRDOS/secured: fat16 <32M
  100.     db    0xc6                  ; DRDOS/secured: fat16 >32M
  101.     db    0xcb                  ; DRDOS/secured: fat32
  102.     db    0xcc                  ; DRDOS/secured: fat32, LBA-mapped
  103.     db    0xce                  ; DRDOS/secured: fat16, LBA-mapped
  104.     db    0xd4                  ; Old Multiuser DOS secured: fat16 <32M
  105.     db    0xd6                  ; Old Multiuser DOS secured: fat16 >32M
  106.     db    0x07                  ; NTFS
  107.     db    0x27                  ; NTFS, hidden
  108.   partition_types_end:
  109.  
  110.  
  111.   extended_types:               ; list of extended partitions
  112.     db    0x05                  ; DOS: extended partition
  113.     db    0x0f                  ; WIN95: extended partition, LBA-mapped
  114.     db    0xc5                  ; DRDOS/secured: extended partition
  115.     db    0xd5                  ; Old Multiuser DOS secured: extended partition
  116.   extended_types_end:
  117.  
  118. endg
  119.  
  120. ; Partition chain used:
  121. ; MBR        ;   PARTITION2 ;   PARTITION3 ;   PARTITION4
  122. ;==========================================================
  123. ; fat16/32   +-- fat16/32   +-- fat16/32   +-- fat16/32   +--
  124. ; extended --+   extended --+   extended --+   extended --+
  125. ; 0              0              0              0
  126. ; 0              0              0              0
  127. ; Notes:
  128. ; - extended partition need to be in second entry on table
  129. ; - it will skip over removed partitions
  130.  
  131. set_FAT32_variables:
  132.     mov   [problem_partition],0
  133.     call  reserve_hd1
  134.     call  reserve_hd_channel
  135.  
  136.     pushad
  137.  
  138.     cmp   dword [hdpos],0
  139.     je    problem_hd
  140.  
  141.     xor   ecx,ecx               ; partition count
  142.     mov   edx,-1                ; flag for partition
  143.     xor   eax,eax               ; read MBR
  144.     xor   ebp,ebp               ; extended partition start
  145.  
  146. new_partition:
  147.     test  ebp,ebp               ; is there extended partition?
  148.     jnz   extended_already_set  ; yes
  149.     xchg  ebp,eax               ; no. set it now
  150.  
  151. extended_already_set:
  152.     add   eax,ebp               ; mbr=mbr+0, ext_part=ext_start+relat_start
  153.     mov   ebx,buffer
  154.     call  hd_read
  155.     cmp  [hd_error],0
  156.     jne  problem_hd
  157.  
  158.     cmp   word [ebx+0x1fe],0xaa55 ; is it valid boot sector?
  159.     jnz   end_partition_chain
  160.     cmp   dword [ebx+0x1be+0xc],0 ; skip over empty partition
  161. ;    jz    next_partition
  162.     jnz    .next_primary_partition
  163.     cmp   dword [ebx+0x1be+0xc+16],0
  164.     jnz    next_primary_partition
  165.     cmp   dword [ebx+0x1be+0xc+16+16],0
  166.     jnz    next_primary_partition_1
  167.     cmp   dword [ebx+0x1be+0xc+16+16+16],0
  168.     jnz    next_primary_partition_2
  169.     jmp   next_partition
  170.    
  171. .next_primary_partition:
  172.     push  eax
  173.     mov   al,[ebx+0x1be+4]      ; get primary partition type
  174.     call  scan_partition_types
  175.     pop   eax
  176.     jnz   next_primary_partition        ; no. skip over
  177.  
  178.     inc   ecx
  179.     cmp   ecx,[fat32part]       ; is it wanted partition?
  180.     jnz   next_primary_partition        ; no
  181.  
  182.         mov     edx, eax                ; start sector
  183.         add     edx, [ebx+0x1be+8]      ; add relative start
  184.         push    edx
  185.         add     edx, [ebx+0x1be+12]     ; add length
  186.         dec     edx                     ; PARTITION_END is inclusive
  187.         mov     [PARTITION_END], edx    ; note that this can be changed
  188.                                         ; when file system data will be available
  189.         mov     dl, [ebx+0x1be+4]
  190.         mov     [fs_type], dl           ; save for FS recognizer (separate FAT vs NTFS)
  191.         pop     edx
  192.  
  193. next_primary_partition:
  194.     push  eax
  195.     mov   al,[ebx+0x1be+4+16]      ; get primary partition type
  196.     call  scan_partition_types
  197.     pop   eax
  198.     jnz   next_primary_partition_1        ; no. skip over
  199.  
  200.     inc   ecx
  201.     cmp   ecx,[fat32part]       ; is it wanted partition?
  202.     jnz   next_primary_partition_1        ; no
  203.  
  204.         mov     edx, eax
  205.         add     edx, [ebx+0x1be+8+16]
  206.         push    edx
  207.         add     edx, [ebx+0x1be+12+16]
  208.         dec     edx
  209.         mov     [PARTITION_END], edx
  210.         mov     dl, [ebx+0x1be+4+16]
  211.         mov     [fs_type], dl
  212.         pop     edx
  213.  
  214. next_primary_partition_1:
  215.     push  eax
  216.     mov   al,[ebx+0x1be+4+16+16]      ; get primary partition type
  217.     call  scan_partition_types
  218.     pop   eax
  219.     jnz   next_primary_partition_2        ; no. skip over
  220.  
  221.     inc   ecx
  222.     cmp   ecx,[fat32part]       ; is it wanted partition?
  223.     jnz   next_primary_partition_2        ; no
  224.  
  225.         mov     edx, eax
  226.         add     edx, [ebx+0x1be+8+16+16]
  227.         push    edx
  228.         add     edx, [ebx+0x1be+12+16+16]
  229.         dec     edx
  230.         mov     [PARTITION_END], edx
  231.         mov     dl, [ebx+0x1be+4+16+16]
  232.         mov     [fs_type], dl
  233.         pop     edx
  234.  
  235. next_primary_partition_2:
  236.     push  eax
  237.     mov   al,[ebx+0x1be+4+16+16+16]      ; get primary partition type
  238.     call  scan_partition_types
  239.     pop   eax
  240.     jnz   next_partition        ; no. skip over
  241.  
  242.     inc   ecx
  243.     cmp   ecx,[fat32part]       ; is it wanted partition?
  244.     jnz   next_partition        ; no
  245.  
  246.         mov     edx, eax
  247.         add     edx, [ebx+0x1be+8+16+16+16]
  248.         push    edx
  249.         add     edx, [ebx+0x1be+12+16+16+16]
  250.         dec     edx
  251.         mov     [PARTITION_END], edx
  252.         mov     dl, [ebx+0x1be+4+16+16+16]
  253.         mov     [fs_type], dl
  254.         pop     edx
  255.  
  256. next_partition:
  257.     push  eax
  258.     mov   al,[ebx+0x1be+4]   ; get extended partition type
  259.     call  scan_extended_types
  260.     pop   eax
  261.     jnz   next_partition_1
  262.  
  263.     mov   eax,[ebx+0x1be+8]     ; add relative start
  264.     test  eax,eax               ; is there extended partition?
  265.     jnz   new_partition         ; yes. read it
  266.  
  267. next_partition_1:
  268.     push  eax
  269.     mov   al,[ebx+0x1be+4+16]   ; get extended partition type
  270.     call  scan_extended_types
  271.     pop   eax
  272.     jnz   next_partition_2
  273.  
  274.     mov   eax,[ebx+0x1be+8+16]     ; add relative start
  275.     test  eax,eax               ; is there extended partition?
  276.     jnz   new_partition         ; yes. read it
  277.  
  278. next_partition_2:
  279.     push  eax
  280.     mov   al,[ebx+0x1be+4+16+16]   ; get extended partition type
  281.     call  scan_extended_types
  282.     pop   eax
  283.     jnz   next_partition_3
  284.  
  285.     mov   eax,[ebx+0x1be+8+16+16]     ; add relative start
  286.     test  eax,eax               ; is there extended partition?
  287.     jnz   new_partition         ; yes. read it
  288.    
  289. next_partition_3:
  290.     push  eax
  291.     mov   al,[ebx+0x1be+4+16+16+16]   ; get extended partition type
  292.     call  scan_extended_types
  293.     pop   eax
  294.     jnz   end_partition_chain   ; no. end chain
  295.  
  296.     mov   eax,[ebx+0x1be+8+16+16+16]  ; get start of extended partition
  297.     test  eax,eax               ; is there extended partition?
  298.     jnz   new_partition         ; yes. read it
  299.    
  300. end_partition_chain:
  301.     mov   [partition_count],ecx
  302.  
  303.     cmp   edx,-1                ; found wanted partition?
  304.     jnz   hd_and_partition_ok   ; yes. install it
  305.     jmp   problem_partition_or_fat
  306.  
  307. scan_partition_types:
  308.     push  ecx
  309.     mov   edi,partition_types
  310.     mov   ecx,partition_types_end-partition_types
  311.     cld
  312.     repne scasb                 ; is partition type ok?
  313.     pop   ecx
  314.     ret
  315.  
  316. scan_extended_types:
  317.     push  ecx
  318.     mov   edi,extended_types
  319.     mov   ecx,extended_types_end-extended_types
  320.     cld
  321.     repne scasb                 ; is it extended partition?
  322.     pop   ecx
  323.     ret
  324.  
  325. problem_fat_dec_count:          ; bootsector is missing or another problem
  326.     dec   [partition_count]     ; remove it from partition_count
  327.  
  328. problem_partition_or_fat:
  329. problem_hd:
  330.     popad
  331.  
  332.     mov   [fs_type],0
  333.     call  free_hd_channel
  334.     mov   [hd1_status],0        ; free
  335.     mov   [problem_partition],1
  336.     ret
  337.  
  338. hd_and_partition_ok:
  339.     mov   eax,edx
  340.     mov   [PARTITION_START],eax
  341.         mov     edx, [PARTITION_END]
  342.         sub     edx, eax
  343.         inc     edx     ; edx = length of partition
  344.  
  345. ;    mov   [hd_setup],1
  346.     mov   ebx,buffer
  347.     call  hd_read               ; read boot sector of partition
  348.         cmp     [hd_error], 0
  349.         jz      boot_read_ok
  350.         cmp     [fs_type], 7
  351.         jnz     problem_fat_dec_count
  352. ; NTFS duplicates bootsector:
  353. ; NT4/2k/XP+ saves bootsector copy in the end of disk
  354. ; NT 3.51 saves bootsector copy in the middle of disk
  355.         and     [hd_error], 0
  356.         mov     eax, [PARTITION_END]
  357.         call    hd_read
  358.         cmp     [hd_error], 0
  359.         jnz     @f
  360.         call    ntfs_test_bootsec
  361.         jnc     boot_read_ok
  362. @@:
  363.         and     [hd_error], 0
  364.         mov     eax, edx
  365.         shr     eax, 1
  366.         add     eax, [PARTITION_START]
  367.         call    hd_read
  368.         cmp     [hd_error], 0
  369.         jnz     problem_fat_dec_count   ; ­¥ áã¤ì¡ ...
  370. boot_read_ok:
  371. ;        mov     [hd_setup], 0
  372. ; if we are running on NTFS, check bootsector
  373. ;        cmp     [fs_type], 7
  374. ;        jz      ntfs_setup
  375.         call    ntfs_test_bootsec
  376.         jnc     ntfs_setup
  377.  
  378.     cmp   word [ebx+0x1fe],0xaa55 ; is it valid boot sector?
  379.     jnz   problem_fat_dec_count
  380.  
  381.     movzx eax,word [ebx+0xe]    ; sectors reserved
  382.     add   eax,[PARTITION_START]
  383.     mov   [FAT_START],eax       ; fat_start = partition_start + reserved
  384.  
  385.     movzx eax,byte [ebx+0xd]    ; sectors per cluster
  386.     mov   [SECTORS_PER_CLUSTER],eax
  387.  
  388.     movzx ecx,word [ebx+0xb]    ; bytes per sector
  389.     mov   [BYTES_PER_SECTOR],ecx
  390.  
  391.     movzx eax,word [ebx+0x11]   ; count of rootdir entries (=0 fat32)
  392.     mov   edx,32
  393.     mul   edx
  394.     dec   ecx
  395.     add   eax,ecx               ; round up if not equal count
  396.     inc   ecx                   ; bytes per sector
  397.     div   ecx
  398.     mov   [ROOT_SECTORS],eax    ; count of rootdir sectors
  399.  
  400.     movzx eax,word [ebx+0x16]   ; sectors per fat <65536
  401.     test  eax,eax
  402.     jnz   fat16_fatsize
  403.     mov   eax,[ebx+0x24]        ; sectors per fat
  404.   fat16_fatsize:
  405.     mov   [SECTORS_PER_FAT],eax
  406.  
  407.     movzx eax,byte [ebx+0x10]   ; number of fats
  408.     test  eax,eax               ; if 0 it's not fat partition
  409.     jz    problem_fat_dec_count
  410.     mov   [NUMBER_OF_FATS],eax
  411.     imul  eax,[SECTORS_PER_FAT]
  412.     add   eax,[FAT_START]
  413.     mov   [ROOT_START],eax      ; rootdir = fat_start + fat_size * fat_count
  414.     add   eax,[ROOT_SECTORS]    ; rootdir sectors should be 0 on fat32
  415.     mov   [DATA_START],eax      ; data area = rootdir + rootdir_size
  416.  
  417.     movzx eax,word [ebx+0x13]   ; total sector count <65536
  418.     test  eax,eax
  419.     jnz   fat16_total
  420.     mov   eax,[ebx+0x20]        ; total sector count
  421.   fat16_total:
  422.     add   eax,[PARTITION_START]
  423.     dec   eax
  424.     mov   [PARTITION_END],eax
  425.     inc   eax
  426.     sub   eax,[DATA_START]      ; eax = count of data sectors
  427.     xor   edx,edx
  428.     div   dword [SECTORS_PER_CLUSTER]
  429.     inc   eax
  430.     mov   [LAST_CLUSTER],eax
  431.     dec   eax                   ; cluster count
  432.     mov   [fatStartScan],2
  433.  
  434.     ; limits by Microsoft Hardware White Paper v1.03
  435.     cmp   eax,4085              ; 0xff5
  436.     jb    problem_fat_dec_count ; fat12 not supported
  437.     cmp   eax,65525             ; 0xfff5
  438.     jb    fat16_partition
  439.  
  440. fat32_partition:
  441.     mov   eax,[ebx+0x2c]        ; rootdir cluster
  442.     mov   [ROOT_CLUSTER],eax
  443.     movzx eax,word [ebx+0x30]   ; fs info sector
  444.     add   eax,[PARTITION_START]
  445.     mov   [ADR_FSINFO],eax
  446.     call  hd_read
  447.     mov   eax,[ebx+0x1ec]
  448.     cmp   eax,-1
  449.     jz    @f
  450.     mov   [fatStartScan],eax
  451. @@:
  452.  
  453.     popad
  454.  
  455.     mov   [fatRESERVED],0x0FFFFFF6
  456.     mov   [fatBAD],0x0FFFFFF7
  457.     mov   [fatEND],0x0FFFFFF8
  458.     mov   [fatMASK],0x0FFFFFFF
  459.     mov   [fs_type],32         ; Fat32
  460.     call  free_hd_channel
  461.     mov   [hd1_status],0        ; free
  462.     ret
  463.  
  464. fat16_partition:
  465.     xor   eax,eax
  466.     mov   [ROOT_CLUSTER],eax
  467.  
  468.     popad
  469.  
  470.     mov   [fatRESERVED],0x0000FFF6
  471.     mov   [fatBAD],0x0000FFF7
  472.     mov   [fatEND],0x0000FFF8
  473.     mov   [fatMASK],0x0000FFFF
  474.     mov   [fs_type],16         ; Fat16
  475.     call  free_hd_channel
  476.     mov   [hd1_status],0        ; free
  477.     ret
  478.