source: trunk/bootcode/regular/partscan.asm@ 171

Last change on this file since 171 was 171, checked in by Ben Rietbroek, 8 years ago

Ignore LARGE FLOPPY removables -- NOT BULLET PROOF YET! [v1.1.1-testing]

A LARGE FLOPPY will have a BPB instead of an MBR and chances are that
the MBR boot-flag locations contain values other than 00h or 80h.
The method implemented here needs to be improved but may catch most
LARGE FLOPPY formatted disks. Especially those with text in the PT area,
which is where AiR-BOOT choked on. LARGE FLOPPIES with a BPB but ZEROS
in the PT area should be OK for AiR-BOOT.

CAUTION:
This is a testbuild !
AirBoot uses the BIOS to access disks and a small coding error can trash
partition tables or other vital disk structures. You are advised to make
backups of TRACK0 and EBRs before using this testbuild. More info at:
https://rousseaux.github.io/netlabs.air-boot/pdf/AirBoot-v1.1.0-manual.pdf

File size: 43.6 KB
Line 
1; AiR-BOOT (c) Copyright 1998-2008 M. Kiewitz
2;
3; This file is part of AiR-BOOT
4;
5; AiR-BOOT is free software: you can redistribute it and/or modify it under
6; the terms of the GNU General Public License as published by the Free
7; Software Foundation, either version 3 of the License, or (at your option)
8; any later version.
9;
10; AiR-BOOT is distributed in the hope that it will be useful, but WITHOUT ANY
11; WARRANTY: without even the implied warranty of MERCHANTABILITY or FITNESS
12; FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13; details.
14;
15; You should have received a copy of the GNU General Public License along with
16; AiR-BOOT. If not, see <http://www.gnu.org/licenses/>.
17;
18;---------------------------------------------------------------------------
19; AiR-BOOT / PARTiTiON SCANNING
20;---------------------------------------------------------------------------
21
22
23IFDEF MODULE_NAMES
24DB 'PARTSCAN',0
25ENDIF
26
27; Note: This is complex code. So make sure that you know what you are doing in
28; here.
29
30PARTSCAN_ScanForPartitions Proc Near
31
32IFDEF AUX_DEBUG
33 IF 1
34 DBG_TEXT_OUT_AUX 'PARTSCAN_ScanForPartitions:'
35 PUSHRF
36 ;~ call DEBUG_DumpRegisters
37 ;~ call AuxIO_DumpParagraph
38 ;~ call AuxIO_TeletypeNL
39 POPRF
40 ENDIF
41ENDIF
42
43 ; Reset X-Reference
44 call PARTSCAN_ResetXref
45
46 mov dh, [TotalHarddiscs]
47 xor al, al
48 mov [NewPartitions], al
49
50 mov byte ptr [CurIO_Scanning], 1 ; Set flag due scanning partitions
51 mov dl, 80h ; Is first harddisc
52 PSSFP_HarddiscLoop:
53
54
55
56; ========================================================= [ Scan Partitions ]
57
58
59 ; Save BIOS disk number
60 push dx
61
62 ;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
63 ;!! THIS IS WHERE WE TRY TO DETECT LARGE FLOPPIES !
64 ;!! ---------------------------------------------------------------
65 ;!! This is a quick hack to ignore LARGE FLOPPY removable media.
66 ;!! With LARGE FLOPPY, the boot record will be a BPB instead of
67 ;!! an MBR. To distinguish, it is assumed that the MBR bootable
68 ;!! flag is either 00h or 80h. LARGE FLOPPIES will often have
69 ;!! other values there. So, the block below tests if all 4 entries
70 ;!! result in 0 when first ored together and then anded with 7fh.
71 ;!!
72 ;!! THIS IS NOT BULLET PROOF AND WILL BE ENHANCED IN THE FUTURE
73 ;!!
74 ;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
75
76 ; Push the whole shebang
77 pusha
78
79 ; Check if this is a removable drive
80 call DriveIO_CalcDiskInfoPointer ; Pointer to DISKINFO
81 mov ax, [bx+LocDISKINFO_I13X_Flags] ; Get INT13X flags
82 test ax, 04h ; Bit 3=1 if removable
83 clc ; Assume fixed
84
85 ; Fixed drive, so skip further checking for LARGE FLOPPY.
86 ; We *DO* halt on broken partition tables !
87 ; This is needed because AiR-BOOT cannot continue with broken
88 ; tables on truly partitioned disks.
89 je @F
90
91
92 ; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
93 ; !! THE DISK IS A REMOVABLE !
94 ; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
95
96
97IFDEF AUX_DEBUG
98 IF 0
99 DBG_TEXT_OUT_AUX 'test bigflop'
100 PUSHRF
101 ;~ call DEBUG_DumpRegisters
102 ;~ call AuxIO_DumpParagraph
103 ;~ call AuxIO_TeletypeNL
104 POPRF
105 ENDIF
106ENDIF
107
108 ; If it has LVM info, it must be partitioned and thus OK
109 mov al, [bx+LocDISKINFO_LVM_Secs] ; Get LVM_SPT
110 test al, al ; See if 0
111 clc ; Assume OK
112 jne @F ; LVM_SPT present, OK
113
114 ; Now load its boot sector and see if AiR-BOOT is there, if so, OK
115 mov si, offset [Scratch] ; Pointer to sector buffer
116 call DriveIO_LoadMBR ; Load it
117 test al, 08h ; AiR-BOOT signature found ?
118 clc ; Assume OK
119 jne @F ; AB found, must be partitioned
120
121 ; A zero sector is also OK -- ready to be partitioned by OS/2 ;)
122 call IsSectorBufferZero ; check if sector is all zeros
123 clc ; Assume OK
124 je @F ; Zero sector, OK
125
126 ; !! NOW WE TEST MBR BOOT FLAGS.
127 ; !! MOST LARGE FLOPPIES WILL HAVE DATA THERE.
128 ; !! NOT BULLET PROOF, NEEDS TO BE IMPROVED.
129 xor ax, ax ; Clear for oring and anding
130 add si, 01beh ; Advance to partition table
131 mov cx, 4 ; Four entries to test
132 cld ; Load upwards
133 __nxt:
134 lodsb ; Load Boot Flag (00h OR 80h)
135 or ah, al ; Merge all bits to AH
136 add si, 16 ; Point to next entry
137 loop __nxt ; Again if still entries to test
138
139 ; A LARGE FLOPPY with 00h or 80h bytes at these 4 locations
140 ; will PASS !!
141 and ah, 7fh ; Strip of potential Boot Flag
142 clc ; Assume OK
143 jz @F ; Good indication this is NOT a BPB, but...
144
145
146 ;!! The Boot Flag bytes were NOT either 00h or 80h, so this is
147 ;!! definintly not a partitioned disk.
148 ;!! SET CY TO INDICATE SKIPPING 'PARTSCAN_ScanDriveForPartitions'
149 stc
150
151 ; End of LARGE FLOPPY test
152 @@:
153
154 ; Restore the whole shebang
155 popa
156
157 ; CARRY IS SET, LARGE FLOPPY OR WHAT -- SKIP IT !!
158 jc @F
159
160 ; This disk should be partitioned, so scan it.
161 ; Broken partitions *DOS* halt AiR-BOOT !
162 call PARTSCAN_ScanDriveForPartitions
163
164 @@:
165
166
167 pop dx
168 inc dl
169 dec dh
170 jnz PSSFP_HarddiscLoop
171 mov byte ptr [CurIO_Scanning], 0 ; Reset flag due scanning complete
172
173IFDEF AUX_DEBUG
174 IF 0
175 PUSHRF
176 call DEBUG_DumpHidePartTables
177 POPRF
178 ENDIF
179ENDIF
180
181 ; Use X-Reference to sync NewPartitionTable with Hide-Config
182 call PARTSCAN_SyncHideConfigWithXref
183
184IFDEF AUX_DEBUG
185 IF 0
186 PUSHRF
187 call DEBUG_DumpHidePartTables
188 POPRF
189 ENDIF
190ENDIF
191
192 ; Now we copy the new IPT over the old one...
193 mov si, offset [NewPartTable]
194 mov di, offset [PartitionTable]
195 ;movzx ax, NewPartitions
196 mov al,NewPartitions
197 mov ah,0
198
199 mov CFG_Partitions, al
200 mov bl, LocIPT_LenOfIPT
201 mul bl
202 mov cx, ax
203 rep movsb
204
205 ; and the New Logical Drive Letter table as well...
206 mov si, offset [NewDriveLetters]
207 mov di, offset [DriveLetters]
208 mov cx, LocIPT_MaxPartitions
209 rep movsb
210
211 ; ...and finally check, if we need to set a Drive-Letter
212 mov dl, [AutoDrvLetter]
213 or dl, dl
214 jz PSSFP_NoAutoDriveLetter
215 ;movzx cx, CFG_Partitions
216 mov cl, [CFG_Partitions]
217 mov ch,0
218
219 or cx, cx
220 jz PSSFP_NoAutoDriveLetter
221 mov si, offset [PartitionTable]
222 mov di, offset [DriveLetters]
223 mov ax, word ptr [AutoDrvLetterSerial+00h]
224 mov bx, word ptr [AutoDrvLetterSerial+02h]
225 PSSFP_AutoDrvLetterLoop:
226 cmp ax, [si+LocIPT_Serial]
227 jne PSSFP_AutoDrvLetterNoMatch
228 cmp bx, [si+LocIPT_Serial+2]
229 jne PSSFP_AutoDrvLetterNoMatch
230 ; We got a match, so set Drive-Letter in DL
231 or bptr [si+LocIPT_Flags], Flags_DriveLetter
232 mov [di], dl
233 PSSFP_AutoDrvLetterNoMatch:
234 add si, LocIPT_LenOfIPT
235 inc di
236 loop PSSFP_AutoDrvLetterLoop
237 mov byte ptr [AutoDrvLetter], 0 ; Disable after processing...
238 PSSFP_NoAutoDriveLetter:
239 ret
240PARTSCAN_ScanForPartitions EndP
241
242
243
244;
245; This function reconnects a forced drive-letter with it's partition
246; when partitions are removed.
247;
248PARTSCAN_UpdateDriveLetters Proc
249
250IFDEF AUX_DEBUG
251 IF 0
252 DBG_TEXT_OUT_AUX 'PARTSCAN_UpdateDriveLetters:'
253 PUSHRF
254 ;~ call DEBUG_DumpRegisters
255 ;~ call AuxIO_DumpParagraph
256 ;~ call AuxIO_TeletypeNL
257 POPRF
258 ENDIF
259ENDIF
260
261 pusha
262 xor bx,bx ; index-pointer
263 xor cx,cx ; counter
264 xor dx,dx ; backup index-pointer
265 mov cl,LocIPT_MaxPartitions ; nr of entries to process
266 mov si,offset [PartitionXref] ; old-new relation table
267 mov di,offset [DriveLetters] ; forced drive-letters table
268
269 ;
270 ; Loop over each entry in the xref-table to see if the partition
271 ; has been removed or has been given a new index in the IPT.
272 ; A removed partition has 0ffh in it's slot and for a partition
273 ; that has a new index in the IPT the value at the slot is different
274 ; from the index of the slot in the xref-table.
275 ;
276 PARTSCAN_UpdateDriveLetters_next_entry:
277 jcxz PARTSCAN_UpdateDriveLetters_done
278 dec cl ; decrement counter
279 mov al,[si+bx] ; get possibly old index for this entry
280 mov dl,bl ; save current index
281 inc bl ; advance index-pointer
282 inc al ; 0ffh will become 0, part removed so continue
283 jz PARTSCAN_UpdateDriveLetters_next_entry
284
285 ;
286 ; If value in slot is the same as the index of the slot then
287 ; the partition has not moved in the IPT.
288 ;
289 dec al ; restore possibly out-of-date index
290 cmp al,dl ; same as array index? then ok, do next
291 je PARTSCAN_UpdateDriveLetters_next_entry
292
293;!
294;! DEBUG_PROBE
295;!
296IFDEF AUX_DEBUGx
297 push 1234h
298 call DEBUG_Probe
299ENDIF
300
301 ;
302 ; The partition has moved in the IPT so we lookup it's forced
303 ; drive-letter at the old location and put it at the new one.
304 ; The old location is identified by the index in the xref-table
305 ; and the new location is identified by the value at that index.
306 ; Thus, when no partitions have been deleted or added, the xref-table
307 ; contains the sequence 0,1,2,3,...,n,0ffh,0ffh, etc.
308 ; The value 0ffh means that no partition is using the slot.
309 ;
310 xor ah,ah ; no drive-letter
311 dec bl ; backup index-pointer one position
312 xchg ah,[di+bx] ; get drive-letter and store zero
313 xchg bl,al ; use slot value as new index
314 mov [di+bx],ah ; store drive-letter
315 xchg al,bl ; restore index-pointer
316 inc bl ; point to next entry
317 jmp PARTSCAN_UpdateDriveLetters_next_entry
318 PARTSCAN_UpdateDriveLetters_done:
319 popa
320 ret
321PARTSCAN_UpdateDriveLetters EndP
322
323
324
325
326; Scannt die Festplatte auf jegliche Partitionstabellen...
327; Falls eine fehlerhafte Partition gefunden wird, wird abgebrochen.
328; falls eine Extended Partition (DOS) gefunden wird, wird erneut gescannt.
329PARTSCAN_ScanDriveForPartitions Proc Near
330
331IFDEF AUX_DEBUG
332 IF 0
333 DBG_TEXT_OUT_AUX 'PARTSCAN_ScanDriveForPartitions:'
334 PUSHRF
335 ;~ call DEBUG_DumpRegisters
336 ;~ call AuxIO_DumpParagraph
337 ;~ call AuxIO_TeletypeNL
338 POPRF
339 ENDIF
340ENDIF
341
342 xor ax, ax
343 xor bx, bx ; Location Absoluter Sektor 0
344 mov cx, 0001h
345 xor dh, dh ; Location Zylinder 0, Side 0, Sektor 1 MBR
346 mov [ExtendedAbsPosSet], al
347 mov wptr [ExtendedAbsPos+0], ax
348 mov wptr [ExtendedAbsPos+2], ax
349 PSSDFP_LoadThisPartition:
350
351 call DriveIO_LoadPartition ; Load a partition record
352
353 jc PSSDFP_InvalidPartition
354
355 ; LVM Support - Reads LVM Information Sector
356 call DriveIO_LoadLVMSector ; Load LVM sector
357
358 call PARTSCAN_ScanPartition
359
360 call DriveIO_SavePartition
361
362 call PARTSCAN_ScanPartitionForExtended
363 jc PSSDFP_LoadThisPartition
364
365 PSSDFP_InvalidPartition:
366 ret
367PARTSCAN_ScanDriveForPartitions EndP
368
369; Scans Current Partition for Extended Partitions, if found, AX,BX,CX,DX will
370; be set to this location and Carry will be set
371PARTSCAN_ScanPartitionForExtended Proc Near Uses si
372
373IFDEF AUX_DEBUG
374 IF 0
375 DBG_TEXT_OUT_AUX 'PARTSCAN_ScanPartitionForExtended:'
376 PUSHRF
377 ;~ call DEBUG_DumpRegisters
378 ;~ call AuxIO_DumpParagraph
379 ;~ call AuxIO_TeletypeNL
380 POPRF
381 ENDIF
382ENDIF
383
384 mov si, offset PartitionSector+446 ; DS:SI - 1st partition entry
385 xor ax, ax
386 PSSPFE_ScanLoop:
387 mov al, [si+LocBRPT_SystemID]
388 cmp al, 5 ; Is Partition EXTENDED ?
389 je PSSPFE_ExtendedPartition
390 cmp al, 0Fh ; Is Partition EXTENDED (M$) ?
391 je PSSPFE_ExtendedPartition
392 jmp PSSPFE_IgnorePartition
393 PSSPFE_ExtendedPartition:
394 mov ax, wptr [si+LocBRPT_RelativeBegin]
395 mov bx, wptr [si+LocBRPT_RelativeBegin+2]
396 add ax, wptr [ExtendedAbsPos+0] ; Adjust...
397 adc bx, wptr [ExtendedAbsPos+2] ; (Shit Design!)
398 test byte ptr [ExtendedAbsPosSet], 1
399 jnz PSSPFE_ExtendedMainKnown
400 mov wptr [ExtendedAbsPos+0], ax
401 mov wptr [ExtendedAbsPos+2], bx
402 mov byte ptr [ExtendedAbsPosSet], 1
403 PSSPFE_ExtendedMainKnown:
404 mov cx, wptr [si+LocBRPT_BeginSector] ; Cylinder/Sector
405 mov dh, bptr [si+LocBRPT_BeginHead] ; Head
406 mov dl, bptr [CurPartition_Location+4] ; Drive
407 stc
408 jmp PSSPFE_EndOfSearch
409 PSSPFE_IgnorePartition:
410 add si, LocBRPT_LenOfEntry
411 cmp si, 500+offset PartitionSector
412 jb PSSPFE_ScanLoop
413 clc
414 PSSPFE_EndOfSearch:
415 ret
416PARTSCAN_ScanPartitionForExtended EndP
417
418; The following routines have NOT *DS* set to CS, so we must address via ES
419PARTSCAN_ScanPartition Proc Near Uses ax si
420
421IFDEF AUX_DEBUG
422 IF 0
423 DBG_TEXT_OUT_AUX 'PARTSCAN_ScanPartition:'
424 PUSHRF
425 ;~ call DEBUG_DumpRegisters
426 ;~ call AuxIO_DumpParagraph
427 ;~ call AuxIO_TeletypeNL
428 POPRF
429 ENDIF
430ENDIF
431
432
433 mov si, offset [PartitionSector+446] ; DS:SI - 1st Partition-Entry
434 PSSP_ScanLoop:
435 mov al, bptr [si+LocBRPT_SystemID]
436 cmp al, 5 ; Is Partition EXTENDED ?
437 je PSSP_IgnorePartition
438 cmp al, 0Fh ; Is Partition EXTENDED (M$-DOS7) ?
439 je PSSP_IgnorePartition
440 cmp al, 0 ; Is Partition EMPTY ?
441 je PSSP_IgnorePartition
442 ; Ignore these partitions, because there are no real Partitions
443
444 ;
445 ; Stop scanning if too many partitions.
446 ;
447 cmp word ptr cs:[NewPartitions],LocIPT_MaxPartitions
448 jae skip_check
449 call PARTSCAN_CheckThisPartition
450 jmp PSSP_IgnorePartition
451 skip_check:
452 ; Cannot boot LVM-Data partitions
453 pusha
454 mov byte ptr cs:[TooManyPartitions],1
455 mov cx, 0C04h
456 ;~ mov si, offset TXT_ERROR_TooManyPartitions
457 mov si, offset TXT_TooManyPartitions
458 add si,5 ; We stole this string, so skip new-line and dash.
459 ;~ call SETUP_Warning_AreYouSure
460 call SETUP_ShowErrorBox
461 popa
462
463 PSSP_IgnorePartition:
464 ; Only clear the boot-flag on the boot-disk.
465 ; Clearing the boot-flags on other disks would prevent booting them
466 ; from the BIOS. (TRAC ticket #6)
467 cmp dl, [BIOS_BootDisk] ; See if this is boot-disk
468 jne PSSP_Skip_Clear_BootFlag ; Nope, skip clear flag
469 and byte ptr [si+LocBRPT_Flags], 7Fh ; Reset the Active-Flag
470 PSSP_Skip_Clear_BootFlag:
471 add si, LocBRPT_LenOfEntry ; 16 Bytes per partition entry
472 cmp si, 500+offset PartitionSector
473 jb PSSP_ScanLoop
474 ; If we are on first HDD and in primary partition table -> mark primary
475 mov al, [BIOS_BootDisk]
476 cmp bptr [CurPartition_Location+4], al ; Drive
477 jne PSSP_NoMarkPrimary
478 cmp wptr [CurPartition_Location+0], 0
479 jne PSSP_NoMarkPrimary
480 cmp wptr [CurPartition_Location+2], 0 ; Absolute Location
481 jne PSSP_NoMarkPrimary
482 call PART_MarkFirstGoodPrimary
483 PSSP_NoMarkPrimary:
484 ret
485PARTSCAN_ScanPartition EndP
486
487MBR_NoName_Patched db 15 dup (0)
488
489; Will insert this partition into NewPartTable and compare it to our "old"
490; LocIPT-table. If the same partition is found there, Flags&CRC are taken from
491; the old table, otherwise they are generated freshly.
492; Will also fill out PartitionXref to sync HideConfig later
493; In: SI - Points to Partition-Entry (16-Bytes)
494PARTSCAN_CheckThisPartition Proc Near Uses di si
495
496 local PartSystemID:byte, PartTypeFlags:byte
497 local PartCRC:word, PartPtr:word
498
499IFDEF AUX_DEBUG
500 IF 0
501 DBG_TEXT_OUT_AUX 'PARTSCAN_CheckThisPartition:'
502 PUSHRF
503 call DEBUG_DumpRegisters
504 ;~ call AuxIO_DumpParagraph
505 ;~ call AuxIO_TeletypeNL
506 POPRF
507 ENDIF
508ENDIF
509
510
511 mov wptr [PartPtr], si ; Save Pointer to PartitionEntry
512
513 mov al, bptr [si+LocBRPT_SystemID]
514 mov PartSystemID, al
515
516 mov cx, wptr [si+LocBRPT_BeginSector] ; Cylinder/Sector
517 mov dh, bptr [si+LocBRPT_BeginHead] ; Head
518 mov dl, bptr [CurPartition_Location+4] ; Drive
519 mov ax, wptr [si+LocBRPT_RelativeBegin] ; Absolute Sector
520 mov bx, wptr [si+LocBRPT_RelativeBegin+2]
521
522 add ax, wptr [CurPartition_Location+0] ; +Partition-Absolute
523 adc bx, wptr [CurPartition_Location+2] ; sectors
524
525 ; Load the partition sector
526 mov si, offset [TmpSector]
527 call DriveIO_LoadSector
528
529 push si
530 mov bx, 4B4Dh ; Magic 'MK' :)
531 call MBR_GetCheckOfSector
532 mov PartCRC, bx ; Save Partition's-CRC
533
534 ; ------------------------------ Gets internal infos of partition type
535 mov al, PartSystemID
536 call PART_SearchFileSysName
537 ; Replies AH - FileSysFlags, AL - UnhiddenID, SI - FileSystemNamePtr
538 mov di, si
539 mov PartTypeFlags, ah
540 mov PartSystemID, al ; Use Unhidden-ID
541 pop si
542
543 ;================================
544 ; AL - File System ID (Unhidden)
545 ; AH - File System Flags
546 ; SI - Boot-Record of Partition
547 ; DI - File System Name
548 ;================================
549
550 cmp PartSystemID, 07h ; We got IFS here?
551 jne PCCTP_IFSdone
552 ; Check, if 'JFS ' is at DWORD offset 36h ; Rousseau: JFS check (LVM / IPT?)
553 cmp wptr [si+36h], 'FJ'
554 jne PCCTP_IFSnoJFS
555 cmp wptr [si+38h], ' S'
556 jne PCCTP_IFSnoJFS
557 mov PartSystemID, 0FCh ; FC is JFS internally
558 jmp PCCTP_IFSdone
559 PCCTP_IFSnoJFS:
560 ; Check, if 'HPFS' is at DWORD offset 36h
561 cmp wptr [si+36h], 'PH'
562 jne PCCTP_ProbablyNTFS
563 cmp wptr [si+38h], 'SF'
564 je PCCTP_IFSdone ; 07 is HPFS internally
565 PCCTP_ProbablyNTFS:
566 inc PartSystemID ; 08 is NTFS instead of 07
567 PCCTP_IFSdone:
568
569
570 ; First check, if LVM Information Sector is available and this partition
571 ; is supported.
572 push ax
573 push dx
574 push si
575 push di
576 mov si, wptr [PartPtr]
577 mov ax, wptr [si+LocBRPT_RelativeBegin] ; Absolute Sector
578 mov dx, wptr [si+LocBRPT_RelativeBegin+2]
579 add ax, wptr [CurPartition_Location+0] ; +Partition-Absolute
580 adc dx, wptr [CurPartition_Location+2] ; sectors
581
582 mov si, offset [LVMSector]
583
584IFDEF AUX_DEBUG
585 IF 0
586 DBG_TEXT_OUT_AUX 'LVMSector'
587 PUSHRF
588 call DEBUG_DumpRegisters
589 call AuxIO_DumpSector
590 ;~ call AuxIO_DumpParagraph
591 ;~ call AuxIO_TeletypeNL
592 POPRF
593 ENDIF
594ENDIF
595
596 call LVM_SearchForPartition ; Search for DX:AX partition
597
598 jnc PCCTP_CheckBootRecord
599 ; Check, if volume has driveletter assigned and remember it for later
600 mov al, [si+LocLVM_VolumeLetter]
601 or al, al
602 jnz PCCTP_HasVolumeLetter
603 mov al, 1 ; 0 would mean "not LVM supported"
604 PCCTP_HasVolumeLetter:
605 ; Save VolumeLetter in separate table
606 ;movzx bx, NewPartitions ; NewPartitions is one behind here, so
607 mov bl,NewPartitions ; NewPartitions is one behind here, so
608 mov bh,0
609
610 mov [PartitionVolumeLetters+bx], al ; it's already a zero-based offset
611 ; Now copy VolumeID and VolumeName to temporary space
612 mov di, offset MBR_NoName_Patched
613 mov ax, [si+LocLVM_PartitionID]
614 stosw
615 mov ax, [si+LocLVM_PartitionID+2]
616 stosw
617 ; Set Serial-Field to LVM-VolumeID
618
619 push di
620 add si, LocLVM_VolumeName ; Use LVM VolumeName
621 ;add si, LocLVM_PartitionName ; Use LVM PartitionName
622 mov cx, 5
623 rep movsw ; Copy LVM-PartitionName to Temp Space
624 movsb ; (11 bytes in total)
625 pop di
626
627IFDEF AUX_DEBUG
628 IF 0
629 DBG_TEXT_OUT_AUX 'Name'
630 PUSHRF
631 mov si, di
632 call AuxIO_Print
633 ;~ call DEBUG_DumpRegisters
634 ;~ call AuxIO_DumpSector
635 ;~ call AuxIO_DumpParagraph
636 ;~ call AuxIO_TeletypeNL
637 POPRF
638 ENDIF
639ENDIF
640
641 ; Check if this is an IBM-BM partition
642 cmp PartSystemID, 0ah
643 jne PCCTP_NoIbmBm
644
645 ; It is, so override the name given by IBM-BM by one that
646 ; fits in 11 chars.
647 mov si, offset ibm_bm_name
648 mov cx,5
649 rep movsw
650 movsb
651
652
653
654 PCCTP_NoIbmBm:
655 pop di
656 pop si
657 pop dx
658 pop ax
659 mov si, offset MBR_NoName_Patched
660 xor ah, ah ; no Flags_NoPartName
661 jmp PCCTP_NameSearchInIPT
662
663 PCCTP_CheckBootRecord:
664 pop di
665 pop si
666 pop dx
667 pop ax
668
669 test ah, FileSysFlags_NoName ; No-Name-Flag ? -> No Partition Name
670
671 jz PCCTP_ThereIsAName
672 jmp PCCTP_ThereIsNoName ; available
673
674 PCCTP_ThereIsAName:
675
676 ; We check for NTFS (got detected a little bit earlier in this routine)
677 cmp PartSystemID, 08h ; We got IFS/NTFS here?
678 jne PCCTP_IsNoNTFS
679 jmp PCCTP_ThereIsNoName ; NTFS has no volume label
680 PCCTP_IsNoNTFS:
681 add si, 2Bh ; DS:SI - Partition-Name
682 test ah, FileSysFlags_FAT32 ; FAT32 specific name getting ?
683
684 jz PCCTP_ResumeNormal
685
686 add si, 1Ch ; Fix for FAT 32, shiat
687 PCCTP_ResumeNormal:
688 mov cx, 11 ; 11 bytes length
689 call PART_CheckForValidPartName
690 jc PCCTP_ThereIsAName2
691
692 jmp PCCTP_ThereIsNoName
693
694 PCCTP_ThereIsAName2:
695
696 sub si, 4 ; DS:SI -> Serial&Name (15-Bytes)
697 xor ah, ah ; no Flags_NoPartName
698; jmp PCCTP_NameSearchInIPT
699
700 ;=======================================================
701 ; NAME SEARCH in IPT-Table
702 ; DS:SI - Serial&Name of Current Partition (15-Bytes)
703 ; AH - NoPartName-Flag (!MUST! be merged with Flags)
704 ;=======================================================
705 PCCTP_NameSearchInIPT:
706 xor ah, ah ; no Flags_NoPartName cause PartName valid
707 mov di, offset PartitionTable ; ES:DI - IPT-Start
708 mov dl, CFG_Partitions
709 or dl, dl
710 jnz PCCTP_SerialNameCompLoop
711 jmp PCCTP_CompareFailed
712 PCCTP_SerialNameCompLoop:
713 mov al, [di+LocIPT_Flags]
714 test al, Flags_NowFound
715 jnz PCCTP_SerialNameAlreadyFound
716 ; Now compare IPT with current Partition
717 mov cx, 15 ; Serial&Name (15-Bytes)
718 push si
719 push di
720 repz cmpsb
721 pop di
722 pop si
723
724 jne PCCTP_NoMatchYet
725
726 jmp PCCTP_Match
727
728 PCCTP_NoMatchYet:
729
730 PCCTP_SerialNameAlreadyFound:
731 add di, LocIPT_LenOfIPT
732 dec dl
733 jnz PCCTP_SerialNameCompLoop
734
735 ; if we didn't find Serial&Name, let's try Name-only without Serial
736 mov di, offset PartitionTable ; ES:DI - IPT-Start
737 mov dl, CFG_Partitions
738 PCCTP_NameCompLoop:
739 mov al, [di+LocIPT_Flags]
740 test al, Flags_NowFound
741 jnz PCCTP_NameAlreadyFound
742 ; Now compare IPT with current Partition
743 mov cx, 11 ; Name only (11-Bytes)
744 push si
745 push di
746 add si, 4
747 add di, 4 ; Skip over Serial-Field
748 repz cmpsb
749 pop di
750 pop si
751 jne PCCTP_NameNoMatch
752 mov cx, [si+0] ; Get Serial
753 mov [di+0], cx
754 mov cx, [si+2]
755 mov [di+2], cx ; ...and put it into IPT
756 jmp PCCTP_Match
757 PCCTP_NameNoMatch:
758 PCCTP_NameAlreadyFound:
759 add di, LocIPT_LenOfIPT
760 dec dl
761 jnz PCCTP_NameCompLoop
762 PCCTP_NameCompFailed:
763
764 ; So finally we search for Location and PartitionID
765 push si
766 ; Initialize some stuff for Location-Search
767 mov dh, PartSystemID
768 mov si, [PartPtr] ; DS:SI - Cur Partition Table
769 ; Relative Sector to MBR/EPR
770 mov cx, wptr [si+LocBRPT_RelativeBegin]
771 mov bx, wptr [si+LocBRPT_RelativeBegin+2]
772 add cx, [CurPartition_Location+0]
773 add bx, [CurPartition_Location+2]
774 ; BX:CX - Absolute First Sector of Partition on HDD
775 pop si
776 mov di, offset PartitionTable ; ES:DI - IPT-Start
777 mov dl, CFG_Partitions
778 PCCTP_NameLocCompLoop:
779 mov al, [di+LocIPT_Flags]
780 test al, Flags_NowFound
781 jnz PCCTP_NameLocAlreadyFound
782 ; Now compare IPT with current Partition
783 cmp dh, [di+LocIPT_SystemID]
784 jne PCCTP_NameLocMismatch
785 cmp cx, [di+LocIPT_AbsoluteBegin]
786 jne PCCTP_NameLocMismatch
787 cmp bx, [di+LocIPT_AbsoluteBegin+2]
788 jne PCCTP_NameLocMismatch
789 ; We matched location, now copy the current PartitionID and Name to
790 ; the old IPT.
791 push di
792 add di, LocIPT_Serial ; DS:SI - LocIPT-Serial&Name
793 mov cx, 15
794 rep movsb ; Copy 15 bytes
795 pop di
796 jmp PCCTP_Match
797 PCCTP_NameLocMismatch:
798 PCCTP_NameLocAlreadyFound:
799 add di, LocIPT_LenOfIPT
800 dec dl
801 jnz PCCTP_NameLocCompLoop
802 ; None of the searches worked, so forget it...
803 jmp PCCTP_CompareFailed
804
805 PCCTP_ThereIsNoName:
806 ; Try to find this partition by comparing location and PartitionID
807 ; aka LocIPT_AbsoluteBegin:dword and LocIPT_SystemID
808 ; If found, simply go to the normal match-routine, otherwise use the
809 ; File-System-Name to build the Volume-Label for the New IPT Entry.
810 mov dh, PartSystemID
811 mov si, [PartPtr] ; DS:SI - Cur Partition Table
812 ; Relative Sector to MBR/EPR
813 mov cx, wptr [si+LocBRPT_RelativeBegin]
814 mov bx, wptr [si+LocBRPT_RelativeBegin+2]
815 add cx, [CurPartition_Location+0]
816 add bx, [CurPartition_Location+2]
817 ; Build a standard-Volume Label from FileSystemNamePtr
818 ; We have to call SearchFileSysName again because of NTFS
819 push ax
820 push cx
821 mov al, dh
822 call PART_SearchFileSysName ; We want SI here <- FileSystemNamePtr
823 mov di, offset MBR_NoName_Patched
824 xor ax, ax
825 stosw
826 stosw ; Set Serial-Field to "NUL"
827 mov cx, 4
828 rep movsw ; Copy FileSystemName to Temp Space
829 xor ax, ax
830 stosw
831 stosb ; Fill last 3 bytes with "NUL"
832 mov si, offset MBR_NoName_Patched
833 pop cx
834 pop ax
835 ;=======================================================
836 ; LOCATION SEARCH in IPT-Table
837 ; DH - PartitionID of Current Partition
838 ; BX:CX - AbsoluteBegin of Current Partition
839 ; AH - NoPartName-Flag (!MUST! be merged with Flags)
840 ; DS:SI - Serial&Name of Current Partition (15-Bytes)
841 ;=======================================================
842 PCCTP_LocSearchInIPT:
843 mov ah, Flags_NoPartName ;set Flags_NoPartName, PartName invalid
844 mov di, offset PartitionTable ; ES:DI - IPT-Start
845 mov dl, CFG_Partitions
846 or dl, dl
847 jz PCCTP_LocCompFailed
848 PCCTP_LocCompLoop:
849 mov al, [di+LocIPT_Flags]
850 test al, Flags_NowFound
851 jnz PCCTP_LocAlreadyFound
852 ; Now compare IPT with current Partition
853 cmp dh, [di+LocIPT_SystemID]
854 jne PCCTP_LocMismatch
855 cmp cx, [di+LocIPT_AbsoluteBegin]
856 jne PCCTP_LocMismatch
857 cmp bx, [di+LocIPT_AbsoluteBegin+2]
858 jne PCCTP_LocMismatch
859 jmp PCCTP_Match
860 PCCTP_LocMismatch:
861 PCCTP_LocAlreadyFound:
862 add di, LocIPT_LenOfIPT
863 dec dl
864 jnz PCCTP_LocCompLoop
865 PCCTP_LocCompFailed:
866 jmp PCCTP_CompareFailed
867
868 ; ==================================
869 ; =MATCH=, found partition in IPT...
870 ; AH - NoPartName-Flag (!MUST! be merged with Flags)
871 ; DL - IPT Partition Number from Loop (inverted)
872 ; ES:DI - LocIPT-Pointer to found IPT-entry
873 ; ==================================
874 PCCTP_Match:
875 mov ch, ah
876 ; Save the new location of this partition in the Xref-Table
877 ; for converting HideConfig.
878 mov dh, dl
879 mov dl, CFG_Partitions
880 sub dl, dh
881 mov dh, NewPartitions ; is actually a counter
882 call PARTSCAN_DefXref ; DL-IPT-Partition, DH-NewPartition
883
884 ; Get Saved-Flags...
885 mov cl, bptr [di+LocIPT_Flags] ; Use saved Flags
886
887 ; ...and Saved-CRC if available...
888 mov ax, wptr [di+LocIPT_BootRecordCRC]
889 or ax, ax
890 jz PCCTP_UseNewComputedCRC
891 mov PartCRC, ax ; Use saved IPT-CRC
892 PCCTP_UseNewComputedCRC:
893 ; ...and mark partition in IPT as already found
894 or bptr [di+LocIPT_Flags], Flags_NowFound
895 ; ...get Serial&Name from IPT-table...
896 mov si, di
897 add si, LocIPT_Serial ; DS:SI - LocIPT-Serial&Name
898 jmp PCCTP_AddToNew
899
900 ; =================================
901 ; =FAILED= search, not found in IPT
902 ; AH - NoPartName-Flag (!MUST! be merged with Flags)
903 ; DS:SI - Serial&Name of Current Partition (15-Bytes)
904 ; =================================
905 PCCTP_CompareFailed:
906 mov ch, ah
907 ; Insert Default Flags...
908 mov cl, LocIPT_DefaultFlags
909
910 mov al, PartTypeFlags
911 ; May I auto-add partitions ?
912 test byte ptr [CFG_PartitionsDetect], 1
913 jz PCCTP_MayNotAddAny ; add, but non-bootable
914 test al, FileSysFlags_BootAble ; AH kam von SearchFileSysName
915 jnz PCCTP_PerhapsBootAble
916 PCCTP_MayNotAddAny:
917 mov cl, LocIPT_DefaultNonBootFlags
918 PCCTP_PerhapsBootAble:
919
920 ; On FAT32-partitions, default to P-Flag (which means using M$-hack)
921 ; Anyway, this hack has to be globaly activated by the user manually...
922 cmp PartSystemID, 09h ; Hardcoded: FAT32
923 je PCCTP_NeedsExtMShack
924 cmp PartSystemID, 0Bh
925 je PCCTP_NeedsExtMShack
926 cmp PartSystemID, 0Ch
927 je PCCTP_NeedsExtMShack
928 cmp PartSystemID, 0Eh ; FAT16 above 8 GB
929 jne PCCTP_NoExtMShack
930 ; We only get here, when the SystemID seems to be an M$ "invention"...
931 PCCTP_NeedsExtMShack:
932 or cl, Flags_ExtPartMShack
933 PCCTP_NoExtMShack:
934
935 ;================================================
936 ; CL - IPT-Partition-Flags, CH - NoPartName-Flag
937 ; DS:SI - PartSerial&Name (15-Bytes)
938 ;================================================
939 PCCTP_AddToNew:
940 mov al, Flags_NoPartName ; Unset NoPartName
941 not al
942 and cl, al
943 or cl, ch ; CL = Both CL and CH merged
944
945 ; Calculate Pointer to IPT
946 mov di, offset NewPartTable ; ES:DI - NewPartTable
947 ;movzx ax, NewPartitions
948 mov al,NewPartitions
949 mov ah,0
950
951 mov bl, LocIPT_LenOfIPT
952 mul bl
953 add di, ax ; ES:DI - Last+1 Entry of NewPartTable
954
955 ; Now finally write this partition to our IPT
956 ;=============================================
957 push cx
958 mov cx, 15 ; Copy Serial&Name...
959 rep movsb
960 pop cx
961
962 mov si, [PartPtr] ; DS:SI - Cur Partition Entry
963 mov al, bptr [CurPartition_Location+4] ; Drive
964 stosb
965 mov al, PartSystemID ; Unhidden SystemID
966 stosb
967 mov al, cl ; Partition-Flags from register...
968 stosb
969 mov ax, PartCRC ; BootRecordCRC...
970 stosw
971 mov al, bptr [si+LocBRPT_BeginHead]
972 stosb
973 mov ax, wptr [si+LocBRPT_BeginSector] ; Cylinder/Sector
974 stosw
975 mov al, bptr [CurPartition_Location+5] ; Head of Part-Table
976 stosb
977 mov ax, wptr [CurPartition_Location+6] ; Cylinder/Sector
978 stosw
979 mov ax, wptr [si+LocBRPT_RelativeBegin]
980 mov bx, wptr [si+LocBRPT_RelativeBegin+2]
981 mov cx, wptr [CurPartition_Location+0] ; +Partition-Absolute
982 mov dx, wptr [CurPartition_Location+2] ; sectors
983 add ax, cx
984 adc bx, dx
985 stosw
986 mov ax, bx
987 stosw
988 mov ax, cx ; Absolute sector of partition table
989 stosw
990 mov ax, dx
991 stosw
992 inc byte ptr [NewPartitions]; Adjusted for Wasm ; NEW IPT Entry DONE
993
994 cmp byte ptr [NewPartitions], LocIPT_MaxPartitions
995 jbe PCCTP_NotTooManyPartitions
996
997 ; Should not be reached since scanning is stopped outside this
998 ; function when partition limit exceeds.
999 mov si, offset TXT_TooManyPartitions
1000 call MBR_Teletype
1001 jmp MBR_HaltSystem
1002
1003
1004 PCCTP_NotTooManyPartitions:
1005 ; UNHIDE PARTITION, if it was hidden previously
1006 mov al, PartSystemID
1007 cmp al, 08h ; internally IFS/NTFS?
1008 je PCCTP_GotInternalIFS
1009 cmp al, 0FCh ; internally IFS/JFS?
1010 jne PCCTP_NoInternalIFS
1011 PCCTP_GotInternalIFS:
1012 mov al, 07h
1013 PCCTP_NoInternalIFS:
1014 mov bptr [si+LocBRPT_SystemID], al
1015
1016 ; Calculate Size of this partition and put it into separate table...
1017 ;movzx ax, NewPartitions
1018 mov al,NewPartitions
1019 mov ah,0
1020
1021 dec ax
1022 mov bx, ax
1023 shl ax, 1
1024 shl bx, 2
1025 add ax, bx ; My way [tm] of multiplying with 6
1026 mov di, offset PartitionSizeTable
1027 add di, ax ; DI - Partition Size-Element
1028 mov ax, wptr [si+LocBRPT_AbsoluteLength] ; Sector-Size
1029 mov bx, wptr [si+LocBRPT_AbsoluteLength+2]
1030 call PART_FillOutSizeElement
1031 ret
1032PARTSCAN_CheckThisPartition EndP
1033
1034stop_scanning db 0
1035
1036; ===================
1037; X-REFERENCE STUFF -> PartitionXref
1038; ===================
1039
1040; Reset X-Reference
1041PARTSCAN_ResetXref Proc Near Uses ax cx di
1042 mov di, offset PartitionXref ; X-Reference for later syncing
1043 mov cx, LocIPT_MaxPartitions
1044 mov ax, 0FFFFh ; Fill up with FFh
1045 rep stosb
1046 mov di, offset NewHidePartTable ; Temporary Hide-Config Table
1047 ;~ mov cx, LocIPT_MaxPartitions * LocIPT_LenOfIPT
1048 mov cx, LocIPT_MaxPartitions * LocHPT_LenOfHPT
1049 rep stosb ; Fill up with FFFFh
1050 mov di, offset NewDriveLetters
1051 mov cx, LocIPT_MaxPartitions ; Temporary Logical-Drive Letter Table
1052 xor ax, ax
1053 rep stosb ; Fill up with 0000h
1054 ret
1055PARTSCAN_ResetXref EndP
1056
1057
1058
1059; In: DL - Partition Number in IPT
1060; DH - Partition Number in NewPartitionTable
1061; Destroyed: None
1062PARTSCAN_DefXref Proc Near Uses ax bx cx dx si di
1063 ;movzx bx, dl
1064 mov bl,dl
1065 mov bh,0
1066
1067 mov bptr [PartitionXref+bx], dh ; X-Reference
1068 ; Copy Hide-Config of IPT partition to new location in new table
1069 mov si, offset HidePartitionTable
1070 mov di, offset NewHidePartTable
1071 ;~ mov bl, LocIPT_MaxPartitions
1072 mov bl, LocHPT_LenOfHPT
1073 mov al, dl
1074 mul bl
1075 add si, ax
1076 mov al, dh
1077 mul bl
1078 add di, ax
1079 ;~ mov cx, LocIPT_MaxPartitions
1080 mov cx, LocHPT_LenOfHPT
1081 rep movsb ; Copy Hide-Config to NewHideTable
1082 ; Process Logical-Drive-Letter table as well...
1083 ;movzx bx, dl
1084 mov bl,dl
1085 mov bh,0
1086
1087 mov al, bptr [DriveLetters+bx] ; Get Drv-Letter from org. pos
1088 ;movzx bx, dh
1089 mov bl,dl
1090 mov bh,0
1091
1092 mov bptr [NewDriveLetters+bx], al ; Put Drv-Letter to new pos
1093 ret
1094PARTSCAN_DefXref EndP
1095
1096
1097
1098; In: DL - Partition Number in previous IPT
1099; Out: DH - Partition Number in NewPartitionTable
1100; Destroyed: None
1101PARTSCAN_GetXref Proc Near Uses bx
1102 ;movzx bx, dl
1103 mov bl,dl
1104 mov bh,0
1105
1106 mov dh, bptr [PartitionXref+bx] ; X-Reference
1107 ret
1108PARTSCAN_GetXref EndP
1109
1110
1111;
1112; Rousseau: Adjusted for packed hidden-part-table !
1113; Needs to be re-written.
1114;
1115; This here updates the contents of the Hide-Configuration to the current IPT
1116; table.
1117PARTSCAN_SyncHideConfigWithXref Proc Near Uses ax bx cx dx si di
1118 mov si, offset NewHidePartTable
1119 mov di, offset HidePartitionTable
1120 mov dh, LocIPT_MaxPartitions ; Max entries in hide-tables.
1121
1122 PSSHCWX_SyncPartLoop:
1123 mov cl, LocIPT_MaxPartitions ; Max entries per hide-entry.
1124 xor dl, dl ; Partition Lost Counter
1125
1126 mov ch,0 ; Index.
1127
1128 PSSHCWX_SyncLoop:
1129 mov bx,si
1130
1131 ;~ lodsb ; Get Part-Pointer from Hide-Cfg
1132
1133 push dx
1134 mov dl,ch
1135 mov dh,6
1136 call CONV_GetBitfieldValue
1137 pop dx
1138
1139 ;~ cmp al, 0FFh
1140 cmp al, 3Fh
1141 je PSSHCWX_SyncEmpty
1142 ;movzx bx, al
1143 mov bl,al
1144 mov bh,0
1145
1146 mov al, [PartitionXref+bx] ; Translate it
1147 ;~ cmp al, 0FFh
1148 cmp al, 3Fh
1149 je PSSHCWX_PartLost
1150
1151 PSSHCWX_SyncEmpty:
1152 mov bx,di
1153 ;~ stosb ; Put translated pointer to new table
1154
1155 push dx
1156 mov dl,ch
1157 mov dh,6
1158 call CONV_SetBitfieldValue
1159 pop dx
1160
1161 inc ch
1162 dec cl
1163 jnz PSSHCWX_SyncLoop
1164
1165 jmp PSSHCWX_SyncLoopEnd
1166
1167 PSSHCWX_PartLost:
1168 inc dl ; One partition got lost...
1169 dec cl
1170 jnz PSSHCWX_SyncLoop
1171
1172 PSSHCWX_SyncLoopEnd:
1173
1174
1175IFDEF AUX_DEBUG
1176 IF 0
1177 pushf
1178 pusha
1179 mov al,dl
1180 call AuxIO_TeletypeHexByte
1181 call AuxIO_TeletypeNL
1182 popa
1183 popf
1184 ENDIF
1185ENDIF
1186
1187
1188 or dl, dl
1189 jz PSSHCWX_NothingLost
1190 ;~ mov al, 0FFh ; Influences OVERWRITE BUG ! (OUT OF BOUNDS !!)
1191 mov al, 3Fh
1192
1193 PSSHCWX_LostFillLoop: ; CHECK !!
1194 ;~ stosb
1195 dec cl
1196 jnz PSSHCWX_LostFillLoop
1197
1198 IFDEF AUX_DEBUG
1199 IF 0
1200 pushf
1201 pusha
1202 mov ax,di
1203 call AuxIO_TeletypeHexWord
1204 call AuxIO_TeletypeNL
1205 popa
1206 popf
1207 ENDIF
1208 ENDIF
1209
1210 PSSHCWX_NothingLost:
1211 add si, LocHPT_LenOfHPT
1212 add di, LocHPT_LenOfHPT
1213 dec dh
1214 jnz PSSHCWX_SyncPartLoop
1215
1216 ret
1217PARTSCAN_SyncHideConfigWithXref EndP
1218
1219ibm_bm_name db 'OS2 BootMgr',0
1220;win_bm_name: db 'BOOTMGR',0
Note: See TracBrowser for help on using the repository browser.