windows-nt/Source/XPSP1/NT/base/mvdm/thunk/gdithk.inc
2020-09-26 16:20:57 +08:00

2397 lines
67 KiB
PHP

CodeData equ <THUNK16BCodeData>
include thkrp.inc
include cbcheck.inc
include thkframe.inc
include public.inc
include thkmacro.inc
include struc.inc
include cbcid.inc
include gdicbid.inc
externDef PrivateEscape:near16
externDef CALLBACK_BODY_16:far16
externDef Escape:far16
externDef AllocCallback:far16
externDef MapLS:far16
externDef UnmapLS:far16
externDef GlobalAlloc:far16
externDef GlobalSize:far16
externDef GlobalFree:far16
externDef GlobalLock:far16
externDef GlobalUnlock:far16
externDef GetTextExtentPoint:far16
ifdef DEBUG
externDef _wsprintf:far16
externDef OutputDebugString:far16
endif
externDef AllocSelectorArray:far16
externDef SetSelectorBase:far16
externDef SetSelectorLimit:far16
externDef FreeSelector:far16
externDef SelectorAccessRights:far16
externDef GetLastError:far16
ilObjType equ 2
ObjPrivate equ 2000H
Stock equ 8000H
INT_OBJ_FLAGS equ (Stock or ObjPrivate)
INT_MIN_OBJ equ 4f47h
INT_OBJ_PEN equ 4f47h
INT_OBJ_BRUSH equ 4f48h
INT_OBJ_FONT equ 4f49h
INT_OBJ_PALETTE equ 4f4ah
INT_OBJ_BITMAP equ 4f4bh
INT_OBJ_RGN equ 4f4ch
INT_OBJ_DC equ 4f4dh
INT_OBJ_IC equ 4f4eh
INT_OBJ_DISABLED_DC equ 4f4fh
INT_OBJ_METADC equ 4f50h
INT_OBJ_METAFILE equ 4f51h
INT_OBJ_MF equ 4f52h
INT_MAX_OBJ equ 4f52h
;; Writes message to debug port.
;;
;; Usage:
;; DPRINT "I'm feeling buggy."
;;
DPRINT macro string
local mes, skip_mes
jmp skip_mes
mes db &string&,13,10,0
skip_mes:
push eax ;Save all registers not preserved by PASCAL format.
push ebx
push ecx
push edx
push cs ;Arg: OutputDebugString(lpstr)
push offset mes
call OutputDebugString
pop edx
pop ecx
pop ebx
pop eax
endm ;DPRINT
RECT16_SIZE equ 8
POINT16_SIZE equ 4
LOGFONT32_SIZE equ 60
BITMAP32_SIZE equ 24
DIBSECTION32_SIZE equ 84
BITMAP16 struc
bm16_Type dw ?
bm16_Width dw ?
bm16_Height dw ?
bm16_WidthBytes dw ?
bm16_Planes db ?
bm16_BitsPixel db ?
bm16_Bits dd ?
BITMAP16 ends
BITMAP32 struc
bm32_Type dd ?
bm32_Width dd ?
bm32_Height dd ?
bm32_WidthBytes dd ?
bm32_Planes dw ?
bm32_BitsPixel dw ?
bm32_Bits dd ?
BITMAP32 ends
ABC16 struc
abcA dw ?
abcB dw ?
abcC dw ?
ABC16 ends
fLocalFlag equ fGdiLog16
; Corresponds to the 32 bit BITMAPINFOHEADER structure.
BMIH32 struc
bi32_Size dd ?
bi32_Width dd ?
bi32_Height dd ?
bi32_Planes dw ?
bi32_BitCount dw ?
bi32_Compression dd ?
bi32_SizeImage dd ?
bi32_XPelsPerMeter dd ?
bi32_YPelsPerMeter dd ?
bi32_ClrUsed dd ?
bi32_ClrImportant dd ?
BMIH32 ends
; Corresponds to the 32-bit BITMAPCOREHEADER structure.
BMCH32 struc
bc32_Size dd ?
bc32_Width dw ?
bc32_Height dw ?
bc32_Planes dw ?
bc32_BitCount dw ?
BMCH32 ends
; Corresponds to the 32-bit BITMAPV4HEADER structure.
BMV4H32 struc
bv432_Size dd ?
bv432_Width dd ?
bv432_Height dd ?
bv432_Planes dw ?
bv432_BitCount dw ?
bv432_Compression dd ?
bv432_SizeImage dd ?
bv432_XPelsPerMeter dd ?
bv432_YPelsPerMeter dd ?
bv432_ClrUsed dd ?
bv432_ClrImportant dd ?
bV432_RedMask dd ?
bV432_GreenMask dd ?
bV432_BlueMask dd ?
bV432_AlphaMask dd ?
bV432_CSType dd ?
bV4Endpoints db 36 dup (?)
bV4GammaRed dd ?
bV4GammaGreen dd ?
bV4GammaBlue dd ?
BMV4H32 ends
BMV5H32 struc
bv532_Size dd ?
bv532_Width dd ?
bv532_Height dd ?
bv532_Planes dw ?
bv532_BitCount dw ?
bv532_Compression dd ?
bv532_SizeImage dd ?
bv532_XPelsPerMeter dd ?
bv532_YPelsPerMeter dd ?
bv532_ClrUsed dd ?
bv532_ClrImportant dd ?
bV532_RedMask dd ?
bV532_GreenMask dd ?
bV532_BlueMask dd ?
bV532_AlphaMask dd ?
bV532_CSType dd ?
bV5Endpoints db 36 dup (?)
bV5GammaRed dd ?
bV5GammaGreen dd ?
bV5GammaBlue dd ?
bV5Intent dd ?
bV5ProfileData dd ?
bV5ProfileSize dd ?
bV5Reserved dd ?
BMV5H32 ends
THUNK16B SEGMENT WORD USE16 PUBLIC 'CODE'
IF 0
REPACK_DEVMODE_32_16 macro
externDef Repack_Devmode_32_16_Proc:near16
call Repack_Devmode_32_16_Proc
endm
;-----------------------------------------------------------------------;
; Repack_Pevmode_32_16_Proc
;
; Entry:
; DS:ESI --> 32-bit source (ESI might be flat offset)
; ES:EDI --> 16-bit destination (EDI is zero-extended from DI)
; direction flag cleared
;-----------------------------------------------------------------------;
Repack_Devmode_32_16_Proc proc near public
; local done
;Move the common part as a single block move.
MoveBytes <(size DEVMODECOMMON)>
;Update the dmSize field
;;;; mov es:[di].(dmSize - (size DEVMODECOMMON)),size DEVMODE16
;!!!Clear out any win32-only flags
;and es:[di].(dmFields - (size DEVMODECOMMON)),0FFFFh
;Insert win16-only fields. EDI points to the byte after
;DEVMODECOMMON. Afterwards, will point to byte after DEVMODE16.
;ZeroBytes <((size DEVMODE16) - (size DEVMODECOMMON))>
;Skip over the extra win32 fields. ESI still points to the byte
;after DEVMODECOMMON.
add esi,(size DEVMODE32) - (size DEVMODECOMMON)
;Move the driver-dependent part. EDI points to the byte after
;DEVMODE16.
mov cx,es:[di].(dmDriverExtra - (size DEVMODE16))
jcxz done
movzx ecx,cx
mov edx,ecx
shr cx,2
and dx,3
rep movs dword ptr es:[edi],dword ptr ds:[esi]
mov cx,dx
rep movs byte ptr es:[edi],byte ptr ds:[esi]
done:
ret
Repack_Devmode_32_16_Proc endp
ENDIF
DIB_BITS_SIZE macro
externDef Dib_Bits_Size_Proc:near16
call Dib_Bits_Size_Proc
endm
;-----------------------------------------------------------------------;
; Dib_Bits_Size_Proc
;
; Inputs:
; eax: linear address of 32-bit BITMAPINFOHEADER (or BITMAPCOREHEADER)
; struct.
;
; Output:
; ecx: inferred size of bitmap data, or 0 for failure.
;
; Formula is:
; if bi32_Compression != (BI_RGB | BI_BITFIELDS)
; size = bi32_SizeImage
; else
; size = ((Width * BitCount + 31) / 32) * 4 * Height * Planes
;-----------------------------------------------------------------------;
Dib_Bits_Size_Proc proc near public
; local exit,fail_exit,use_formula
; local bitmapcoreheader,bitmapinfoheader
push ds
mov ds,FlatData
mov esi,eax
; DPRINT "DIB_BIT_SIZE: Computing bitmap data size."
; int 3
mov eax, dword ptr [esi]
cmp eax, SIZEOF BMIH32
je bitmapinfoheader
cmp eax, SIZEOF BMV4H32
je bitmapinfoheader
cmp eax, SIZEOF BMV5H32
je bitmapinfoheader
cmp eax, SIZEOF BMCH32
je bitmapcoreheader
; int 3
jmp fail_exit
bitmapcoreheader:
movzx eax, [esi].bc32_Width
movzx ebx,[esi].bc32_BitCount
mul ebx
jc fail_exit
add eax, 31
jc fail_exit
shr eax, 5 ;Divide by 32 (and exorcise remainder!)
shl eax, 2 ;Multiply by 4
movzx ecx, [esi].bc32_Height
mul ecx
jc fail_exit
movzx ebx,[esi].bc32_Planes
mul ebx
mov ecx,eax
jnc exit
jmp fail_exit
bitmapinfoheader:
cmp dword ptr [esi].bi32_Compression, BI_RGB
je use_formula
cmp dword ptr [esi].bi32_Compression, BI_BITFIELDS
je use_formula
mov ecx, [esi].bi32_SizeImage
jmp exit
use_formula:
; DPRINT "DIB_BIT_SIZE: Using formula."
mov eax, [esi].bi32_Width
xor ebx,ebx
mov bx,[esi].bi32_BitCount
mul ebx
jc fail_exit
add eax, 31
jc fail_exit
shr eax, 5 ;Divide by 32 (and exorcise remainder!)
shl eax, 2 ;Multiply by 4
mov ecx,[esi].bi32_Height
test ecx,ecx ;top down dibs ?
jns got_height
neg ecx ;make it positive.
got_height:
mul ecx
jc fail_exit
xor ebx,ebx
mov bx,[esi].bi32_Planes
mul ebx
mov ecx,eax
jnc exit
fail_exit:
xor ecx,ecx
exit:
; int 3
pop ds
ret
Dib_Bits_Size_Proc endp
THUNK16B ENDS
;-----------------------------------------------------------------------;
; UNPACK__GETTEXTMETRICSA_lpMetrics
;-----------------------------------------------------------------------;
UNPACK__GETTEXTMETRICSA_lpMetrics macro x, y
PACK_TEXTMETRIC_16_32
endm
;-----------------------------------------------------------------------;
; PUSH__SETABORTPROC_pfnAbort
;-----------------------------------------------------------------------;
PUSH__SETABORTPROC_pfnAbort macro iOffset, iTempOffset
push dword ptr [bp+iOffset]
push dword ptr CBID_ABORTPROC
call AllocCallback
push dx
push ax
endm
;-----------------------------------------------------------------------;
; PACK__STARTDOCA_lpdi
;-----------------------------------------------------------------------;
OLD_DOCINFO_SIZE equ 12
NEW_DOCINFO_SIZE equ 20
PACK__STARTDOCA_lpdi macro iOffset, iTempOffset
lods dword ptr ds:[esi]
; ax == lpdi->cbSize
; if cbSize is not the new sizeof(DOCINFO),
; assume lpdi is a 3.x style DOCINFO
cmp ax,NEW_DOCINFO_SIZE
je @F
mov ax,OLD_DOCINFO_SIZE
@@:
push ax
sub ax,2
stosw ;;cbSize (int)
MAP_POINTER LOCAL__STARTDOCA_lpszDocNameTemp ;;PLUGGED lpszDocName
MAP_POINTER LOCAL__STARTDOCA_lpszOutputTemp ;;PLUGGED lpszOutput
pop ax
cmp ax,OLD_DOCINFO_SIZE
je @F
MAP_POINTER LOCAL__STARTDOCA_lpszDatatypeTemp
lods dword ptr ds:[esi]
stosd ;;fwType
@@:
endm
;-----------------------------------------------------------------------;
; UNPACK__STARTDOCA_lpdi
;-----------------------------------------------------------------------;
UNPACK__STARTDOCA_lpdi macro iOffset, iTempOffset
pushd LOCAL__STARTDOCA_lpszDocNameTemp
call UnmapLS
pushd LOCAL__STARTDOCA_lpszOutputTemp
call UnmapLS
pushd LOCAL__STARTDOCA_lpszDatatypeTemp
call UnmapLS
endm
;-----------------------------------------------------------------------;
; body_THKESCAPE
;-----------------------------------------------------------------------;
body_THKESCAPE macro
bp_hdc equ <bp_top>
bp_nEscape equ <bp_top+ 4>
bp_cbInput equ <bp_top+ 8>
bp_lpInData equ <bp_top+12>
bp_lpOutData equ <bp_top+16>
push word ptr bp_hdc
push word ptr bp_nEscape
push word ptr bp_cbInput
push dword ptr bp_lpInData
push dword ptr bp_lpOutData
call PrivateEscape
endm
;-----------------------------------------------------------------------;
; body_SETMETAFILEBITSEX
;-----------------------------------------------------------------------;
body_SETMETAFILEBITSEX macro
local exit
bp_nSize equ <bp_top>
bp_lpvData equ <bp_top+4>
bp_hmem equ <[bp-2]>
sub sp,2 ;make space for bp_hmem
; Protect ourselves -- no pointer or no bytes to copy mean no reason to
; call Win3.1.
mov eax,bp_lpvData
or eax,eax
jz exit
mov eax,bp_nSize
or eax,eax
jz exit
; Allocate a global handle to pass to Win3.1. If can't get handle return
; error.
;
;!!! This memory should be deleted in DeleteMetaFile. If the app never
; calls DeletMetaFile, it will be deleted when the process dies because
; GlobalAlloc tags the memory with the process that allocated it.
pushw GMEM_MOVEABLE
push eax
call GlobalAlloc
movzx eax,ax ;prepare for error return code
or ax,ax
jz exit
; Copy the data from the input buffer to the global memory we allocated.
mov bp_hmem,ax
push ds
mov ds,FlatData ;DS:ESI --> source
mov esi,bp_lpvData ;
mov es,ax ;ES:EDI --> destination
xor edi,edi ;
; Compute dword (ECX) and byte (DX) counts. We can use DX because it will
; contain 0, 1, or 2. When we copy bytes, the high word of ECX will already
; be zero from the dword-copy, so we only have to update CX for the
; byte-copy.
mov ecx,dword ptr bp_nSize
mov dx,cx
shr ecx,2
and dx,3
cld
rep movs dword ptr es:[edi], dword ptr ds:[esi]
mov cx,dx
rep movs byte ptr es:[edi], byte ptr ds:[esi]
pop ds
; Since Win32 GetMetaFileBitsEx actually returns the bits for a disk
; metafile, we must patch the metafile header now. (This is compatible
; with NT.)
xor edi,edi
mov word ptr es:[edi], 1 ; METAHEADER.mtType = MEMORYMETAFILE
; !!! SetMetaFileBitsBetter just returns the handle passed in. With
; this assumption, we will be passing back the handle allocated above
; with GlobalAlloc.
push word ptr bp_hmem
call SetMetaFileBitsBetter
movzx eax,ax ;prepare return code
; EAX = return code (global memory handle)
exit:
endm
;-----------------------------------------------------------------------;
; CREATEBITMAP_COMMON:
;
; Common thunk code for CreateBitmap() and CreateBitmapIndirect().
; Tiles the bit buffer (if any), creates equivalent Win16 BITMAP
; structure on stack and calls Win16 CreateBitmapIndirect().
;
; Note: All device-dependent bitmap scan lines are word-padded (not
; dword-padded) even in Win32 (decided this with DavidW: 2/93)
;
; Entry points:
; eax = 0:32 pointer to Win32 BITMAP structure.
;
; Exit:
; eax = result of Win16 CreateBitmapIndirect() if successfully
; thunked arguments. 0 if unsuccessful.
;
;-----------------------------------------------------------------------;
CREATEBITMAP_COMMON macro
local exit,fail_exit,dwFreeInfo,wOldDS
; DPRINT "Just entered CREATEBITMAP_COMMON. eax -> Win32 BITMAP"
; int 3
push bp
mov bp,sp
push ds ;Save ds
xor edx,edx ;New local (to store result of TILE_BUFFER)
push edx
wOldDS equ word ptr [bp - 2]
dwFreeInfo equ dword ptr [bp - 6]
mov ds,FlatData
mov esi,eax
;Infer the size of the bit buffer:
;
; size = ((width * bitspixel + 15) / 16) * 2 * height * planes
;
mov ax,[esi].bm32_BitsPixel
movzx eax,ax
mul [esi].bm32_Width
jc fail_exit
add eax,15
jc fail_exit
shr eax,4
shl eax,1
mov ebx,eax ;Tuck WidthBytes in safe register
mul [esi].bm32_Height
jc fail_exit
xor ecx,ecx
mov cx,[esi].bm32_Planes
mul ecx
jc fail_exit
mov ecx,eax
; assert(ecx == size of bm32_Bits buffer)
sub sp,14 ;make room for a Win16 BITMAP structure
mov ax,ss
mov es,ax
mov di,sp
; repack Win32 BITMAP (ds:esi) into Win16 BITMAP (es:di)
lodsd ds:[esi] ;Type (DWORD->WORD)
stosw es:[di]
lodsd ds:[esi] ;Width (DWORD->WORD)
stosw es:[di]
lodsd ds:[esi] ;Height (DWORD->WORD)
stosw es:[di]
add esi,4 ;WidthBytes (DWORD->WORD)
mov ax,bx ; Replace with our own computed value
stosw es:[di]
lodsw ds:[esi] ;Planes (WORD->BYTE)
stosb es:[di]
lodsw ds:[esi] ;BitsPixel (WORD->BYTE)
stosb es:[di]
lodsd ds:[esi] ;lpBits (0:32 -> tiled 0:16)
; DPRINT "CREATEBITMAP_COMMON: About to tile buffer"
; int 3
push es ;Save registers that TILE_BUFFER
push di ; trashes
; assert (eax == 0:32 ptr to bit data, ecx == inferred size of bit buffer)
TILE_BUFFER
pop di
pop es
jc fail_exit
mov dwFreeInfo,ecx
stosd es:[di]
mov bx,sp
push ss ;Arg: CreateBitmapIndirect(lpbm)
push bx ;^^^
; DPRINT "CREATEBITMAP_COMMON: About to call Win16 API."
; int 3
call CreateBitmapIndirect
movzx eax,ax
push eax ;save API result
mov ecx,dwFreeInfo
UNTILE_BUFFER
pop eax ;restore API result
jmp exit
fail_exit:
xor eax,eax
exit:
mov ds,wOldDS ;do this before restoring sp!
mov sp,bp
pop bp
endm; CREATEBITMAP_COMMON
;-----------------------------------------------------------------------;
; body_CREATEBITMAPINDIRECT
;-----------------------------------------------------------------------;
body_CREATEBITMAPINDIRECT macro
mov eax,[bp_top] ;eax == 0:32 pointer to Win32 BITMAP
CREATEBITMAP_COMMON
endm
;-----------------------------------------------------------------------;
; body_CREATEBITMAP
;
; Create equivalent Win32 BITMAP structure on stack and call
; same code that CreateBitmapIndirect() does.
;-----------------------------------------------------------------------;
body_CREATEBITMAP macro
local bp_nWidth, bp_nHeight, bp_nPlanes, bp_nBitCount, bp_lpBits
bp_nWidth equ [bp_top]
bp_nHeight equ [bp_top+4]
bp_nPlanes equ [bp_top+8]
bp_nBitCount equ [bp_top+12]
bp_lpBits equ [bp_top+16]
; Create an equivalent Win32 BITMAP structure on stack and pass it
; to CreateBitmapIndirect
pushd bp_lpBits
pushw bp_nBitCount
pushw bp_nPlanes
pushd 0 ;Dummy WidthBytes (CREATEBITMAPCOMMON ignores it)
pushd bp_nHeight
pushd bp_nWidth
pushd 0 ;Type
mov ax,sp
push ss ;Arg: MapSL(sel:off)
push ax ;^^^
call MapSL ;OK: ss is never a movable handle here.
CREATEBITMAP_COMMON
mov sp,bp
endm ;body_CREATEBITMAP
;-------------------------------------------------------------------------
; RAWPACK_GETBITMAPBITS
;-------------------------------------------------------------------------
RAWPACK__GETBITMAPBITS_lpBits macro lpBits,lp1616
local exit,fail_exit
mov eax,[bp + &lpBits]
or eax,eax
jz fail_exit
mov ecx,[bp_top + 4] ;dwCount (size of buffer)
or ecx,ecx
jz fail_exit ;is this the right action??
TILE_BUFFER
mov [bp - &lp1616&],eax
mov LOCAL__GETBITMAPBITS_dwFreeInfo,ecx
jmp exit
fail_exit:
mov sp,bp
xor eax,eax
ERRCHK_EXIT 0,87,Exit_12
exit:
endm ;RAWPACK_GETBITMAPBITS_lpBits
;-------------------------------------------------------------------------
; RAWUNPACK_GETBITMAPBITS
;-------------------------------------------------------------------------
RAWUNPACK__GETBITMAPBITS_lpBits macro lpBits,lp1616
mov ecx,LOCAL__GETBITMAPBITS_dwFreeInfo
UNTILE_BUFFER
endm ;RAWUNPACK_GETBITMAPBITS
;-------------------------------------------------------------------------
; RAWPACK_SETBITMAPBITS
;-------------------------------------------------------------------------
RAWPACK__SETBITMAPBITS_lpBits macro lpBits,lp1616
local exit,fail_exit
mov eax,[bp + &lpBits]
or eax,eax
jz fail_exit
mov ecx,[bp_top + 4] ;dwCount (size of buffer)
or ecx,ecx
jz fail_exit ;(fail return or 0 bytes copied: it's the same)
TILE_BUFFER
mov [bp - &lp1616&],eax
mov LOCAL__SETBITMAPBITS_dwFreeInfo,ecx
jmp exit
fail_exit:
mov sp,bp
xor eax,eax
ERRCHK_EXIT 0,87,Exit_12
exit:
endm ;RAWPACK_SETBITMAPBITS
;-------------------------------------------------------------------------
; RAWUNPACK_SETBITMAPBITS
;-------------------------------------------------------------------------
RAWUNPACK__SETBITMAPBITS_lpBits macro lpBits,lp1616
mov ecx,LOCAL__SETBITMAPBITS_dwFreeInfo
UNTILE_BUFFER
endm ;RAWUNPACK_SETBITMAPBITS
;-----------------------------------------------------------------------;
; body_DELETEMETAFILE
;-----------------------------------------------------------------------;
body_DELETEMETAFILE macro
local exit
bp_hmf equ <bp_top>
; !!! Determine whether or not to delete directly!
push bp_hmf
call DeleteMetaFile
cwde
exit:
endm
IF 0
;-----------------------------------------------------------------------;
; body_CREATEICA
;-----------------------------------------------------------------------;
body_CREATEICA macro
local exit
local repack_devmode
local push_callframe
bp_lpszDriver equ <bp_top>
bp_lpszDevice equ <bp_top+4>
bp_lpszOutput equ <bp_top+8>
bp_lpdm equ <bp_top+12>
bp_lpdmTmp equ <dword ptr [bp-4]>
bp_hdm equ < word ptr [bp-6]>
bp_lpszDriverTmp equ <dword ptr [bp-10]>
bp_lpszDeviceTmp equ <dword ptr [bp-14]>
bp_lpszOutputTmp equ <dword ptr [bp-18]>
sub eax,eax
push eax ;bp_lpdmTmp
push ax ;bp_hdm
push eax ;bp_lpszDriverTmp
push eax ;bp_lpszDeviceTmp
push eax ;bp_lpszOutputTmp
mov ecx,bp_lpdm
or ecx,ecx
jnz repack_devmode
jmp push_callframe
; We have to repack the DEVMODE structure. Compute the size needed,
; allocate it, setup pointers and invoke the macro to do the copying.
repack_devmode:
push word ptr GMEM_MOVEABLE
mov es,FlatData
movzx eax,es:[ecx].dmSize
movzx ecx,es:[ecx].dmDriverExtra
add eax,ecx
push eax
call GlobalAlloc
movzx eax,ax ;prepare for error
or ax,ax
jz exit
mov word ptr bp_hdm,ax
; Set up DS:ESI
; ES:EDI
push ds
mov ds,FlatData
mov esi,bp_lpdm
mov es,ax
sub edi,edi
mov word ptr bp_lpdmTmp[0],di
mov word ptr bp_lpdmTmp[2],ax
cld
REPACK_DEVMODE_32_16
pop ds
push_callframe:
push dword ptr bp_lpszDriver
call MapLS ;PLUGGED
mov bp_lpszDriverTmp,eax
push eax
push dword ptr bp_lpszDevice
call MapLS ;PLUGGED
mov bp_lpszDeviceTmp,eax
push eax
push dword ptr bp_lpszOutput
call MapLS ;PLUGGED
mov bp_lpszOutputTmp,eax
push eax
push bp_lpdmTmp
call CreateIC
movzx eax,ax
push eax
mov cx,bp_hdm
or cx,cx
jz @F
push cx
call GlobalFree
@@:
pushd bp_lpszOutputTmp
call UnmapLS
pushd bp_lpszDeviceTmp
call UnmapLS
pushd bp_lpszDriverTmp
call UnmapLS
pop eax
exit:
endm
ENDIF
;-----------------------------------------------------------------------;
; body_GETOUTLINETEXTMETRICSA
;-----------------------------------------------------------------------;
OUTLINETEXTMETRIC16_SIZEX equ 114+3*32+64
OUTLINETEXTMETRIC32_SIZEX equ 212+3*32+64
body_GETOUTLINETEXTMETRICSA macro
local push_callframe
local exit
bp_hdc equ <bp_top>
bp_cbData equ <bp_top+4>
bp_lpotm equ <bp_top+8>
bp_lpotm16 equ <dword ptr [bp-4]>
bp_lpotm32 equ <dword ptr [bp-8]>
sub eax,eax
push eax ; Make room for lpotm16
push eax ; Make room for lpotm32
cmp dword ptr bp_lpotm, 0 ; Size call?
je push_callframe ; Yes, drop thru
; Make 16bit return buffer
sub sp, OUTLINETEXTMETRIC16_SIZEX
mov word ptr bp_lpotm16[0],sp
mov word ptr bp_lpotm16[2],ss
; Make 32bit temp buffer
sub sp, OUTLINETEXTMETRIC32_SIZEX
mov word ptr bp_lpotm32[0],sp
mov word ptr bp_lpotm32[2],ss
push_callframe:
push word ptr bp_hdc
pushw OUTLINETEXTMETRIC16_SIZEX
push dword ptr bp_lpotm16
call GetOutlineTextMetrics
movzx eax,ax
test eax, eax ; Win16 return success?
jz exit ; No, return NULL
cmp dword ptr bp_lpotm, 0 ; Caller really wants data?
jne unpackotm ; Yes, unpack and copy it to him
add eax, (OUTLINETEXTMETRIC32_SIZE - OUTLINETEXTMETRIC16_SIZE)
jmp exit ; No, add delta and return
unpackotm:
; Unpack the OUTLINETEXTMETRICS structure.
push eax ; Save rc
push ds ; Save ds
xor esi, esi ;
lds si, bp_lpotm16 ; ds:[esi] -> otm16 temp
xor edi, edi ;
les di, bp_lpotm32 ; es:[edi] -> otm32 temp
cld
PACK_OUTLINETEXTMETRIC_16_32
pop ds ; Restore ds (FlatLand)
xor esi, esi ; fs:[esi] -> otm32 temp
lfs si, bp_lpotm32 ;
mov es, FlatData ; es:[edi] -> caller's buffer
mov edi, bp_lpotm ;
mov ecx, bp_cbData ; Copy amount caller requested
rep movsb es:[edi], fs:[esi] ;
pop eax ; Restore rc
exit:
mov sp,bp
endm
;-----------------------------------------------------------------------;
; body_GETOBJECTA
;-----------------------------------------------------------------------;
body_GETOBJECTA macro
local exit
local type_palette
local type_brush
local type_pen
local type_font
local copy_bitmap
local copy_palette
local copy_brush
local copy_pen
local copy_font
local copy_data
local reload_dst
local GO_BUF_SIZE
bp_hObject equ <bp_top>
bp_nCount equ <bp_top+4>
bp_lpObject equ <bp_top+8>
bp_lpObjectTmp equ <dword ptr [bp-4]>
;Make the temporary buffer big enough for 32-bit DIBSECTION, the biggest
;structure returned by GetObjectA32. We will allocate two temporary
;buffers. The first will receive the bits from Win3.1. The second
;will receive the repacked bits, and will then be copied to the output
;buffer.
;
GO_BUF_SIZE equ DIBSECTION32_SIZE
xor eax,eax
push eax ; ptr param #1 bp_lpObjectTmp
sub sp,GO_BUF_SIZE*2 ; alloc two temp buffers
mov word ptr bp_lpObjectTmp[0],sp ; save buffer offset
mov word ptr bp_lpObjectTmp[2],ss ; save buffer selector
; create new call frame and make the call
push word ptr bp_hObject
push word ptr GO_BUF_SIZE ; temp buffer size
push dword ptr bp_lpObjectTmp
call GetObject ; call 16-bit version
cwde
or ax,ax
jz exit ; nothing to unpack
mov si,bp_hObject ; dereference the object & find out
mov cx,INT_OBJ_FONT ; assume it's a font
test si,2 ; is it a moveable handle
jz GO_Branch ; if not it must be a font
mov si,[si] ; what type it is (LMHtoP)
mov cx,[si].ilObjType ;
and ch,HIGH (NOT INT_OBJ_FLAGS) ;
GO_Branch:
mov si,word ptr bp_lpObjectTmp
mov edi,dword ptr bp_lpObject
cld
cmp cx,INT_OBJ_PALETTE
je type_palette
cmp cx,INT_OBJ_BRUSH
je type_brush
cmp cx,INT_OBJ_PEN
je type_pen
cmp cx,INT_OBJ_FONT
je type_font
; Structure conversion code
; Each of these code fragments must leave with
; eax = computed number of bytes for return structure.
; bitmap
or edi,edi
jnz copy_bitmap
mov eax,DIBSECTION32_SIZE ; sizeof DIBSECTION
jmp exit
copy_bitmap:
mov di,ss
mov ds,di
mov es,di
lea di,[si+GO_BUF_SIZE]
lodsw ; bmType
cwde
stosd
lodsw ; bmWidth
mov cx,ax
cwde
stosd
lodsw ; bmHeight
cwde
stosd
lodsw ; bmWidthBytes
cwde
stosd ;store it
lodsb ; bmPlanes
cbw
stosw
lodsb ; bmBitsPixel
cbw
stosw
; the bmBits field will be non NULL for CreateDIBSection bitmaps and we need
; to convert that to a flat pointer.
lodsd ; get bmBits
or eax,eax ; is it null ?
jz short @f ; yes, no translation needed.
push eax ; 16:16 pointer
call MapSL ; convert to flat.
@@:
stosd ; save.
; what follows now is the DIBSECTION structure minus the BITMAP structure.
; however, all the fields here are properly aligned and can be moved in one shot.
mov cx,(DIBSECTION32_SIZE - BITMAP32_SIZE)/4
.errnz (DIBSECTION32_SIZE - BITMAP32_SIZE) and 3
rep movsd
mov eax,DIBSECTION32_SIZE ; bytes generated thus far.
jmp copy_data
type_font:
or edi,edi
jnz copy_font
mov eax,LOGFONT32_SIZE
jmp exit
copy_font:
mov di,ss
mov ds,di
mov es,di
lea di,[si+GO_BUF_SIZE]
PACK_LOGFONT_16_32
mov eax,LOGFONT32_SIZE
jmp copy_data
type_pen:
or edi,edi
jnz copy_pen
mov eax,LOGPEN32_SIZE
jmp exit
copy_pen:
mov di,ss
mov ds,di
mov es,di
lea di,[si+GO_BUF_SIZE]
lodsw ; lopnStyle
cwde
stosd
lodsw ; lopnWidth.x
cwde
stosd
lodsw ; lopnWidth.y
cwde
stosd
movsd ; lopnColor
mov eax,LOGPEN32_SIZE
jmp copy_data
type_brush:
or edi,edi
jnz copy_brush
mov eax,LOGBRUSH32_SIZE
jmp exit
copy_brush:
mov di,ss
mov ds,di
mov es,di
lea di,[si+GO_BUF_SIZE]
lodsw ; lbStyle
cwde
stosd
movsd ; lbColor
lodsw ; lbHatch
cwde
stosd
mov eax,LOGBRUSH32_SIZE
jmp copy_data
type_palette:
or edi,edi
jnz copy_palette
mov eax,4 ; only 4 bytes returned
jmp exit
copy_palette:
mov di,ss
mov ds,di
mov es,di
lea di,[si+GO_BUF_SIZE]
lodsw
movzx eax,ax
stosd
mov eax,4 ; only 4 bytes returned
; Copy converted data to caller's buffer.
; eax = computed byte count
copy_data:
mov ecx,dword ptr bp_nCount
cmp ecx,eax
jb reload_dst
mov ecx,eax
reload_dst:
push ecx ; save return code
mov edx,ecx
shr ecx,2
and edx,3
movzx esi,word ptr bp_lpObjectTmp
add esi,GO_BUF_SIZE
mov es,cs:THUNK16BCodeData
mov es,es:FlatData
mov edi,dword ptr bp_lpObject
rep movs dword ptr es:[edi],dword ptr ds:[esi]
mov ecx,edx
rep movs byte ptr es:[edi],byte ptr ds:[esi]
pop eax ; restore return code directly to eax
exit:
endm
;------------------------------------------------------------------------
; RAWPACK__GETFONTDATA_lpvBuffer
;------------------------------------------------------------------------
; Special cases:
; lpvBuffer == NULL return size of required buffer
; cbData == 0 return size of required buffer
RAWPACK__GETFONTDATA_lpvBuffer macro lpvBufferOff, lp16Off
local fail_exit,exit,cbData
cbData equ <[bp_top + 16]> ;size of lpvBuffer
mov eax,[bp + &lpvBufferOff&]
mov ecx,cbData
TILE_BUFFER
jc fail_exit
mov dword ptr [bp - &lp16Off&], eax
mov dword ptr LOCAL__GETFONTDATA_dwFreeInfo, ecx
jmp exit
fail_exit:
mov sp,bp
xor eax,eax ;GetFontData() returns -1 to indicate
dec eax ; failure.
ERRCHK_EXIT -1,87,Exit_20
exit:
endm ;RAWPACK__GETFONTDATA_lpvBuffer
;------------------------------------------------------------------------
; RAWUNPACK__GETFONTDATA_lpvBuffer
;------------------------------------------------------------------------
RAWUNPACK__GETFONTDATA_lpvBuffer macro lpvBufferOff, lp16Off
mov ecx, dword ptr LOCAL__GETFONTDATA_dwFreeInfo
UNTILE_BUFFER
endm ;RAWUNPACK__GETFONTDATA_lpvBuffer
;------------------------------------------------------------------------
; RAWPACK__GETGLYPHOUTLINEA_lpvBuffer
;------------------------------------------------------------------------
;
; Special cases:
; lpvBuffer == NULL return size of required buffer
; cbData == 0 return size of required buffer
RAWPACK__GETGLYPHOUTLINEA_lpvBuffer macro lpvBufferOff, lp16Off
local fail_exit,exit,cbData
cbData equ <[bp_top + 16]> ;size of user's buffer
mov eax,[bp+&lpvBufferOff&]
mov ecx,cbData
TILE_BUFFER
jc fail_exit
mov dword ptr [bp - &lp16Off&], eax
mov dword ptr LOCAL__GETGLYPHOUTLINEA_dwFreeInfo, ecx
jmp exit
fail_exit:
mov sp,bp
xor eax,eax
dec eax
ERRCHK_EXIT -1,87,Exit_28
exit:
endm ;RAWPACK__GETGLYPHOUTLINEA_lpvBuffer
;------------------------------------------------------------------------
; RAWUNPACK__GETGLYPHOUTLINEA_lpvBuffer
;------------------------------------------------------------------------
RAWUNPACK__GETGLYPHOUTLINEA_lpvBuffer macro lpvBufferOff, lp16Off
mov ecx, LOCAL__GETGLYPHOUTLINEA_dwFreeInfo
UNTILE_BUFFER
endm ;RAWUNPACK__GETGLYPHOUTLINEA_lpvBuffer
;------------------------------------------------------------------------
; RAWPACK__GETKERNINGPAIRSA_lpkp
;------------------------------------------------------------------------
RAWPACK__GETKERNINGPAIRSA_lpkp macro lpkpOff, lp16Off
local fail_exit,exit,cPairs,tile_it
cPairs equ <[bp_top + 4]>
mov eax,[bp+&lpkpOff&]
or eax,eax
jz tile_it
mov ecx,cPairs
or ecx,ecx ;if the buffer size is 0, function
jz fail_exit ; should return 0.
cmp ecx,10000h ;make sure buffer size will fit in
jae fail_exit ; a Win16 INT.
shl ecx,1
mov edx,ecx
shl ecx,1
add ecx,edx
; assert(ecx == cPairs * 6)
tile_it:
; int 3
TILE_BUFFER
; int 3
jc fail_exit
mov dword ptr [bp - &lp16Off&], eax
mov dword ptr LOCAL__GETKERNINGPAIRSA_dwFreeInfo,ecx
jmp exit
fail_exit:
mov sp,bp
xor eax,eax
ERRCHK_EXIT 0,87,Exit_12
exit:
endm ;RAWPACK__GETKERNINGPAIRSA_lpkp
;------------------------------------------------------------------------
; RAWUNPACK__GETKERNINGPAIRSA_lpkp
;------------------------------------------------------------------------
RAWUNPACK__GETKERNINGPAIRSA_lpkp macro lpkpOff, lp16Off
local exit,cPairs,unpack_loop
cPairs equ <[bp_top + 4]>
; int 3
test ax, ax ; Any pairs returned?
jz exit ; No, skip out
mov esi,[bp + &lpkpOff&]
or esi,esi
jz exit
push ds
push es
movzx ecx,ax ; Get # pairs in ecx
mov ds,FlatData
mov ax,ds
mov es,ax
shl ecx,1
mov edx,ecx
shl ecx,1
; assert(edx == 2*cPairs)
; assert(ecx == 4*cPairs)
add esi,edx
add esi,ecx
dec esi
dec esi
; assert(esi == lpkp + 6*cPairs - 2)
mov edi,esi
add edi,edx
; assert(edi == lpkp + 8*cPairs - 2)
shr ecx,2 ;Restore ecx to cPairs
std
unpack_loop:
lodsw ds:[esi]
cwde
dec edi
dec edi
stosd es:[edi]
inc edi
inc edi
movsw es:[edi],ds:[esi]
movsw es:[edi],ds:[esi]
loopd unpack_loop
cld
pop es
pop ds
exit:
mov ecx,dword ptr LOCAL__GETKERNINGPAIRSA_dwFreeInfo
UNTILE_BUFFER
; int 3
endm ;RAWUNPACK__GETKERNINGPAIRSA_lpkp
IF 0
;-----------------------------------------------------------------------;
; body_RESETDCA
;-----------------------------------------------------------------------;
body_RESETDCA macro
local exit
local repack_devmode
local push_callframe
bp_hdc equ <bp_top>
bp_lpdm equ <bp_top+4>
bp_lpdmTmp equ <dword ptr [bp-4]>
bp_hdm equ < word ptr [bp-6]>
sub eax,eax
push eax ;bp_lpdmTmp
push ax ;bp_hdm
mov ecx,bp_lpdm
or ecx,ecx
jnz repack_devmode
jmp push_callframe
; We have to repack the DEVMODE structure. Compute the size needed,
; allocate it, setup pointers and invoke the macro to do the copying.
repack_devmode:
push word ptr GMEM_MOVEABLE
mov es,FlatData
movzx eax,es:[ecx].dmSize
movzx ecx,es:[ecx].dmDriverExtra
add eax,ecx
push eax
call GlobalAlloc
movzx eax,ax ;prepare for error
or ax,ax
jz exit
mov word ptr bp_hdm,ax
; Set up DS:ESI
; ES:EDI
push ds
mov ds,FlatData
mov esi,bp_lpdm
mov es,ax
sub edi,edi
mov word ptr bp_lpdmTmp[0],di
mov word ptr bp_lpdmTmp[2],ax
cld
REPACK_DEVMODE_32_16
pop ds
push_callframe:
push word ptr bp_hdc
push bp_lpdmTmp
call ResetDC
movzx eax,ax
mov cx,bp_hdm
or cx,cx
jz exit
push eax
push cx
call GlobalFree
pop eax
exit:
endm
ENDIF
;---------------------------------------------------------------------------;
; RAWPACK__THKCREATEDIBITMAP_lpInitBits
;---------------------------------------------------------------------------;
RAWPACK__THKCREATEDIBITMAP_lpInitBits macro lpBits, lp1616
local exit,fail_exit
cmp dword ptr [bp_top+8], CBM_INIT
jne exit ;lp1616 already contains 0:0 pointer
mov eax,[bp_top + 16] ;Get pointer to BITMAPINFOHEADER
DIB_BITS_SIZE
or ecx,ecx
jz fail_exit
mov eax,[bp + &lpBits&]
or eax,eax
jz fail_exit
TILE_BUFFER
jc fail_exit
mov dword ptr [bp - &lp1616&], eax
mov dword ptr LOCAL__THKCREATEDIBITMAP_dwFreeInfo, ecx
jmp exit
fail_exit:
mov sp,bp
xor eax,eax
ERRCHK_EXIT 0,87,Exit_24
exit:
endm ;RAWPACK__THKCREATEDIBITMAP_lpInitBits
;---------------------------------------------------------------------------;
; RAWUNPACK__THKCREATEDIBITMAP_lpInitBits
;---------------------------------------------------------------------------;
RAWUNPACK__THKCREATEDIBITMAP_lpInitBits macro lpBits, lp1616
mov ecx,dword ptr LOCAL__THKCREATEDIBITMAP_dwFreeInfo
UNTILE_BUFFER
endm ;RAWUNPACK__THKCREATEDIBITMAP_lpInitBits
;---------------------------------------------------------------------------;
; RAWPACK__STRETCHDIBITS_lpBits
;---------------------------------------------------------------------------;
RAWPACK__STRETCHDIBITS_lpBits macro lpBits, lp1616
local exit,fail_exit
mov eax,[bp_top + 40] ;Get pointer to BITMAPINFOHEADER
DIB_BITS_SIZE
or ecx,ecx
jz fail_exit
mov eax,[bp + &lpBits&]
or eax,eax
jz fail_exit
TILE_BUFFER
jc fail_exit
mov dword ptr [bp - &lp1616&], eax
mov dword ptr LOCAL__STRETCHDIBITS_dwFreeInfo, ecx
jmp exit
fail_exit:
mov sp,bp
xor eax,eax
dec eax
ERRCHK_EXIT -1,87,Exit_52
exit:
endm ;RAWPACK__STRETCHDIBITS_lpBits
;---------------------------------------------------------------------------;
; RAWUNPACK__STRETCHDIBITS_lpBits
;---------------------------------------------------------------------------;
RAWUNPACK__STRETCHDIBITS_lpBits macro lpBits, lp1616
mov ecx,dword ptr LOCAL__STRETCHDIBITS_dwFreeInfo
UNTILE_BUFFER
endm ;RAWUNPACK__STRETCHDIBITS_lpBits
;---------------------------------------------------------------------------;
; RAWPACK__SETDIBITS_lpBits
;---------------------------------------------------------------------------;
RAWPACK__SETDIBITS_lpBits macro lpBits, lp1616
local exit,fail_exit
mov eax,[bp_top + 20] ;Get pointer to BITMAPINFOHEADER
DIB_BITS_SIZE
or ecx,ecx
jz fail_exit
mov eax,[bp + &lpBits&]
or eax,eax
jz fail_exit
TILE_BUFFER
jc fail_exit
mov dword ptr [bp - &lp1616&], eax
mov dword ptr LOCAL__SETDIBITS_dwFreeInfo, ecx
jmp exit
fail_exit:
mov sp,bp
xor eax,eax
ERRCHK_EXIT 0,87,Exit_28
exit:
endm ;RAWPACK__SETDIBITS_lpBits
;---------------------------------------------------------------------------;
; RAWUNPACK__SETDIBITS_lpBits
;---------------------------------------------------------------------------;
RAWUNPACK__SETDIBITS_lpBits macro lpBits, lp1616
mov ecx,dword ptr LOCAL__SETDIBITS_dwFreeInfo
UNTILE_BUFFER
endm ;RAWUNPACK__SETDIBITS_lpBits
;---------------------------------------------------------------------------;
; RAWPACK__GETDIBITS_lpBits
;---------------------------------------------------------------------------;
RAWPACK__GETDIBITS_lpBits macro lpBits, lp1616
local exit,null_exit,fail_exit
mov eax,[bp + &lpBits&]
or eax,eax
jz null_exit
mov eax,[bp_top + 20] ;Get pointer to BITMAPINFOHEADER
DIB_BITS_SIZE
or ecx,ecx
jz fail_exit
mov eax,[bp + &lpBits&]
TILE_BUFFER
jc fail_exit
mov dword ptr [bp - &lp1616&], eax
mov dword ptr LOCAL__GETDIBITS_dwFreeInfo, ecx
jmp exit
fail_exit:
mov sp,bp
xor eax,eax
ERRCHK_EXIT 0,87,Exit_28
null_exit:
xor eax,eax
mov dword ptr LOCAL__GETDIBITS_dwFreeInfo,eax
exit:
endm ;RAWPACK__GETDIBITS_lpBits
;---------------------------------------------------------------------------;
; RAWUNPACK__GETDIBITS_lpBits
;---------------------------------------------------------------------------;
RAWUNPACK__GETDIBITS_lpBits macro lpBits, lp1616
mov ecx,dword ptr LOCAL__GETDIBITS_dwFreeInfo
UNTILE_BUFFER
endm ;RAWUNPACK__GETDIBITS_lpBits
;---------------------------------------------------------------------------;
; RAWPACK__SETDIBITSTODEVICE_lpBits
;---------------------------------------------------------------------------;
RAWPACK__SETDIBITSTODEVICE_lpBits macro lpBits, lp1616
local exit,fail_exit
mov eax,[bp_top + 40] ;Get pointer to BITMAPINFOHEADER
DIB_BITS_SIZE
or ecx,ecx
jz fail_exit
mov eax,[bp + &lpBits&]
or eax,eax
jz fail_exit
TILE_BUFFER
jc fail_exit
mov dword ptr [bp - &lp1616&], eax
mov dword ptr LOCAL__SETDIBITSTODEVICE_dwFreeInfo, ecx
jmp exit
fail_exit:
mov sp,bp
xor eax,eax
ERRCHK_EXIT 0,87,Exit_48
exit:
endm ;RAWPACK__SETDIBITSTODEVICE_lpBits
;---------------------------------------------------------------------------;
; RAWUNPACK__SETDIBITSTODEVICE_lpBits
;---------------------------------------------------------------------------;
RAWUNPACK__SETDIBITSTODEVICE_lpBits macro lpBits, lp1616
mov ecx,dword ptr LOCAL__SETDIBITSTODEVICE_dwFreeInfo
UNTILE_BUFFER
endm ;RAWUNPACK__SETDIBITSTODEVICE_lpBits
;---------------------------------------------------------------------------;
; RAWPACK__PLAYMETAFILERECORD_lpMetaRecord
;---------------------------------------------------------------------------;
RAWPACK__PLAYMETAFILERECORD_lpMetaRecord macro lpMFR, lp1616
local exit,fail_exit
mov eax,[bp + &lpMFR&]
or eax,eax
jz fail_exit
mov es,FlatData
mov ecx,es:[eax]
shl ecx,1
jc fail_exit
add ecx,4 ; add some slop in case drivers touch
jo fail_exit ; a little too much... #9978,win95c
TILE_BUFFER
jc fail_exit
mov dword ptr [bp - &lp1616&], eax
mov dword ptr LOCAL__PLAYMETAFILERECORD_dwFreeInfo, ecx
jmp exit
fail_exit:
mov sp,bp
xor eax,eax ;PlayMetaFileRecord doesn't return a
ERRCHK_EXIT 0,87,Exit_16 ;a value, so fake it.
exit:
endm ;RAWPACK__PLAYMETAFILERECORD_lpMetaRecord
;---------------------------------------------------------------------------;
; RAWUNPACK__PLAYMETAFILERECORD_lpMetaRecord
;---------------------------------------------------------------------------;
RAWUNPACK__PLAYMETAFILERECORD_lpMetaRecord macro lpMFR, lp1616
mov ecx,dword ptr LOCAL__PLAYMETAFILERECORD_dwFreeInfo
UNTILE_BUFFER
endm ;RAWUNPACK__PLAYMETAFILERECORD_lpMetaRecord
;---------------------------------------------------------------------------;
; Return value for PlayMetaFileRecord
;---------------------------------------------------------------------------;
RET__PLAYMETAFILERECORD macro
; The 16-bit PlayMetaFileRecord API has a void return but the Win32 version
; has a BOOL return so always return success.
mov eax,1
endm
;---------------------------------------------------------------------------
; Handling error code of STARTDOC api.
;---------------------------------------------------------------------------
err_STARTDOCA macro
local exit,l1,l2,l3,l4
cmp eax,0 ;Avoid overhead when successful
jge exit
cmp eax,-1 ;SP_ERROR, generic error, check GetLastError()
jne l1
call GetLastError
cmp eax,0
jne l4 ;if GetLastError() != 0, exit
pushd 87 ;if GetLastError() == 0, SetLastError(INVALID_PARAM)
call SetLastError
jmp l4
; This expands to a pretty embarrassing control structure (checks
; against all four values even after a match is found). Looking forward
; to throwing this out when we optimize the thunk layer.
; ERRCHK_EXIT -1,87,l1 ;SP_ERROR -> BAD_PARAM
l1: ERRCHK_EXIT -4,112,l2 ;SP_OUTOFDISK -> DISK_FULL
l2: ERRCHK_EXIT -5,8,l3 ;SP_OUTOFMEMORY -> NOT_ENOUGH_MEM
l3: ERRCHK_EXIT -3,63,l4 ;SP_USERABORT -> PRINT_CANCELLED
l4: mov eax,-1 ;return SP_ERROR for failure
exit:
endm ;err_STARTDOCA
;---------------------------------------------------------------------------
; Handling error code of ESCAPE api.
;---------------------------------------------------------------------------
err_THKESCAPE macro
local exit,l1,l2,l3
cmp eax,0 ;Avoid overhead when successful
jge exit
; This expands to a pretty embarrassing control structure (checks
; against all four values even after a match is found). Looking forward
; to throwing this out when we optimize the thunk layer.
ERRCHK_EXIT -1,87,l1 ;SP_ERROR -> BAD_PARAM
l1: ERRCHK_EXIT -4,112,l2 ;SP_OUTOFDISK -> DISK_FULL
l2: ERRCHK_EXIT -5,8,l3 ;SP_OUTOFMEMORY -> NOT_ENOUGH_MEM
l3: ERRCHK_EXIT -3,63,exit ;SP_USERABORT -> PRINT_CANCELLED
exit:
endm ;err_ESCAPE
;--------------------------------------------------------------------------
; body_GETTEXTEXTENTEXPOINTA
;--------------------------------------------------------------------------
body_GETTEXTEXTENTEXPOINTA macro
local exit,fail_exit
local bp_hdc, bp_lpszStr, bp_cchString, bp_nMaxExtent
local bp_lpnFit, bp_alpDx, bp_lpSize
local bp_lpszStr16,bp_lpSize16
local p1,loop,loop_exit,loop_exit2,unpack_size,no_alpDx
bp_hdc equ <[bp_top]>
bp_lpszStr equ <[bp_top+4]>
bp_cchString equ <[bp_top+8]>
bp_nMaxExtent equ <[bp_top+12]>
bp_lpnFit equ <[bp_top+16]>
bp_alpDx equ <[bp_top+20]>
bp_lpSize equ <[bp_top+24]>
bp_lpszStr16 equ <[bp-4]> ;16:16 lpszStr pointer
bp_lpSize16 equ <[bp-8]> ;16:16 lpSize pointer
xor eax,eax ;Allocate 0-initialized locals
push eax ; bp_lpszStr16
push eax ; bp_lpSize16
; Convert lpszStr arg to 16:16 pointer and stuff away.
mov eax,dword ptr bp_lpszStr
push eax
call MapLS ;PLUGGED
mov dword ptr bp_lpszStr16,eax
; Convert lpSize arg to 16:16 pointer and stuff away.
mov eax,dword ptr bp_lpSize
push eax
call MapLS ;PLUGGED
mov dword ptr bp_lpSize16,eax
; Optimization: if lpfnFit and alpDx both NULL, degenerate to
; GetTextExtentPoint().
mov eax,dword ptr bp_lpnFit
or eax,dword ptr bp_alpDx
jz measure_whole
; If lpfnFit == 0, we're supposed to ignore nMaxExtent. To avoid dealing
; with this special case, set nMaxExtent to max.
mov eax,dword ptr bp_lpnFit
or eax,eax
jnz p1
dec eax ;eax <-- 0xffffffff
mov dword ptr bp_nMaxExtent, eax
; Assert: nMaxExtent now set to valid value.
p1:
mov ecx,1
loop:
; Measure increasingly long prefixes until we reach the end of the
; string or exceed nMaxExtent. ecx == prefix length (ranges from 1
; to cchString inclusive).
cmp ecx,dword ptr bp_cchString
ja loop_exit
push ecx ;Save prefix length
; Note: Using caller's SIZE as temporary for GetTextExtentPoint().
; If this is the last call before hitting the end of the string,
; this'll put the right return value in SIZE. If not, we'll
; do a final measure to set SIZE right.
push word ptr bp_hdc ;Arg: GetTextExtentPoint
push dword ptr bp_lpszStr16 ;Arg: GetTextExtentPoint
push cx ;Arg: GetTextExtentPoint
push dword ptr bp_lpSize16 ;Arg: GetTextExtentPoint
call GetTextExtentPoint
pop ecx ;Restore prefix length
or ax,ax
jz fail_exit
mov es,FlatData
mov esi,bp_lpSize
mov ax,es:[esi + 0] ;Retrieve size.cx
cwde
cmp eax,bp_nMaxExtent ;If exceeded nMaxExtent, end of
ja loop_exit ; story.
; Store partial width in alpDx (if not NULL).
mov edi,dword ptr bp_alpDx
or edi,edi
jz no_alpDx
mov es,FlatData
mov es:[edi + ecx*4 - 4], eax
no_alpDx:
inc ecx
jmp loop
; Assert: ecx - 1 == length of longest prefix not violating nMaxExtent
loop_exit:
dec ecx
mov edi,bp_lpnFit
or edi,edi
jz loop_exit2
mov es,FlatData
mov es:[edi],ecx
loop_exit2:
; Optimization: if we ran off the end of the string, SIZE already contains
; right (16-bit) values so bypass final call to GetTextExtentPoint().
cmp ecx,dword ptr bp_cchString
je unpack_size
; Deliberate fall-through to measure_whole
measure_whole:
push word ptr bp_hdc
push dword ptr bp_lpszStr16
push word ptr bp_cchString
push dword ptr bp_lpSize16
call GetTextExtentPoint
or ax,ax
jz fail_exit
unpack_size:
; Unpack LPSIZE object
mov es,FlatData
mov esi,bp_lpSize
mov ax,es:[esi + 2] ;Unpack Y
cwde
mov es:[esi + 4],eax
mov ax,es:[esi + 0] ;Unpack X
cwde
mov es:[esi + 0],eax
xor eax,eax ;Set success return value.
inc eax
jmp exit
fail_exit:
xor eax,eax
exit:
push eax
pushd bp_lpszStr16
call UnmapLS
pushd bp_lpSize16
call UnmapLS
pop eax
endm ;body_GETTEXTEXTENTEXPOINTA
;--------------------------------------------------------------------------
; body_THKPLAYENHMETAFILERECORD
;--------------------------------------------------------------------------
body_THKPLAYENHMETAFILERECORD macro
local pop_exit
bp_hdc equ <[bp_top]>
bp_lpht equ <[bp_top+4]>
bp_lpby equ <[bp_top+8]>
bp_che equ <[bp_top+12]>
bp_cby equ <[bp_top+16]>
bp_return equ <[bp-4]> ;return value
bp_tile_lpht equ <[bp-8]> ;ecx from TILE_BUFFER
bp_tile_lpby equ <[bp-12]> ;ecx from TILE_BUFFER
; Create zero-inited stack space for the return value.
xor eax, eax
push eax ;bp_return = 0
; Convert lpht arg into a selector array and create stack space.
mov eax, dword ptr bp_lpht
mov ecx, dword ptr bp_che
test ecx, 0C0000000h ;so we can shift left safely
jnz pop_exit
shl ecx, 2 ;HANDLE is 4 bytes in 16-bit and 32-bit
TILE_BUFFER
push ecx
push eax ;save 16:16 ptr temporarily
; Convert lpby arg into a selector array and create stack space.
mov eax, dword ptr bp_lpby
mov ecx, dword ptr bp_cby
TILE_BUFFER
pop edx ;get 16:16 pointer to handles
push ecx
; Re-pack the stack and make the 16-bit call.
push word ptr bp_hdc
push edx ;16:16 pointer to handles
push eax ;16:16 pointer to bytes
push dword ptr bp_che
call PlayEnhMetaFileRecord
; Save the return value on the stack. (The high word is already zero.)
mov word ptr bp_return, ax
; Free the tiled selector arrays and stack space.
pop ecx
UNTILE_BUFFER
pop ecx
UNTILE_BUFFER
; Clean the stack and set the return value.
pop_exit:
pop eax
endm ;body_THKPLAYENHMETAFILERECORD
;-------------------------------------------------------------------------
; RAWPACK_GETPATH_lpptl
;-------------------------------------------------------------------------
RAWPACK__GETPATH_lpptl macro lpptl,lp1616
local exit,fail_exit,no_check
mov ecx,[bp_top+12] ;cptl (count of points)
test ecx, 0E0000000h ;so we can shift left safely
jnz fail_exit
shl ecx, 3 ;# bytes = cptl * 8
mov LOCAL__GETPATH_dwFreeInfo1,ecx ;assume ecx is zero
or ecx,ecx
jz exit
mov eax,[bp + &lpptl]
or eax,eax
jz fail_exit
; Make sure it's writeable. If not, thunk fault handler will catch it.
mov es, FlatData
or byte ptr es:[eax],0
mov edx, [bp + &lpptl& + 4]
or edx,edx
jz no_check
or byte ptr es:[edx],0
no_check:
TILE_BUFFER
mov [bp - &lp1616&],eax
mov LOCAL__GETPATH_dwFreeInfo1,ecx
jmp exit
fail_exit:
mov sp,bp
xor eax,eax
dec eax
ERRCHK_EXIT -1,87,Exit_16
exit:
endm ;RAWPACK_GETPATH_lpBits
;-------------------------------------------------------------------------
; RAWUNPACK_GETPATH_lpptl
;-------------------------------------------------------------------------
RAWUNPACK__GETPATH_lpptl macro lpptl,lp1616
mov ecx,LOCAL__GETPATH_dwFreeInfo1
UNTILE_BUFFER
endm ;RAWUNPACK_GETPATH
;-------------------------------------------------------------------------
; RAWPACK_GETPATH_lpby
;-------------------------------------------------------------------------
RAWPACK__GETPATH_lpby macro lpby,lp1616
local exit,fail_exit
mov ecx,[bp_top+12] ;cptl (count of points)
mov LOCAL__GETPATH_dwFreeInfo2,ecx ;assume ecx is zero
or ecx,ecx
jz exit
mov eax,[bp + &lpby]
or eax,eax
jz fail_exit
TILE_BUFFER
mov [bp - &lp1616&],eax
mov LOCAL__GETPATH_dwFreeInfo2,ecx
jmp exit
fail_exit:
mov sp,bp
xor eax,eax
dec eax
ERRCHK_EXIT -1,87,Exit_16
exit:
endm ;RAWPACK_GETPATH_lpBits
;-------------------------------------------------------------------------
; RAWUNPACK_GETPATH_lpby
;-------------------------------------------------------------------------
RAWUNPACK__GETPATH_lpby macro lpby,lp1616
mov ecx,LOCAL__GETPATH_dwFreeInfo2
UNTILE_BUFFER
endm ;RAWUNPACK_GETPATH
;-------------------------------------------------------------------------
; RAWPACK_GDICOMMENT
;-------------------------------------------------------------------------
RAWPACK__GDICOMMENT_lpby macro lpby,lp1616
local exit,fail_exit
mov eax,[bp + &lpby]
or eax,eax
jz fail_exit
mov ecx,[bp_top+4] ;cby (size of buffer)
or ecx,ecx
jz fail_exit
TILE_BUFFER
mov [bp - &lp1616&],eax
mov LOCAL__GDICOMMENT_dwFreeInfo,ecx
jmp exit
fail_exit:
mov sp,bp
xor eax,eax
ERRCHK_EXIT 0,87,Exit_12
exit:
endm ;RAWPACK_GDICOMMENT_lpBits
;-------------------------------------------------------------------------
; RAWUNPACK_GDICOMMENT
;-------------------------------------------------------------------------
RAWUNPACK__GDICOMMENT_lpby macro lpby,lp1616
mov ecx,LOCAL__GDICOMMENT_dwFreeInfo
UNTILE_BUFFER
endm ;RAWUNPACK_GDICOMMENT
;-------------------------------------------------------------------------
; RAWPACK_GETENHMETAFILEBITS
;-------------------------------------------------------------------------
RAWPACK__GETENHMETAFILEBITS_lpby macro lpby,lp1616
local exit
mov eax,[bp + &lpby]
mov ecx,[bp_top+4] ;cby (size of buffer)
TILE_BUFFER
mov [bp - &lp1616&],eax
mov LOCAL__GETENHMETAFILEBITS_dwFreeInfo,ecx
exit:
endm ;RAWPACK_GETENHMETAFILEBITS_lpBits
;-------------------------------------------------------------------------
; RAWUNPACK_GETENHMETAFILEBITS
;-------------------------------------------------------------------------
RAWUNPACK__GETENHMETAFILEBITS_lpby macro lpby,lp1616
mov ecx,LOCAL__GETENHMETAFILEBITS_dwFreeInfo
UNTILE_BUFFER
endm ;RAWUNPACK_GETENHMETAFILEBITS
;-------------------------------------------------------------------------
; RAWPACK_GETENHMETAFILEDESCRIPTIONA
;-------------------------------------------------------------------------
RAWPACK__GETENHMETAFILEDESCRIPTIONA_lpby macro lpby,lp1616
local exit
mov eax,[bp + &lpby]
mov ecx,[bp_top+4] ;cby (size of buffer)
TILE_BUFFER
mov [bp - &lp1616&],eax
mov LOCAL__GETENHMETAFILEDESCRIPTIONA_dwFreeInfo,ecx
exit:
endm ;RAWPACK_GETENHMETAFILEDESCRIPTIONA_lpBits
;-------------------------------------------------------------------------
; RAWUNPACK_GETENHMETAFILEDESCRIPTIONA
;-------------------------------------------------------------------------
RAWUNPACK__GETENHMETAFILEDESCRIPTIONA_lpby macro lpby,lp1616
mov ecx,LOCAL__GETENHMETAFILEDESCRIPTIONA_dwFreeInfo
UNTILE_BUFFER
endm ;RAWUNPACK_GETENHMETAFILEDESCRIPTIONA
;-------------------------------------------------------------------------
; RAWPACK_GETENHMETAFILEPALETTEENTRIES
;-------------------------------------------------------------------------
RAWPACK__GETENHMETAFILEPALETTEENTRIES_lpby macro lpby,lp1616
local exit,fail_exit
mov eax,[bp + &lpby]
mov ecx,[bp_top+4] ;cpe (count of PALETTEENTRYs)
test ecx, 0C0000000h ;so we can shift left safely
jnz fail_exit
shl ecx,2
TILE_BUFFER
mov [bp - &lp1616&],eax
mov LOCAL__GETENHMETAFILEPALETTEENTRIES_dwFreeInfo,ecx
jmp exit
fail_exit:
mov sp,bp
xor eax,eax
dec eax
ERRCHK_EXIT -1,87,Exit_12
exit:
endm ;RAWPACK_GETENHMETAFILEPALETTEENTRIES_lpPALETTEENTRIES
;-------------------------------------------------------------------------
; RAWUNPACK_GETENHMETAFILEPALETTEENTRIES
;-------------------------------------------------------------------------
RAWUNPACK__GETENHMETAFILEPALETTEENTRIES_lpby macro lpby,lp1616
mov ecx,LOCAL__GETENHMETAFILEPALETTEENTRIES_dwFreeInfo
UNTILE_BUFFER
endm ;RAWUNPACK_GETENHMETAFILEPALETTEENTRIES
;-------------------------------------------------------------------------
; RAWPACK_SETENHMETAFILEBITS
;-------------------------------------------------------------------------
RAWPACK__SETENHMETAFILEBITS_lpby macro lpby,lp1616
local exit,fail_exit
mov eax,[bp + &lpby]
or eax,eax
jz fail_exit
mov ecx,[bp_top] ;cby (size of buffer)
or ecx,ecx
jz fail_exit
TILE_BUFFER
mov [bp - &lp1616&],eax
mov LOCAL__SETENHMETAFILEBITS_dwFreeInfo,ecx
jmp exit
fail_exit:
mov sp,bp
xor eax,eax
ERRCHK_EXIT 0,87,Exit_8
exit:
endm ;RAWPACK_SETENHMETAFILEBITS_lpBits
;-------------------------------------------------------------------------
; RAWUNPACK_SETENHMETAFILEBITS
;-------------------------------------------------------------------------
RAWUNPACK__SETENHMETAFILEBITS_lpby macro lpby,lp1616
mov ecx,LOCAL__SETENHMETAFILEBITS_dwFreeInfo
UNTILE_BUFFER
endm ;RAWUNPACK_SETENHMETAFILEBITS
;-------------------------------------------------------------------------
; RAWPACK_ENUMOBJECTS
;-------------------------------------------------------------------------
RAWPACK__ENUMOBJECTS_lpObjectFunc macro iOffset,iTempOffset
local pen, exit
cmp word ptr [bp_top+4],1 ;OBJ_PEN?
je pen
PACK_CALLBACK iOffset,iTempOffset,CBID_ENUMBRUSH
jmp exit
pen:
PACK_CALLBACK iOffset,iTempOffset,CBID_ENUMPEN
exit:
endm ;RAWPACK__ENUMOBJECTS_lpObjectFunc
;-------------------------------------------------------------------------
; RAWUNPACK_ENUMOBJECTS
;-------------------------------------------------------------------------
RAWUNPACK__ENUMOBJECTS_lpObjectFunc macro iOffset,iTempOffset
local pen, exit
;unpack don't care about CBID
;just make it readable
cmp word ptr [bp_top+4],1 ;OBJ_PEN?
je pen
UNPACK_CALLBACK iOffset,iTempOffset,CBID_ENUMBRUSH
jmp exit
pen:
UNPACK_CALLBACK iOffset,iTempOffset,CBID_ENUMPEN
exit:
endm ;RAWUNPACK__ENUMOBJECTS_lpObjectFunc