Subversion Repositories Kolibri OS

Rev

Rev 1378 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
431 serge 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
 
593 mikedld 8
$Revision: 1379 $
9
 
10
 
65 mario79 11
;*************************************************************
578 mario79 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
65 mario79 17
;*************************************************************
18
 
277 diamond 19
uglobal
65 mario79 20
align 4
256 diamond 21
 
65 mario79 22
;******************************************************
431 serge 23
; Please do not change this place - variables  in text
65 mario79 24
; Mario79
25
; START place
26
;******************************************************
27
PARTITION_START      dd 0x3f
28
PARTITION_END        dd 0
1378 turbanoff 29
fs_type              db 0       ; 0=none, 1=NTFS, 2=EXT2/3, 16=FAT16, 32=FAT32
277 diamond 30
align 4
256 diamond 31
 
32
fs_dependent_data_start:
33
; FATxx data
34
 
65 mario79 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
 
649 diamond 52
fatStartScan         dd 2
53
 
256 diamond 54
fs_dependent_data_end:
321 diamond 55
file_system_data_size = $ - PARTITION_START
56
if file_system_data_size > 96
57
ERROR: sizeof(file system data) too big!
1379 turbanoff 58
end if
256 diamond 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
1379 turbanoff 79
end virtual
80
 
1378 turbanoff 81
virtual at fs_dependent_data_start
82
; EXT2 data
83
ext2_data:
1379 turbanoff 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 на глобальную процедуру
1378 turbanoff 97
    .ext2_temp_inode                dd ?    ; inode для мелких процедур
98
if $ > fs_dependent_data_end
99
ERROR: increase sizeof(fs_dependent_data)!
100
end if
256 diamond 101
end virtual
1379 turbanoff 102
 
65 mario79 103
;***************************************************************************
104
; End place
105
; Mario79
106
;***************************************************************************
277 diamond 107
endg
108
iglobal
65 mario79 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
256 diamond 128
    db    0x07                  ; NTFS
1379 turbanoff 129
    db    0x27                  ; NTFS, hidden
1378 turbanoff 130
    db    0x83                  ; Linux native file system (ext2fs)
65 mario79 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:
1379 turbanoff 144
; MBR <---------------------
145
; |                         |
146
; |-> PARTITION1          |
147
; |-> EXTENDED PARTITION -        ;not need be second partition
148
; |-> PARTITION3
149
; |-> PARTITION4
150
 
1378 turbanoff 151
set_PARTITION_variables:
152
set_FAT32_variables:        ;deprecated
65 mario79 153
    mov   [problem_partition],0
154
    call  reserve_hd1
321 diamond 155
    call  reserve_hd_channel
65 mario79 156
 
709 diamond 157
    pushad
158
 
65 mario79 159
    cmp   dword [hdpos],0
160
    je    problem_hd
161
 
162
    xor   ecx,ecx               ; partition count
1378 turbanoff 163
    or    edx,-1                ; flag for partition
164
    xor   eax,eax               ; address MBR
65 mario79 165
    xor   ebp,ebp               ; extended partition start
166
 
1378 turbanoff 167
new_mbr:
168
    test  ebp,ebp               ; is there extended partition? (MBR or EMBR)
65 mario79 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
74 mario79 176
    cmp  [hd_error],0
177
    jne  problem_hd
65 mario79 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
1378 turbanoff 182
    jnz    test_primary_partition_0
578 mario79 183
    cmp   dword [ebx+0x1be+0xc+16],0
1378 turbanoff 184
    jnz    test_primary_partition_1
578 mario79 185
    cmp   dword [ebx+0x1be+0xc+16+16],0
1378 turbanoff 186
    jnz    test_primary_partition_2
578 mario79 187
    cmp   dword [ebx+0x1be+0xc+16+16+16],0
1378 turbanoff 188
    jnz    test_primary_partition_3
189
    jmp   end_partition_chain
190
 
191
test_primary_partition_0:
65 mario79 192
    push  eax
193
    mov   al,[ebx+0x1be+4]      ; get primary partition type
194
    call  scan_partition_types
195
    pop   eax
1378 turbanoff 196
    jnz   test_primary_partition_1      ; no. skip over
65 mario79 197
 
198
    inc   ecx
1378 turbanoff 199
    cmp   ecx,[known_part]       ; is it wanted partition?
200
    jnz   test_primary_partition_1      ; no
65 mario79 201
 
256 diamond 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
 
1378 turbanoff 213
test_primary_partition_1:
65 mario79 214
    push  eax
215
    mov   al,[ebx+0x1be+4+16]      ; get primary partition type
216
    call  scan_partition_types
217
    pop   eax
1378 turbanoff 218
    jnz   test_primary_partition_2        ; no. skip over
65 mario79 219
 
220
    inc   ecx
1378 turbanoff 221
    cmp   ecx,[known_part]       ; is it wanted partition?
222
    jnz   test_primary_partition_2        ; no
65 mario79 223
 
256 diamond 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
65 mario79 233
 
1378 turbanoff 234
test_primary_partition_2:
65 mario79 235
    push  eax
236
    mov   al,[ebx+0x1be+4+16+16]      ; get primary partition type
