; ======================================================== if 0 REBOOT.ASM Copyright (c) 1991 - Microsoft Corp. All rights reserved. Microsoft Confidential johnhe - 12/01/89 endif ;-----------------------------------------------------------------------------; ; K E Y B O A R D S C A N C O D E S ; ;-----------------------------------------------------------------------------; KB_INTERCEPT EQU 4fh DEL_KEY EQU 53h ALT_SHIFT EQU 08h CTL_SHIFT EQU 04h WARM_BOOT_CODE EQU 1234h ;-----------------------------------------------------------------------------; ; BIOS DATA AREA LOCATED AT 40:00 ;-----------------------------------------------------------------------------; ROM_DATA SEGMENT AT 040h org 17h KB_FLAG LABEL BYTE org 072h WarmBootFlag LABEL WORD ROM_DATA ENDS ;-----------------------------------------------------------------------------; ; CPU POWER-ON STARTUP LOCATION AT ffff:00 ;-----------------------------------------------------------------------------; ROM_BIOS SEGMENT AT 0ffffh org 0 PowerOnReset LABEL FAR ROM_BIOS ENDS ;-----------------------------------------------------------------------------; ;include MODEL.INC ;-----------------------------------------------------------------------------; ;.CODE _TEXT segment public 'CODE' assume cs:_TEXT,ds:nothing public _DnaReboot _DnaReboot PROC near ;RebootSystem PROC ifdef NEC_98 DoInt15: ; ; 37h bit 2 is shutdown bit. ; mov al,0bh out 37h,al mov al,0fh out 37h,al mov al,0h out 0f0h,al jmp DoInt15 else ; PC98 mov AX,3515h int 21h ; Get int 15h vector in ES:BX mov AX,ES ; AX == Segment or AX,BX ; Is this a NULL ptr jz WarmBoot ; If zero we can't do an int 15h DoInt15: mov ax, seg WarmBootFlag mov ds, ax assume DS:ROM_DATA mov KB_FLAG,ALT_SHIFT OR CTL_SHIFT mov AX,(KB_INTERCEPT SHL 8) OR DEL_KEY int 15h ; Put Ctrl/Alt/Del into key buffer WarmBoot: cli cld mov ax, seg WarmBootFlag mov ds, ax assume DS:ROM_DATA mov WarmBootFlag, WARM_BOOT_CODE jmp PowerOnReset ; Jump to the processor power-on address FFFF:0000h endif ; NEC_98 ` _DnaReboot ENDP ;RebootSystem ENDP ; ======================================================== ;++ ; ; BOOLEAN ; _far ; _cdecl ; DnAbsoluteSectorIo( ; IN unsigned Drive, //0=A, etc ; IN ULONG StartSector, ; IN USHORT SectorCount, ; IN OUT PVOID Buffer, ; IN BOOLEAN Write ; ) ; ;-- public _DnAbsoluteSectorIo _DnAbsoluteSectorIo PROC far ; params Drive equ 6 Int2526Packet equ 8 Write equ 18 ; locals GotLock equ -2 push bp mov bp,sp sub sp,2 push ds push es push bx push si push di mov byte ptr [bp].GotLock,0 ; initialize lock state flag ; ; Check for Win9x by checking for version 7 or greater. ; The minor version number is 10 for OSR2. ; ; We might also be running on some other vendor's DOS 7, ; so if locking fails we try the i/o anyway. ; mov ax,3306h ; get MS-DOS version int 21h cmp bl,8 ; Is Millenium ? je milljmp ; cmp bl,7 ; check for DOS7 or above (Win9x) jb dosjmp ; not Win9x jmp winjmp ; Regular Win9x jmp dosjmp: mov bl,8 ; assume standard ioctl jmp locked ; not Win9x milljmp: mov bl,48h ; extended ioctl jmp getlock winjmp: mov bl,48h ; DOS 7 or above, assume extended ioctl cmp bh,10 ; test OSR2 jae getlock ; OSR2, leave bl alone, use ext ioctl mov bl,8 ; Win9x gold, use standard ioctl getlock: push bx ; standard/extended ioctl .286 push 4ah ; lock volume ioctl code .8086 push [bp].Drive call LockOrUnlock jc locked ; failure, try i/o anyway inc byte ptr [bp].GotLock ; remember we have level 0 lock locked: ; ; Dirty hack -- the int25/26 buffer is laid ; out exactly the way the parameters are passed ; on the stack. ; ; In OSR2 or later case, try new int21 first. Int25/26 don't work on FAT32. ; cmp bl,48h ; OSR2 or later? mov ax,ss mov ds,ax push bx ; save OSR2 or later flag lea bx,[bp].Int2526Packet ; ds:bx = disk i/o param mov cx,0ffffh ; tell DOS to use param packet jne int2526 ; don't try new int21 on old system mov ax,7305h ; new abs disk i/o int21 call mov dl,[bp].Drive ; fetch drive inc dl ; make drive 1-based mov si,0 ; assume read cmp byte ptr [bp].Write,0 ; write operation? je doint21 ; no, read op inc si ; write op doint21: int 21h ; call DOS jnc did_io ; no error, done int2526: mov al,[bp].Drive ; fetch drive (0-based) cmp byte ptr [bp].Write,0 ; write operation? je @f ; no, read op int 26h ; abs disk write jmp short didio1 @@: int 25h didio1: pop ax ; int 25/26 wierdness did_io: pop bx ; restore osr2 flag in bx .386 setnc al ; convert carry status to boolean return code .8086 push ax ; save return code ; ; Unlock if necessary, using same lock level ; of successful lock. ; cmp byte ptr [bp].GotLock,0 je done ; no lock to undo push bx ; osr2 or later flag/ioctl category .286 push 6ah ; unlock volume ioctl code .8086 push [bp].Drive call LockOrUnlock done: pop ax ; restore return code in al pop di ; restore caller registers pop si pop bx pop es pop ds mov sp,bp ; restore stack frame pop bp ret _DnAbsoluteSectorIo ENDP LockOrUnlock PROC near .286 pusha ; pushes 16 bytes mov bp,sp dolock: mov ch,byte ptr [bp+22] ; get ioctl category, 8 or 48 mov ax,440dh ; generic ioctl code .386 movzx bx,byte ptr [bp+18] ; bl = drive, bh = lock level 0 .286 inc bl ; convert drive to 1-based mov cl,byte ptr [bp+20] ; lock/unlock ioctl code xor dx,dx ; non-format lock int 21h jnc lockdone cmp byte ptr [bp+22],8 ; tried regular ioctl? (clobbers carry) mov byte ptr [bp+22],8 ; try regular ioctl on next pass jne dolock ; try regular ioctl stc ; error return lockdone: popa ret 6 ; carry set for return .8086 LockOrUnlock ENDP _TEXT ends END ; ========================================================