Subversion Repositories Kolibri OS

Rev

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

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