237
    call  scan_partition_types
238
    pop   eax
1378 turbanoff 239
    jnz   test_primary_partition_3        ; no. skip over
65 mario79 240
 
241
    inc   ecx
1378 turbanoff 242
    cmp   ecx,[known_part]       ; is it wanted partition?
243
    jnz   test_primary_partition_3        ; no
65 mario79 244
 
256 diamond 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
65 mario79 254
 
1378 turbanoff 255
test_primary_partition_3:
65 mario79 256
    push  eax
257
    mov   al,[ebx+0x1be+4+16+16+16]      ; get primary partition type
258
    call  scan_partition_types
259
    pop   eax
1378 turbanoff 260
    jnz   test_ext_partition_0        ; no. skip over
65 mario79 261
 
262
    inc   ecx
1378 turbanoff 263
    cmp   ecx,[known_part]       ; is it wanted partition?
264
    jnz   test_ext_partition_0  ; no
65 mario79 265
 
256 diamond 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
65 mario79 275
 
1378 turbanoff 276
test_ext_partition_0:
65 mario79 277
    push  eax
278
    mov   al,[ebx+0x1be+4]   ; get extended partition type
279
    call  scan_extended_types
280
    pop   eax
1378 turbanoff 281
    jnz   test_ext_partition_1
65 mario79 282
 
283
    mov   eax,[ebx+0x1be+8]     ; add relative start
284
    test  eax,eax               ; is there extended partition?
1378 turbanoff 285
    jnz   new_mbr               ; yes. read it
65 mario79 286
 
1378 turbanoff 287
test_ext_partition_1:
65 mario79 288
    push  eax
289
    mov   al,[ebx+0x1be+4+16]   ; get extended partition type
290
    call  scan_extended_types
291
    pop   eax
1378 turbanoff 292
    jnz   test_ext_partition_2
65 mario79 293
 
1378 turbanoff 294
    mov   eax,[ebx+0x1be+8+16]  ; add relative start
65 mario79 295
    test  eax,eax               ; is there extended partition?
1378 turbanoff 296
    jnz   new_mbr               ; yes. read it
65 mario79 297
 
1378 turbanoff 298
test_ext_partition_2:
65 mario79 299
    push  eax
300
    mov   al,[ebx+0x1be+4+16+16]   ; get extended partition type
301
    call  scan_extended_types
302
    pop   eax
1378 turbanoff 303
    jnz   test_ext_partition_3
65 mario79 304
 
305
    mov   eax,[ebx+0x1be+8+16+16]     ; add relative start
306
    test  eax,eax               ; is there extended partition?
1378 turbanoff 307
    jnz   new_mbr               ; yes. read it
308
 
309
test_ext_partition_3:
65 mario79 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?
1378 turbanoff 318
    jnz   new_mbr               ; yes. read it
319
 
65 mario79 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:
709 diamond 349
problem_hd:
65 mario79 350
    popad
351
 
256 diamond 352
    mov   [fs_type],0
321 diamond 353
    call  free_hd_channel
65 mario79 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
256 diamond 361
        mov     edx, [PARTITION_END]
362
        sub     edx, eax
363
        inc     edx     ; edx = length of partition
65 mario79 364
 
256 diamond 365
;    mov   [hd_setup],1
65 mario79 366
    mov   ebx,buffer
367
    call  hd_read               ; read boot sector of partition
256 diamond 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
1378 turbanoff 389
        jnz     problem_fat_dec_count   ; no chance...
256 diamond 390
boot_read_ok:
1378 turbanoff 391
 
256 diamond 392
; if we are running on NTFS, check bootsector
74 mario79 393
 
1378 turbanoff 394
        call    ntfs_test_bootsec      ; test ntfs
1379 turbanoff 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
1378 turbanoff 403
        jnz	problem_fat_dec_count
404
 
65 mario79 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
1190 diamond 413
    test  eax,eax
414
    jz    problem_fat_dec_count
65 mario79 415
    mov   [SECTORS_PER_CLUSTER],eax
416
 
417
    movzx ecx,word [ebx+0xb]    ; bytes per sector
1191 diamond 418
    cmp   ecx,0x200
1190 diamond 419
    jnz   problem_fat_dec_count
65 mario79 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
649 diamond 463
    mov   [fatStartScan],2
65 mario79 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
649 diamond 477
    call  hd_read
478
    mov   eax,[ebx+0x1ec]
479
    cmp   eax,-1
480
    jz    @f
481
    mov   [fatStartScan],eax
482
@@:
65 mario79 483
 
484
    popad
485
 
486
    mov   [fatRESERVED],0x0FFFFFF6
487
    mov   [fatBAD],0x0FFFFFF7
488
    mov   [fatEND],0x0FFFFFF8
489
    mov   [fatMASK],0x0FFFFFFF
256 diamond 490
    mov   [fs_type],32         ; Fat32
321 diamond 491
    call  free_hd_channel
65 mario79 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
256 diamond 505
    mov   [fs_type],16         ; Fat16
321 diamond 506
    call  free_hd_channel
65 mario79 507
    mov   [hd1_status],0        ; free
1379 turbanoff 508
    ret