Subversion Repositories Kolibri OS

Rev

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