Subversion Repositories Kolibri OS

Rev

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