page ,132 title OLE2STUB.ASM ;*********************************************************************** ;* * ;* MODULE : OLE2STUB.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 OLE2.H normally. ; However, instead of linking to OLE2.LIB, link to OLE2STUB.OBJ ; ; All functions will return error conditions if OLE2.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 _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 _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 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, add sp,128 popa jmp short @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, mov [si].hModule,ax or ax,ax jz LoadModuleStubLoad LoadModuleStubGetProc: cCall GetProcAddress, 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 OLE2 Run-Time-Load Table Begin_Module_Table OLE2 OLE2_Proc OleInitialize 2, 4, 8000ffffh OLE2_Proc OleUninitialize 3, 0, 8000ffffh OLE2_Proc ReleaseStgMedium 32, 4, 8000ffffh OLE2_Proc OleSetClipboard 49, 4, 8000ffffh OLE2_Proc OleGetClipboard 50, 4, 8000ffffh OLE2_Proc OleFlushClipboard 76, 0, 8000ffffh ; ; end the OLE2 R-T-L table End_Module_Table OLE2 ;********************************************************************* ; STUB ROUTINES ;********************************************************************* ; no stub routines for OLE2. ;********************************************************************* ; 'C' RUNTIME HACK ;********************************************************************* sBegin Code assumes cs,Code assumes ds,nothing assumes es,nothing externFP GlobalAlloc externFP GlobalLock externFP GlobalFree .386 ; ; stutpid hack to get GetDGOUP to work!!! ; public ___ExportedStub ___ExportedStub: mov ax,DataBASE %out ***************** WHY IS THE C RUNTIME BROKEN??? GMEM_MOVEABLE equ 0002h public __fmalloc __fmalloc proc far pop eax pop bx push bx push eax GMEM_SHARE equ 2000h GMEM_MOVEABLE equ 0002h cCall GlobalAlloc, cCall GlobalLock, retf __fmalloc endp public __ffree __ffree proc far pop eax ; return addr pop ebx ; sel:off push ebx push eax shr ebx,16 cCall GlobalFree, retf __ffree endp sEnd end