kolibrios/programs/hd_load/9x2klbr/vxd.asm
CleverMouse 812bae4a84 add hd_load to russian livecd
git-svn-id: svn://kolibrios.org@2783 a494cfbc-eb01-0410-851d-a64ba20cac60
2012-06-15 14:18:39 +00:00

235 lines
4.1 KiB
NASM

.386p
WIN40COMPAT = 1
include vmm.inc
include v86mmgr.inc
DECLARE_VIRTUAL_DEVICE LDKLBR,1,0,LDKLBR_Control,UNDEFINED_DEVICE_ID,1
;Begin_control_dispatch LDKLBR
;Control_Dispatch w32_DeviceIoControl, OnDeviceIoControl
;Control_Dispatch Sys_Dynamic_Device_Exit, OnExit
;End_control_dispatch LDKLBR
VxD_LOCKED_DATA_SEG
VkdControlProc dd 0
vkdddb dd 0
diskinfobuf:
db 10h,0,0,0FFh
db 0Ch dup (0)
oldidt label fword
dw 03FFh
dd 0
include mtldr.inc
imgname dd 0
VxD_LOCKED_DATA_ENDS
VxD_LOCKED_CODE_SEG
BeginProc NewControlProc
cmp eax, Reboot_Processor
jz short MyReboot
jmp [VkdControlProc]
EndProc NewControlProc
BeginProc MyReboot
VMMCall _MapPhysToLinear,<0D000h,2000h,0>
push eax
VMMCall _MapPhysToLinear,<0,1000h,0>
xchg eax, ebx
cli
lea esi, [ebx+53Ch]
lodsd
mov [ebx+413h], ax
shr eax, 10h
mov [ebx+40Eh], ax
; restore BIOS IDT - vectors 00..1F
mov edi, ebx
mov ecx, 20h
rep movsd
; int 19
mov eax, [ebx+810h]
mov [ebx+64h], eax
; vectors 40,41,42,43,46,4B,4F
lea edi, [ebx+40h*4]
movsd
movsd
movsd
movsd
scasd
scasd
movsd
add edi, 10h
movsd
add edi, 0Ch
movsd
; vectors 70..77
; lea esi, [ebx+5DCh]
lea edi, [ebx+70h*4]
mov ecx, 8
rep movsd
; reboot to mtldr
mov dword ptr [ebx+467h], 0D000007h ; 0D00:0007
mov al, 0Fh
out 70h, al
jecxz $+2
jecxz $+2
mov al, 5
out 71h, al
; copy mtldr code
mov esi, offset mtldr
; mov edi, 0D000h
pop edi
push edi
mov ecx, mtldr_size
rep movsb
; copy mtldr parameters
mov esi, [imgname]
mov edi, esi
mov al, 0
xor ecx, ecx
dec ecx
repnz scasb
pop edi
not ecx
movzx eax, word ptr [edi+5]
add edi, eax
rep movsb
; load old IDT
lidt [oldidt]
; reboot
mov al, 0FEh
out 64h, al
hlt
EndProc MyReboot
BeginProc LDKLBR_Control
cmp eax, w32_DeviceIoControl
jz short OnDeviceIoControl
cmp eax, Sys_Dynamic_Device_Exit
jz short OnExit
cmp eax, Reboot_Processor
jz MyReboot
clc
ret
OnExit:
; allow unload if and only if we are not hooking
cmp [VkdControlProc], 1
cmc
ret
OnDeviceIoControl:
cmp dword ptr [esi+12], DIOC_Open
jz @@open
cmp dword ptr [esi+12], 0Fh
jnz _exit
; request to set path of image
mov ecx, [esi+20] ; cbInBuffer
cmp ecx, 300
ja short @@paramerr
test ecx, ecx
jnz short @@param1ok
@@paramerr:
xor eax, eax
inc eax
@@errret:
mov ecx, [vkdddb]
mov edx, [VkdControlProc]
mov [ecx + VxD_Desc_Block.DDB_Control_Proc], edx
mov [VkdControlProc], 0
ret
@@param1ok:
mov eax, [esi+16] ; lpvInBuffer
; set drive
mov dl, [eax]
or dl, 20h
sub dl, 60h
jz short @@paramerr
cmp dl, 'z'-60h
ja short @@paramerr
push esi
Push_Client_State Uses_edi
mov ecx, 10h
stc
push ds
pop fs
mov esi, offset diskinfobuf
VMMCall Get_Cur_VM_Handle
VxDCall V86MMGR_Allocate_Buffer
VMMCall Begin_Nest_V86_Exec
assume ebp:ptr Client_Reg_Struc
mov [ebp.Client_AX], 440Dh
mov [ebp.Client_BL], dl
mov [ebp.Client_CX], 086Fh
mov [ebp.Client_DX], di
mov eax, edi
shr eax, 10h
mov [ebp.Client_DS], ax
mov eax, 21h
VMMCall Exec_Int
VMMCall End_Nest_Exec
mov ecx, 10h
stc
push ds
pop fs
VxDCall V86MMGR_Free_Buffer
Pop_Client_State Uses_esi
pop esi
mov al, byte ptr [diskinfobuf+3]
cmp al, 0FFh
jz @@errret
cmp al, 80h
jb @@paramerr
mov byte ptr [mtldr+4], al
mov eax, dword ptr [diskinfobuf+8]
mov dword ptr [mtldr], eax
; set path
mov ecx, [imgname]
jecxz @f
VMMCall _HeapFree, <ecx,0>
@@:
mov ecx, [esi+20]
dec ecx
push ecx
VMMCall _HeapAllocate, <ecx,0>
pop ecx
mov [imgname], eax
xchg edi, eax
mov esi, [esi+16]
inc esi
@@1:
lodsb
cmp al, 'A'
jb short @f
cmp al, 'Z'
ja short @f
or al, 20h
@@:
stosb
loop @@1
xor eax, eax
ret
@@open:
; don't hook if already hooked
cmp [VkdControlProc], 0
jnz short @f
mov eax, 0Dh
VMMCall Get_DDB
mov [vkdddb], ecx
mov eax, [ecx + VxD_Desc_Block.DDB_Control_Proc]
mov [VkdControlProc], eax
mov [ecx + VxD_Desc_Block.DDB_Control_Proc], NewControlProc
@@:
xor eax, eax
_exit:
ret
EndProc LDKLBR_Control
VxD_LOCKED_CODE_ENDS
end