;++ ; ;Copyright (c) 1995 Microsoft Corporation ; ;Module Name: ; ; bootfix.asm ; ;Abstract: ; ; The code in this "image" is responsible for checking if is appropriate ; for us to boot from CD. We want to boot from CD whenever we don't have ; a valid active partition or when the user pressed CTRL key during the ; boot process. ; ;Author: ; ; Calin Negreanu (calinn) 25-May-1998 ; ;Environment: ; ; Image has been loaded at 2000:0000 by ETFS boot code. ; Real mode ; ISO 9660 El Torito no-emulation CD-ROM Boot support ; DL = El Torito drive number we booted from ; ;Revision History: ; ; Calin Negreanu (calinn) 18-Feb-1999 ; ;-- page ,132 title bootfix name bootfix .8086 CODE SEGMENT ASSUME CS:CODE,DS:CODE,SS:NOTHING,ES:NOTHING ORG 0000H _BootFix label byte MaxCodeSize EQU 1024 Part_Active EQU 0 Part_Type EQU 4 Data_PartType EQU 0 ;address of partition type inside BootData structure LoadSeg EQU 3000H ;we load MBR here SectSize EQU 512 EntriesOnMbr EQU 4 MbrDataOff EQU 01BEH VolbootOrg EQU 7c00h JMPFAR MACRO DestOfs,DestSeg db 0eah dw OFFSET DestOfs dw DestSeg endm START: ; ; we already have a valid stack set by the original ETFS boot sector ; we only need to set ds and es ; push ds push es mov ax,cs mov ds,ax mov es,ax ; ; read partition table from hdd 80h at LoadSeg:0000 ; push es mov ax,LoadSeg mov es,ax mov bx,0000h mov ax,0201h ;read function, one sector mov cx,0001h mov dx,0080h int 13h jnc MbrOk ; ; there was an error, boot from CD ; pop es jmp CdBoot MbrOk: pop es ; ; now it's the time to loop and find the active partition table ; push es mov ax,LoadSeg mov es,ax mov cx,EntriesOnMbr ;number of partitions in partition table mov bp,MbrDataOff ;01beh LoopActive: ; ; 00 - inactive, 80h active, others-invalid ; cmp BYTE PTR es:[bp].Part_Active,00H jl CheckInactive jne BadMbr add bp,16 loop LoopActive ; ; no active partition found. boot from CD ; pop es jmp CdBoot CheckInactive: push bp InactiveLoop: add bp,16 dec cx jz ActiveFound cmp BYTE PTR es:[bp].Part_Active,00H je InactiveLoop pop bp BadMbr: ; ; bad mbr was found. boot from CD ; pop es jmp CdBoot ActiveFound: pop bp pop es ; ; let's see if we can display UI (that is if MsgPressKey is not empty ; mov si, OFFSET MsgPressKey lodsb mov UIAllowed, al push si mov si,OFFSET MsgPressKey call PrintMsg pop si ; ; read all available keys from the queue (prevents us from booting from CD when there ; is some garbage there ; mov cx, 80h FlushQueue: mov ah, 01h int 16h jz QueueEmpty mov ah, 00h int 16h loop FlushQueue QueueEmpty: ; ; hook int08 ; cli push es xor ax,ax mov es,ax mov bx,08h * 4 mov ax,es:[bx] mov WORD PTR [OldInt08 ], ax mov ax,es:[bx+2] mov WORD PTR [OldInt08+2], ax mov WORD PTR es:[bx],OFFSET NewInt08 mov WORD PTR es:[bx+2],cs pop es sti ; ; loop until the delay ticks is 0. Check for a key pressed (if UI), or for CTRL pressed (if no UI) ; CheckKey: cmp UIAllowed, 0 je CheckCTRL mov ah, 01h int 16h jnz KeyPressed CheckCTRL: mov ah,02h int 16h and al,00000100b jnz KeyPressed NotPressed: cmp DotTicks, 0 jg AddDot push si mov si,OFFSET MsgDot call PrintMsg pop si mov DotTicks, 18 AddDot: cmp DelayTicks, 0 jne CheckKey call UnhookInt08 jmp BootFromHD UnhookInt08: cli push es xor ax,ax mov es,ax mov bx,08h * 4 mov ax,WORD PTR [OldInt08] mov es:[bx],ax mov ax,WORD PTR [OldInt08+2] mov es:[bx+2],ax pop es sti ret KeyPressed: call UnhookInt08 jmp CdBoot BootFromHD: ; ; let's move the mbr code to 0000:7c00 and jump there ; mov ax,LoadSeg mov ds,ax xor ax,ax mov es,ax xor si,si mov di,VolBootOrg mov cx,SectSize cld rep movsb mov dl,80h JMPFAR VolbootOrg,0000H CdBoot: ; ; return to caller code ; pop es pop ds retf NewInt08: pushf cli cmp WORD PTR cs:[DelayTicks], 0 je default08 dec WORD PTR cs:[DotTicks] dec WORD PTR cs:[DelayTicks] default08: popf push WORD PTR cs:[OldInt08+2] push WORD PTR cs:[OldInt08] retf ; ;EXPECTS DS:SI - MESSAGE ADDR ; PrintMsg proc near push ax push bx cmp UIAllowed, 0 je PrintMsgEnd PrintMsgLoop: lodsb cmp al,0 je PrintMsgEnd mov ah,0eh mov bx,0007h int 10h jmp PrintMsgLoop PrintMsgEnd: pop bx pop ax ret PrintMsg endp include bootfix.inc ; message text UIAllowed db 0 MsgDot db "." db 0 OldInt08 dd ? DelayTicks dw 4*18+1 ; 4 seconds DotTicks dw 18 .errnz ($-_BootFix) GT (MaxCodeSize - 2) ;FATAL: bootfix code is too large org MaxCodeSize - 2 db 55h,0aah CODE ENDS END START