home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Media Share 13
/
mediashare_13.zip
/
mediashare_13
/
ZIPPED
/
PROGRAM
/
APR94_2.ZIP
/
LISTINST
/
LISTINST.ASM
< prev
next >
Wrap
Assembly Source File
|
1994-03-01
|
26KB
|
742 lines
;ListInst.ASM
;from Dr. Dobbs Journal,April 1994
;Copyright (c) 1994 Klaus Mueller. All rights reserved.
OPTION M510
.386p
INCLUDE VMM.INC
INCLUDE INT2FAPI.INC
INCLUDE WIN386.INC
Create_ListInst_Service_Table EQU 1 ;service table created
INCLUDE LISTINST.INC
;*****************************************************************************
; V I R T U A L D E V I C E D E C L A R A T I O N
;*****************************************************************************
Declare_Virtual_Device ListInst, 1, 0, ListInst_VxD_Control, \
ListInst_Device_ID,ListInst_Init_Order, \
ListInst_V86_API
;*****************************************************************************
; R E A L M O D E I N I T I A L I Z A T I O N
;*****************************************************************************
VXD_REAL_INIT_SEG
real_init proc near
push edx
mov ah, 9
mov dx, offset copyright
int 21h
xor ax, ax
xor bx, bx
xor si, si
pop edx
ret
real_init endp
copyright db 'ListInst.386 -- provides structures of the Instance Data'
db ' Manager.',0dh,0ah
db 'Copyright (c) 1994 Klaus Mueller. All Rights Reserved.'
db 0dh,0ah,'$'
VXD_REAL_INIT_ENDS
VxD_ICODE_SEG
BeginProc ListInst_Sys_Critical_Init
;int 3
movzx eax,dx ;real mode offset of ref data from
and edx,0ffff0000h ;VxDLoad TSR
shr edx,0ch ;segment
add edx,eax ;linear address
mov w386_sis_tbl,edx
mov Data_Buf_Size,1000h
;allocate 1 page for the InstDataStrucs from the hooked _AddInstanceItem call
VMMcall _PageAllocate <1, PG_SYS, 0, 0, 0, 0, 0, PAGEFIXED+PAGEZEROINIT>
cmp eax,0
je allocerr
mov Data_Buf_Handle,eax
mov Data_Buf_Addr,edx
int 3
;Instancing of the first byte in the 1st MB in order to get all calls to
;_AddInstanceItem befor ListInst_Sys_Critical_Init. The _AddInstanceItem
;service chains the InstDataStrucs together to a sorted double linked list
;via InstLinkF and instLinkB.
;If the LinkF field is -1, no other calls were made.
;If LinkF <> -1, then it represents a call to _AddInstanceItem caused by an
;system.ini - entry "LOCALTSRS= tsr_name". The VMM instances the hole TSR,
;the first 16 Byte represents the MCB of the PSP. So we can determine the name
;of the fully instanced TSR.
mov KM_Instance.InstLinAddr,0
mov KM_Instance.InstSize,1
mov KM_Instance.InstType,ALWAYS_FIELD
mov esi,offset32 KM_Instance
VMMcall _AddInstanceItem <esi,0>
cmp KM_Instance.InstLinkF,-1 ;any LOCALTSRS ?
je nolocal
mov esi,KM_Instance.InstLinkF ;yes, get it
loclp: mov Inst_Struc_Ptr,esi
mov calladr,'LTSR'
call addinst ;add instance item to our list
mov esi,[esi.InstDataStruc.InstLinkF] ;get next InstDataStruc
cmp esi,-1 ;no more strucs?
jne loclp
nolocal:mov eax,_AddInstanceItem
mov esi,offset32 myhook
VMMcall Hook_Device_Service
mov [oldservice],esi
;int 3 ;uncomment this for debug
clc ;no error
ret
allocerr:
stc
ret
EndProc ListInst_Sys_Critical_Init
VxD_ICODE_ENDS
;*****************************************************************************
; L O C K E D C O D E S E G M E N T
;*****************************************************************************
VxD_LOCKED_CODE_SEG
BeginProc ListInst_VxD_Control
Control_Dispatch Sys_Critical_Init, ListInst_Sys_Critical_Init
; Control_Dispatch Init_Complete, ListInst_Init_Complete
clc
ret
EndProc ListInst_VxD_Control
VxD_LOCKED_CODE_ENDS
;*****************************************************************************
; O N L Y D A T A S E G M E N T
;*****************************************************************************
VxD_DATA_SEG
w386_sis_tbl dd 0
oldservice dd 0
count dd 0
ddbpointer dd 0
Inst_Struc_Ptr dd 0
calladr dd 0
init_done dd 0
Inst_Data_Count dd 0
inst_count dd 0
desc_count dd 0
VMCB_PG_Table dd 0
SYS_PG_Table dd 0
win4_flag dd 0
w4_pres_count dd 0
w4_npres_count dd 0
w4_cur_handle dd 0
Inst_Desc_Buf dd 0
Inst_Buf_Handle dd 0
Inst_Buf_Size dd 0
bit_array dd 0
Data_Buf_Handle dd 0
Data_Buf_Addr dd 0
Data_Buf_Size dd 0
hook_err dd 0
string_buf dd 0
string_buf_handle dd 0
string_buf_size dd 0
int_2f_string db 'VMM:Create_Int_2F_Inst_Tbl: ',0
localtsr_string db 'VMM:Instance_LOCALTSRS : ',0
dos_sys_string db 'SYS DRV '
nostring db '????'
cur_inst dd 0
KM_Instance InstDataStruc {}
VxD_DATA_ENDS
VxD_CODE_SEG
BeginProc Hooked_AddInstanceItem
;The AddInstanceItem Hook stores the callers address and the instance data
;pointer in the Inst_Data_Buf buffer.
myhook:
;int 3 ;uncomment this for debug
push ebp
mov ebp,esp
push [ebp+0ch] ;Flags
push [ebp+8] ;Instance Structure Pointer
push [ebp+8]
pop Inst_Struc_Ptr
push [ebp+4] ;Callers returnaddress
pop calladr
call [oldservice] ;call old handler
add esp,8
pop ebp
;int 3
cmp eax,0 ;error in AddInstanceItem ?
je exit
call addinst ;add Instance Item to our list
exit: ;int 3
ret
;*****************************************************************************
;addinst - adds a instance item to our list.
;INPUT: calladr - address of caller of _AddInstanceItem
; Inst_Struc_Ptr - address of InstDataStruc
;OUTPUT: hookerr = -1 - error growing Data_Buf
; hookerr = 0 - all O.K.
;*****************************************************************************
addinst:push edi
push esi
push ecx
push eax
hook2: mov edi,Data_Buf_Addr
mov ecx,Inst_Data_Count
imul ecx,sizeof KM_InstData
add edi,ecx
push edi
add edi,sizeof KM_InstData
mov ecx,Data_Buf_Addr
add ecx,Data_Buf_Size
cmp edi,ecx
pop edi
jl hook1
mov ecx,Data_Buf_Size
add ecx,1000h
shr ecx,0ch
mov edx,Data_Buf_Handle
VMMcall _PageReAllocate <EDX, ECX, PAGEZEROINIT>
cmp eax,0
je hookerr
add Data_Buf_Size,1000h
mov Data_Buf_Handle,eax
mov Data_Buf_Addr,edx
jmp hook2
hook1: mov eax,calladr ;save callers address in buffer
stosd
mov esi,Inst_Struc_Ptr
mov ecx,(sizeof InstDataStruc)/4
rep movsd ;save instance data struc
inc Inst_Data_Count
hookret:pop eax ;next offset pair
pop ecx
pop esi
pop edi
ret
hookerr:mov hook_err,-1
jmp hookret
EndProc Hooked_AddInstanceItem
BeginProc ListInst_Get_Instance_Desc_Buffer, Service
cmp Inst_Desc_Buf,0
jne getdes
call descr ;build Instance Description Buf
jc getderr ;error in decr buf build
getdes: mov esi,Inst_Desc_Buf ;return address of buffer
clc
getderr:ret
EndProc ListInst_Get_Instance_Desc_Buffer
BeginProc ListInst_V86_API
;int 3
cmp [ebp.Client_AX],Inst_Map
je instmap
cmp [ebp.Client_AX],Inst_Ownership
je instown
cmp [ebp.Client_AX],Desc_Buf_Size
je descsize
cmp [ebp.Client_AX],Inst_Map_Size
je mapsize
v86err: or [ebp.Client_FLAGS],1 ;set carry
ret
descsize:
call descr
jc v86err
mov eax,Inst_Buf_Size
Client_Ptr_Flat edi, DS, BX
stosd
ret
mapsize:mov eax,Inst_Data_Count ;# of inst strucs
imul eax, sizeof Inst_Hook_Struc
Client_Ptr_Flat edi, DS, BX
stosd
ret
;V86 API, determine instance page ownership
instown:;int 3
VMMcall Get_VMM_Version
cmp ah,3
je win3
cmp ah,4
je win4
or [ebp.Client_FLAGS],1
ret
win3: cmp ecx,0 ;debug VMM ?
je nodeb3 ;no, retail VMM
mov VMCB_PG_Table,CB_PT_Deb31_Off ;debug VMM loaded
jmp vm1
nodeb3: mov VMCB_PG_Table,CB_PT_Ret31_Off ;get offset for retail VMM
jmp vm1
win4: cmp ecx,0 ;debug VMM ?
je nodeb4
or [ebp.Client_FLAGS],1 ;yes, cannot handle
ret
nodeb4: mov win4_flag,-1
mov VMCB_PG_Table,CB_PT_Ret40_Off
vm1: VMMcall Get_Sys_VM_Handle
mov ecx,110h
mov edi,VMCB_PG_Table
mov edx,[ebx+edi] ;get page table of SYS VM
mov SYS_PG_Table,edx
ownloop:mov eax,[edx] ;get page entry
mov esi,eax
cmp win4_flag,-1
jne w3loop
and esi,P_WRITE
jz nextpg
jmp gotinst
w3loop: and esi,PG_Type ;filter "Avail" field of entry
cmp esi,PgT_INSTANCE ;instanced page found ?
je gotinst
nextpg: add edx,4 ;no, test next page
lp1: loop ownloop
done: cmp Inst_Desc_Buf,0
jne done1
call descr ;build Instance Description Buf
jnc done1 ;error in decr buf build
Client_Ptr_Flat edi,DS,BX ;get callers buffer
mov edi,[edi] ;get far pointer
call v862lin
mov eax,0
mov ecx,(sizeof Inst_Desc_Struc)/4
rep stosd
jmp done2
done1: mov ecx,Inst_Buf_Size
shr ecx,2 ;copy dword
mov esi,Inst_Desc_Buf
Client_Ptr_Flat edi,DS,BX ;get callers buffer
mov edi,[edi] ;get far pointer
call v862lin
rep movsd ;copy Instance Description Buf
done2: Client_Ptr_Flat edi,DS,DX ;get callers buffer
mov edi,[edi] ;get far pointer
call v862lin
mov esi,inst_count
imul esi,sizeof Inst_Ownership_Struc
add edi,esi
mov eax,Last_Entry
stosd
mov inst_count,0
ret ;walked all VM's
gotinst:and eax,P_PRES ;page present ?
jnz gotpres
got1: cmp win4_flag,-1
jne got31
inc w4_npres_count
got31: VMMcall Get_Next_VM_Handle ;SYS VM does not own Inst Pg
VMMCall Test_Sys_VM_Handle ;check all others
jnz nextvm ;Z=1 if SYS VM
cmp win4_flag,-1
jne lp3
cmp w4_pres_count,1
jne lp4
cmp w4_npres_count,0
je lp4
mov eax,110h
sub eax,ecx
cmp eax,0a0h
jl got4
cmp eax,0c8h ;exclude screen mem
jl lp4
got4: push ebx
mov ebx,w4_cur_handle
call storepg ;write instance page to V86 buf
pop ebx ;restore current VM handle
lp4: mov w4_pres_count,0
mov w4_npres_count,0
lp3: add edx,4 ;next page table entry
jmp lp1
nextvm: push edx
sub edx,SYS_PG_Table ;current offset into page table
mov eax,edx
mov edi,VMCB_PG_Table
mov edx,[ebx+edi] ;get page table of next VM
add edx,eax ;current entry
mov eax,[edx] ;get current entry
pop edx ;current entry from SYS_VM
jmp gotinst
gotpres:cmp win4_flag,-1
jne gotpr3
inc w4_pres_count
mov w4_cur_handle,ebx
jmp got31 ;test next entry
gotpr3: call storepg ;store page number in V86 buffer
jmp got31 ;test next entry
;Storepg - Writes number of instanced page and VM handle, flags, ID
;to V86 buffer in DS:DX
;INPUT: EBX = VM handle
; EBP = Client_Ptr
; ECX = current pagecount (<110h)
storepg:push eax
push esi
push edi
mov eax,110h
sub eax,ecx ;eax = number of inst page
Client_Ptr_Flat edi,DS,DX ;get callers buffer
mov edi,[edi] ;get far pointer
call v862lin
mov esi,inst_count
imul esi,sizeof Inst_Ownership_Struc
add edi,esi
mov [edi.Inst_PG_No],eax ;store number of instanced page
mov [edi.Owner_VM_Handle],ebx ;store VM_Handle
mov eax,[ebx.CB_VM_Status]
mov [edi.Owner_VM_Flags],eax
mov eax,[ebx.CB_VMID] ;get VMID
mov [edi.Owner_VM_ID],eax ;store ID
inc inst_count
pop edi
pop esi
pop eax
ret
;Create the Instance Description Buffer with data from hooked _AddInstanceItem
;Since 140 Kb are not a big problem in win386, I simply allocate a bit array.
;Every bit stands for a Byte in the first 10fh pages.
;A bit is set if the corresponding byte is marked instanced in an InstData
;struc. In this way I must not handle the overlapping (left, right, lower,
;upper) instance items for building the Instance Description Buffer.
;If you ever inspect the code from the VMM, which generates the VMM
;Instance Description Buffer, you will be astonished how a different approach
;can avoid al lot of programming work.
descr: ;int 3
pushad
cmp hook_err,-1 ;error in _AddInstanceItemhook?
je deserr
mov eax,110000h
shr eax,3
mov ecx,eax
push ecx
VMMcall _HeapAllocate <eax,0>
pop ecx
cmp eax,0
je deserr
mov edi,eax
mov bit_array,eax
shr ecx,2
mov eax,0
push edi
rep stosd ;perform ZeroInit
pop edi
mov Inst_Buf_Size,1000h ;size in dword
VMMcall _PageAllocate <1,PG_SYS,0,0,0,0,0,PAGEFIXED+PAGEZEROINIT>
mov Inst_Desc_Buf,edx ;store address
mov Inst_Buf_Handle,eax ;store handle
mov ebx,8
mov esi,Data_Buf_Addr
mov ecx,Inst_Data_Count ;# of InstData strucs
;int 3
desclp: push ecx
mov eax,[esi.KM_InstData.InstType]
cmp eax,ALWAYS_Field
je blp1
cmp eax,INDOS_Field
jnz skiplp
blp1: mov eax,[esi.KM_InstData.InstLinaddr] ;get VM linear address
mov ecx,[esi.KM_InstData.InstSize]
bitlp: bts [edi],eax ;386 power!,set bit in array
inc eax
loop bitlp
skiplp: add esi,sizeof KM_InstData ;next InstData Struc
pop ecx ;current Inst_Data_Count
loop desclp
mov ecx,110000h
mov ebx,Inst_Desc_Buf ;all bits set
mov eax,0 ;begin with bit 0
mov esi,0 ;size of last item
tstlp: bt [edi],eax ;test bit
inc eax
jc bitset
loop tstlp
desret: mov eax,bit_array
VMMcall _HeapFree <eax, 0>
clc
popad
ret ;all bits tested
itemend:mov [ebx.Inst_Desc_Struc.Item_Size],edx
cmp edx,4
push edx
jb item5
mov edx,[ebx.Inst_Desc_Struc.VM_Lin_Address]
test edx,3
jz item2
and edx,3
sub edx,4
neg edx
push eax
mov eax,[ebx.Inst_Desc_Struc.Item_Size]
sub eax,edx
cmp eax,4
jb item4
mov eax,esi
and eax,3
sub eax,4
neg eax
cmp eax,edx
jz item4
ja item3
add esi,eax
add esi,4
sub esi,edx
jmp item4
item3: sub eax,edx
add esi,eax
item4: pop eax
jmp item5
item2: add esi,3 ;last Inst_Buf_Off
and esi,not 3
item5: ;int 3
mov [ebx.Inst_Desc_Struc.Inst_Buf_Off],esi ;offset in Inst Buf
pop edx
add esi,edx ;Inst_Buf_Off for next item
add ebx,sizeof Inst_Desc_Struc ;next entry
push ebx
mov edx,Inst_Desc_Buf
add edx,Inst_Buf_Size
add ebx,sizeof Inst_Desc_Struc ;next entry
cmp ebx,edx
pop ebx
jl item1
sub ebx,Inst_Desc_Buf
push ebx
push eax
push ecx
mov ecx,Inst_Buf_Size
add ecx,1000h
shr ecx,0ch
mov edx,Inst_Buf_Handle
VMMcall _PageReAllocate <EDX, ECX, PAGEZEROINIT>
cmp eax,0
je deserr
add Inst_Buf_Size,1000h
mov Inst_Buf_Handle,eax
mov Inst_Desc_Buf,edx
pop ecx
pop eax
pop ebx
add ebx,Inst_Desc_Buf
item1: dec ecx
jnz tstlp
jmp desret ;all bits tested
bitset: dec ecx
mov edx,1 ;instanced byte counter
dec eax
mov [ebx.Inst_Desc_Struc.VM_Lin_Address],eax
inc eax
itemlp: bt [edi],eax ;test following bit
inc eax ;next bit
jnc itemend
inc edx ;instanced byte counter++
loop itemlp
jmp desret ;all bits tested
deserr: stc ;signal error
popad
ret
;V86 API, result of _AddInstanceItem hook
instmap:;int 3
cmp hook_err,-1 ;errore during -AddInstanceItem hook ?
jne hookok
or [ebp.Client_Flags],1 ;signal error
ret
hookok: cmp string_buf,0 ;already build ?
je instgo
jmp instcpy
instgo: mov eax,Inst_Data_Count
imul eax,sizeof Inst_Hook_Struc
cmp eax,1000h
ja instgo1
mov eax,1
jmp instgo2
instgo1:add eax,1000h
and eax,0fffh
shr eax,0ch
instgo2:VMMcall _PageAllocate <eax, PG_SYS, 0, 0, 0, 0, 0, PAGEFIXED+PAGEZEROINIT>
cmp eax,0
je inster1
mov string_buf_handle,eax
mov string_buf,edx
mov ecx,Inst_Data_Count
instlp: push ecx
mov esi,count
imul esi,sizeof KM_InstData
add esi,Data_Buf_Addr
;int 3
mov edi,[esi.KM_InstData.AddInst_Caller]
mov cur_inst,esi
cmp edi,'LTSR' ;instance struc from LOCALTSRS entry ?
je locadd
VxDcall VxDQuery_Address_to_VxDName
jc insterr
isVxD: push edi ;points to VxDname received from VxDQuery
;int 3
mov edi,w386_sis_tbl ;first Win386_KM_SIS
nextsis:mov ebx,[edi.KM_SIS.SIS_Instance_Data_Ptr]
cmp ebx,0 ;any instance data in current Win386_KM_SIS ?
jne idata
endlst: cmp [edi.KM_SIS.SIS_Next_Ptr],0 ;last SIS ?
je no2f
add edi,sizeof KM_SIS ;next Win386_KM_SIS
jmp nextsis
idata: mov esi,ebx ;Seg:Off of inst data list
movzx eax,si ;offset of inst data list
and esi,0ffff0000h
shr esi,0ch ;linear address of segment
add esi,eax ;linadr of inst data list
nextiis:int 3
mov ebx,[esi.IIS_Ptr] ;Seg:Off of instance item
cmp ebx,0 ;no more items ?
je endlst
movzx eax,bx ;offset of Instance Item
and ebx,0ffff0000h
shr ebx,0ch ;linear address of segment
add ebx,eax ;linadr of instance item
mov eax,cur_inst ;current Instance struc
;current instance item from int_2f_inst_table ?
cmp ebx,[eax.KM_InstData.InstLinAddr]
je inst2f
add esi,sizeof Instance_Item_Struc ;next Instance_Item_Struc
jmp nextiis
;InstDataStruc of DOS-TSR via int 2f
inst2f: add esp,4 ;forget name from VxDQuery
;int 3
mov esi,offset32 int_2f_string
mov ebx,edi ;current Win386_KM_SIS
inst2f1:mov edi,[count]
imul edi,sizeof Inst_Hook_Struc
add edi,string_buf
push edi ;current Inst_Hook_Struc
mov ecx,string_len/4
rep movsd ;copy "Create_Int_2F_Inst_Table" string
sub edi,9
mov esi,ebx ;points to Win386_KM_SIS
add esi,offset KM_SIS.Tsr_Name ;points to name of DOS TSR
cmp byte ptr [esi],'S'
jne inst1
cmp byte ptr[esi+1],'D'
jne inst1
mov esi,offset32 dos_sys_string
movsd ;copy "CONFIG DRV" string
movsd
jmp endname
inst1: movsd
movsd ;copy name of DOS TSR
sub edi,8
mov ecx,9
mov al,0
repne scasb
jne endname
mov al,20h
dec edi
rep stosb ;fill up with spaces
jmp endname
;InstDataStruc of a LOCALTSR via system.ini entry
locadd: ;int 3 ;uncomment this for debug
mov esi,offset32 localtsr_string
mov edi,[count]
imul edi,sizeof Inst_Hook_Struc
add edi,string_buf
push edi ;current Inst_Hook_Struc
mov ecx,string_len/4
rep movsd ;copy "VMM: Instance_LOCALTSRS " string
sub edi,9
mov esi,cur_inst ;InstDataStruc
mov esi,[esi.KM_InstData.InstLinAddr] ;esi = MCB of LOCALTSR
add esi,offset MCB_Name ;points to name of DOS TSR
movsd
movsd ;copy name of DOS TSR
sub edi,8
mov ecx,9
mov al,0
repne scasb
jne endname
mov al,20h
dec edi
rep stosb ;fill up with spaces
jmp endname
no2f: pop edi
mov esi,edi ;pointer to VxDName
mov edi,count
imul edi,sizeof Inst_Hook_Struc
add edi,string_buf
push edi
mov ecx,string_len/4
rep movsd ;save VxDName in string_buf
endname:pop edi ;current Inst_Hook_Struc
mov eax,cur_inst ;Instance struc
mov edx,[eax.KM_InstData.InstLinAddr]
mov [edi.Inst_Hook_Struc.Inst_Lin_Adr],edx
mov edx,[eax.KM_InstData.InstSize]
mov [edi.Inst_Hook_Struc.Inst_Size],edx
inc count
pop ecx
dec ecx
jnz instlp
instcpy:Client_Ptr_Flat edi,DS,DX ;address of callers ptr to buffer
mov edi,[edi]
call v862lin
mov esi,string_buf
mov ecx,Inst_Data_Count ;# of inst strucs
imul ecx, sizeof Inst_Hook_Struc
shr ecx,2
rep movsd ;copy data into callers V86 buffer
mov count,0
ret
insterr:pop ecx
inster1:or [ebp.Client_FLAGS],1 ;set carry, error
ret
;INPUT edi = Seg:Offs V86
;OUTPUT edi = linadr
v862lin:push edx
movzx edx,di
shr edi,10h
shl edi,4
add edi,edx
pop edx
ret
EndProc ListInst_V86_API
VxD_CODE_ENDS
END