Subversion Repositories Kolibri OS

Rev

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

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