Subversion Repositories Kolibri OS

Rev

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

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