Subversion Repositories Kolibri OS

Rev

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

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