Subversion Repositories Kolibri OS

Rev

Rev 649 | 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: 709 $
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
256 diamond 29
fs_type              db 0       ; 0=none, 1=NTFS, 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!
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
79
end virtual
80
 
65 mario79 81
;***************************************************************************
82
; End place
83
; Mario79
84
;***************************************************************************
277 diamond 85
endg
86
iglobal
65 mario79 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
256 diamond 106
    db    0x07                  ; NTFS
709 diamond 107
    db    0x27                  ; NTFS, hidden
65 mario79 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
321 diamond 134
    call  reserve_hd_channel
65 mario79 135
 
709 diamond 136
    pushad
137
 
65 mario79 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
74 mario79 155
    cmp  [hd_error],0
156
    jne  problem_hd
65 mario79 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
578 mario79 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:
65 mario79 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
 
256 diamond 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
 
65 mario79 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
 
256 diamond 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
65 mario79 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
 
256 diamond 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
65 mario79 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
 
256 diamond 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
65 mario79 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:
709 diamond 329
problem_hd:
65 mario79 330
    popad
331
 
256 diamond 332
    mov   [fs_type],0
321 diamond 333
    call  free_hd_channel
65 mario79 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
256 diamond 341
        mov     edx, [PARTITION_END]
342
        sub     edx, eax
343
        inc     edx     ; edx = length of partition
65 mario79 344
 
256 diamond 345
;    mov   [hd_setup],1
65 mario79 346
    mov   ebx,buffer
347
    call  hd_read               ; read boot sector of partition
256 diamond 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
709 diamond 373
;        cmp     [fs_type], 7
374
;        jz      ntfs_setup
375
        call    ntfs_test_bootsec
376
        jnc     ntfs_setup
74 mario79 377
 
65 mario79 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
649 diamond 432
    mov   [fatStartScan],2
65 mario79 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
649 diamond 446
    call  hd_read
447
    mov   eax,[ebx+0x1ec]
448
    cmp   eax,-1
449
    jz    @f
450
    mov   [fatStartScan],eax
451
@@:
65 mario79 452
 
453
    popad
454
 
455
    mov   [fatRESERVED],0x0FFFFFF6
456
    mov   [fatBAD],0x0FFFFFF7
457
    mov   [fatEND],0x0FFFFFF8
458
    mov   [fatMASK],0x0FFFFFFF
256 diamond 459
    mov   [fs_type],32         ; Fat32
321 diamond 460
    call  free_hd_channel
65 mario79 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
256 diamond 474
    mov   [fs_type],16         ; Fat16
321 diamond 475
    call  free_hd_channel
65 mario79 476
    mov   [hd1_status],0        ; free
477
    ret