mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
195 lines
4.3 KiB
195 lines
4.3 KiB
;;--------------------------------------------------------------------
|
|
;;
|
|
;; Microsoft OS/2 LAN Manager
|
|
;; Copyright(c) Microsoft Corp., 1990
|
|
;;
|
|
;;------------------------------------------------------------------
|
|
;;
|
|
;;Description :
|
|
;; Demand load functions into a DOS psuedo DLL.
|
|
;;
|
|
;;History :
|
|
;;
|
|
;;stevez 03-23-92 First bits into the bucket.
|
|
;;
|
|
;; jroberts 06-05-94 If LoadDll fails, it returns
|
|
;; rpc_s_name_service_unavailable
|
|
.model large, c
|
|
|
|
TableSegment segment word public 'data'
|
|
|
|
FunctionNames label dword
|
|
|
|
TableSegment ends
|
|
|
|
dgroup group TableSegment
|
|
|
|
.data
|
|
hModule dd 0
|
|
|
|
.code
|
|
LoadModR proto moduleName:ptr byte, handle:ptr dword
|
|
CallExportInit proto handle:dword
|
|
GetProcAddrR proto handle:dword, FunctionName:ptr byte, Address:ptr dword
|
|
UnloadModR proto handle:dword
|
|
|
|
|
|
iFunctionCurrent = 0
|
|
|
|
; The following macro creates a function thunk, a entry
|
|
; in the function table of pointers and a entry in the
|
|
; table of function names.
|
|
|
|
ExportFunction macro FunctionName:req, ArgWordCount:req
|
|
local StringName
|
|
|
|
|
|
; A thunk is simply a jump indirect through a table.
|
|
; AX is loaded with enough information to demand load the
|
|
; table entry if the dll hasn't been loaded.
|
|
|
|
FunctionName proc Pascal
|
|
mov ax, iFunctionCurrent*4 + (ArgWordCount*2 shl 8)
|
|
jmp FunctionTable[iFunctionCurrent*4]
|
|
FunctionName endp
|
|
|
|
|
|
; Create a string for the function name and a pointer to that
|
|
; string in the TableSegment.
|
|
|
|
.data
|
|
StringName db "&FunctionName", 0
|
|
@CurSeg ends
|
|
|
|
TableSegment segment word public 'data'
|
|
dd StringName
|
|
TableSegment ends
|
|
|
|
.code
|
|
|
|
iFunctionCurrent = iFunctionCurrent + 1
|
|
endm
|
|
|
|
ModuleName macro ModName, extension:=<.rpc>
|
|
|
|
.data
|
|
|
|
FunctionMax dw iFunctionCurrent*4
|
|
DllName db "&ModName&&extension", 0
|
|
|
|
; This is the vector of funtion pointers used to call indirect with.
|
|
; The table is initialized to point the the routine which demand loads
|
|
; all the entrys in the table.
|
|
|
|
FunctionTable dd iFunctionCurrent dup (LoadDLL)
|
|
|
|
.code
|
|
|
|
; The following function unloads the DLL.
|
|
|
|
ModName&Discard proc public uses di
|
|
|
|
; First, reset the table to the load function.
|
|
|
|
mov ax, word ptr hModule
|
|
or ax, word ptr hModule+2
|
|
jz Done
|
|
|
|
mov ax, offset LoadDLL
|
|
mov bx, cs
|
|
push ds
|
|
pop es
|
|
mov di, offset FunctionTable
|
|
mov cx, iFunctionCurrent
|
|
|
|
.repeat
|
|
|
|
stosw
|
|
xchg ax,bx
|
|
stosw
|
|
xchg ax,bx
|
|
|
|
.untilcxz
|
|
|
|
; Free the memory allocated by this DLL.
|
|
|
|
invoke UnloadModR, hModule
|
|
mov word ptr hModule,0
|
|
mov word ptr hModule+2,0
|
|
|
|
Done:
|
|
ret
|
|
|
|
ModName&Discard endp
|
|
|
|
.data
|
|
|
|
ErrorExit dd ?
|
|
|
|
.code
|
|
|
|
LoadDLL proc private uses si
|
|
|
|
push ax ; save the function ordinal
|
|
|
|
; First, open up the DLL module.
|
|
|
|
invoke LoadModR, Addr DllName, Addr hModule
|
|
|
|
.if ax
|
|
ErrorReturn:
|
|
mov ax, 80 ; rpc_s_name_service_unavailable
|
|
|
|
pop bx ;Bx = number of argumnets to call
|
|
xchg bh,bl
|
|
xor bh,bh
|
|
|
|
pop si ; restore the registers
|
|
|
|
; Since this is a pascal function we must fix up the stack
|
|
; on return, do this by poping the return into a static,
|
|
; adjusting the stack and then jumping to the return.
|
|
|
|
pop word ptr ErrorExit
|
|
pop word ptr ErrorExit+2
|
|
add sp, bx
|
|
|
|
jmp [ErrorExit]
|
|
.endif
|
|
|
|
invoke CallExportInit, hModule
|
|
|
|
; For each function, look up the address in the DLL.
|
|
|
|
xor si,si
|
|
.while (si < FunctionMax)
|
|
|
|
mov ax,offset FunctionTable
|
|
add ax,si
|
|
|
|
invoke GetProcAddrR, hModule, FunctionNames[si], ds::ax
|
|
or ax,ax
|
|
jnz ErrorReturn
|
|
|
|
add si,4
|
|
.endw
|
|
|
|
|
|
; All the function pointers have been fixed up. Now
|
|
; jump to the function now that we have the address
|
|
|
|
pop bx ; Function ordinal in Bx
|
|
xor bh,bh
|
|
|
|
pop si ; Restore registers
|
|
|
|
; jump to function with stack adjusted just like a normal call.
|
|
|
|
jmp FunctionTable[Bx]
|
|
|
|
|
|
LoadDLL endp
|
|
|
|
end
|
|
|
|
endm
|