Windows2000/private/windows/media/avi/avifile/acmstub.asm
2020-09-30 17:12:32 +02:00

452 lines
8.5 KiB
NASM

page ,132
title ACMSTUB.ASM
;* *
;* MODULE : ACMSTUB.ASM *
;* *
;* DESCRIPTION : Provide functions to allow run-time linking to *
;* the ACM. *
;* *
;* COPYRIGHT : Copyright 1991, Microsoft Corp. All Rights Reserved.*
;* *
;* Author: David Maymudes *
;* Based on similar code for MMSYSTEM by: *
;* Todd Laney and Matt Saettler - Multimedia Systems *
;* *
; Documentation (such as it is)
; Call function as you normally would. Include MSACM.H normally.
; However, instead of linking to MSACM.LIB, link to ACMSTUB.OBJ
; All functions will return error conditions if MSACM.DLL is not present.
; Because I'm lazy, the calling routine has to load the module into
; memory before calling any of this.
page
.286
?PLM=1 ; PASCAL Calling convention is DEFAULT
?WIN=0 ; Windows calling convention
.xlist
include cmacros.inc
.list
; CONSTANT DECLARATIONS
ifndef FALSE
FALSE equ 0
endif
ifndef NULL
NULL equ 0
endif
ifndef MMSYSERR_ERROR
MMSYSERR_ERROR equ 1
endif
; EXTERN DECLARATIONS
externFP OutputDebugString
externFP _wsprintf
externFP GetProcAddress
externFP GetModuleHandle
;ifdef DEBUG
; externFP __dprintf ; in DPRINTF.C
;endif
; STRUCTURE DECLARATIONS
LONG struc
lo dw ?
hi dw ?
LONG ends
FARPOINTER struc
off dw ?
sel dw ?
FARPOINTER ends
PROCENTRY struc
curproc dd ? ; see parameters to macros, below
ordinal dw ?
numparms dw ?
errret dd ?
ifdef DEBUG
szProc db ?
endif
PROCENTRY ends
MODENTRY struc
hModule dw ?
szModule db ?
MODENTRY ends
; DATA SEGMENT DECLARATIONS
ifndef SEGNAME
SEGNAME equ <_TEXT>
endif
createSeg %SEGNAME, CodeSeg, word, public, CODE
page
; MACRO DECLARATIONS
; MACRO DOUT
; Parms:
; text Text to output using OutputDebugString when DEBUG is defined
; Text is automatically appended with CR/LF
DOUT macro text
local string_buffer
ifdef DEBUG ; only do output if DEBUG is defined
_DATA segment
string_buffer label byte
db "&text&",13,10,0
_DATA ends
pusha
push DataBASE
push DataOFFSET string_buffer
call OutputDebugString
popa
endif
endm
; MACRO Begin_Module_Table
; Parms:
; Module_Name Name of Module to Run-Time-Link
; defines <Module_Name>_Proc Macro
; Use End_Module_Table to close
Begin_Module_Table MACRO Module_Name
sBegin DATA
ifdef DEBUG
public Module_Name&_Module_Table
endif
Module_Name&_Module_Table label word
dw -1 ; hModule
db "&Module_Name&",0
sEnd Data
sBegin CodeSeg
assumes cs,CodeSeg
assumes ds,Data
assumes es,nothing
ifdef DEBUG ; make public so debugger is aware of it
public load&Module_Name
endif
; entry:
; DS:BX --> ProcEntry for API being called
load&Module_Name& proc far
; stack frame is not modified or copied
; vars are still in place
mov ax,DataOFFSET Module_Name&_Module_Table
jmp LoadModuleStub
load&Module_Name& endp
sEnd CodeSeg
page
; MACRO <Module_Name>_Proc
; Parms:
; Name of procedure Name of procedure to emulate
; ordinal of exported proc
; # of stack parms use 0 for CDECL routines
; error return value default error value for use by FailAPIStub
; fail proc defaults to FailAPIStub if not specified
; use custom 'fail' proc to replace functionlity
; if specified module/proc not found in system
Module_Name&_Proc macro ProcName, Ordinal, sizestack, errret, failproc
sBegin Data
ifdef DEBUG
public Module_Name&&Ordinal&
endif
Module_Name&&Ordinal& label word
ifb <failproc>
dd load&Module_Name
dw &Ordinal
dw &sizestack
dd &errret
else
dd load&Module_Name
dw &Ordinal
dw -1
dd &failproc
endif
ifdef DEBUG
db "&ProcName&",0
endif
sEnd Data
sBegin CodeSeg
assumes cs,CodeSeg
assumes ds,Data
assumes es,nothing
public &ProcName&
&ProcName& proc far
; stack frame is not modified or copied
; vars are still in place
mov bx,DataOFFSET Module_Name&&Ordinal&
jmp [bx].curproc ; current proc
&ProcName& endp
sEnd CodeSeg
endm
endm
page
; MACRO End_Module_Table
; Parms
; Module_Name Must be the same as in Begin_Module_Table
End_Module_Table macro Module_Name
purge Module_Name&_Proc
endm
; Helper routines for SHELL
sBegin CodeSeg
assumes cs,CodeSeg
assumes ds,Data
assumes es,nothing
; FailApiStub
; Default handler if Module or Proc Address is not found.
; returns default error code
; entry:
; DS:BX --> PROCENTRY
FailApiStub proc far
pop dx ; get return addr
pop ax
add sp,[bx].numparms ; remove params from stack
push ax ; restore return addr
push dx
mov ax,[bx].errret.lo ; return fail code
mov dx,[bx].errret.hi
retf
FailApiStub endp
; LoadModuleStub
; Initial handler for all procs. Attempts to load module (if not already
; loaded) and then gets proc address. If any errors, sets curproc to
; failproc for 'unavailable' processing.
; If successful, then sets curproc to imported function and calls it.
; entry:
; DS:BX --> PROCENTRY
; DS:AX --> MODENTRY
; NOTE: Assumes module is already loaded
; To be totally general:
; if can't GetModuleHandle(),
; needs to do a OpenFile(OF_EXIST,...) + LoadLibrary()
; needs to FreeLibrary() all DLLs at end/exit
LoadModuleStub proc far
ifdef DEBUG
pusha
sub sp,128
mov si,sp
mov di,ax ; DS:DI --> MODENTRY
push [bx].ordinal ; %d
lea ax,[bx].szProc ; %ls
push ds
push ax
lea ax,[di].szModule ; %ls
push ds
push ax
lea ax,format_string ; format string
push cs
push ax
push ss ; buffer
push si
call _wsprintf
add sp,9*2 ; clear 9 words
cCall OutputDebugString,<ss,si>
add sp,128
popa
jmp @f
format_string:
db "Linking %ls!%ls@%d",13,10,0
@@:
endif
pusha
mov si,ax ; ds:[si] --> MODENTRY
mov di,bx ; ds:[di] --> PROCENTRY
mov ax,[si].hModule
or ax,ax
jz LoadModuleStubFail ; module does not exist
cmp ax,-1
jne LoadModuleStubGetProc
lea ax,[si].szModule
cCall GetModuleHandle, <ds,ax>
mov [si].hModule,ax
or ax,ax
jz LoadModuleStubLoad
LoadModuleStubGetProc:
cCall GetProcAddress,<ax,0,[di].ordinal>
or dx,dx
jz LoadModuleStubFail
LoadModuleStubDone:
mov [di].curproc.lo,ax
mov [di].curproc.hi,dx
popa
jmp [bx].curproc
LoadModuleStubLoad:
;; call load library here after verifying with OpenFile()
; for now, fall through to error
LoadModuleStubFail:
DOUT <*** API not found! ***>
mov ax,CodeSegOFFSET FailApiStub
mov dx,cs
cmp [di].numparms,-1 ; do we have a fail proc?
jne LoadModuleStubDone ; no...use FailApiStub
mov ax,[di].errret.lo ; yes..it is stored in errret
mov dx,[di].errret.hi
jmp short LoadModuleStubDone ; use it
LoadModuleStub endp
sEnd CodeSeg
page
; CODE and DATA
; Define SHELL Run-Time-Load Table
Begin_Module_Table MSACM
MSACM_Proc acmGetVersion 7, 0, 0
MSACM_Proc acmFormatChoose 40, 4, MMSYSERR_ERROR
MSACM_Proc acmMetrics 8, 8, MMSYSERR_ERROR
; end the MSACM R-T-L table
End_Module_Table MSACM
; STUB ROUTINES
; no stub routines for MSACM.
end