msgmacro.inc
来自「用于查询PC机上的USB端口是否有设备挂接上」· INC 代码 · 共 553 行 · 第 1/2 页
INC
553 行
movzx reg, @MSG_&c&AB.@msgab_rgOfs[msgno*2-2-2*@MSG_&c&CLASSMASK] ; Y: Get offset
add reg, @MSG_&c&AB.@msgab_pMsgs ; Add bias
jmp l ; Done
skip:
ENDIF
ENDM
; @MSG_GetOneConstClass: Internal helper macro for GET_MESSAGE_PTR
;
; c = message class to try
; msgnum = constant message number
; reg = target register
; @MSG_regstr = optional `+reg*2'
@MSG_GetOneConstClass MACRO c, msgnum, reg
IF (msgnum AND @MSG_CLASSMASK) EQ @MSG_&c&CLASSMASK
% movzx reg, @MSG_&c&AB.@msgab_rgOfs[(msgnum AND @MSG_MSGMASK)*2-2 @MSG_regstr]
add reg, @MSG_&c&AB.@msgab_pMsgs ; Add bias
ENDIF
ENDM
;
; GET_MESSAGE_PTR msgnum, reg, msgreg
;
; msgnum is the message number to retrieve, which can be a message constant
; or a register. Using a register is discouraged, however, because it
; causes bloated code to be generated.
;
; reg is the register to receive the result.
;
; msgreg (optional) is a register which will be added to msgnum to produce
; the actual message number. If you want to pass a variable as msgnum,
; you should instead pass a constant as msgnum and the offset from msgnum
; as the msgreg.
;
; Valid input
;
; GET_MESSAGE_PTR MSG_X, esi - returns pointer to message X
; GET_MESSAGE_PTR MSG_X, esi, eax - returns pointer to message X+EAX
; GET_MESSAGE_PTR eax, esi - returns pointer to message EAX
; (larger than others)
GET_MESSAGE_PTR MACRO msgnum:REQ, reg:REQ, msgreg
LOCAL Done
IF (OPATTR(msgnum)) AND 010h ; if msg number is in a register with no hint
% forc c, @MSG_CLASSNAMES
@MSG_GetOneRegClass c, msgnum, reg, Done
endm
Done:
ELSE ; We have a hint; exploit it!
IFB <msgreg>
@MSG_regstr TEXTEQU <>
ELSE
@MSG_regstr TEXTEQU <+&msgreg*2>
ENDIF
% forc c, @MSG_CLASSNAMES
@MSG_GetOneConstClass c, <msgnum>, reg
endm
ENDIF
ENDM
;==============================================================================
;
; Macros for sprintf'ing messages
;
;==============================================================================
; @MSG_Lsprintf_Helper: Internal helper macro for LOCALIZED_SPRINTF
;
; c = message class to try
; msgnum = constant message number
@MSG_Lsprintf_Helper MACRO c, msgnum
IF (msgnum AND @MSG_CLASSMASK) EQ @MSG_&c&CLASSMASK
@MSG_callparams EQU <offset32 @MSG_&c&AB>
ENDIF
ENDM
;
; LOCALIZED_SPRINTF
;
; Usage: LOCALIZED_SPRINTF buf, msgno, parms
;
; buf = where to put the output string
; msgno = message number (must be a constant)
; parms = optional parameters to the sprintf
;
;
; Returns: None
;
; Uses: Flags
LOCALIZED_SPRINTF MACRO buf:REQ, msgnum:REQ, parms:VARARG
@MSG_callparams textequ <ERROR: Bad message number>
% forc c, @MSG_CLASSNAMES
@MSG_Lsprintf_Helper c, <msgnum>
endm
@MSG_callparams CATSTR <buf, >, @MSG_callparams, <, (msgnum) AND @MSG_MSGMASK, >, <parms>
VMMCall _LocalizeSprintf, <%@MSG_callparams>
ENDM
;
; PUSH_SPRINTF
;
; Usage: PUSH_SPRINTF msgno, parms
;
; msgno = message number
; parms = optional parameters to the sprintf
;
; The message number may be a constant (in which case it can be a
; message from any class), or it may be held in a register (in
; which case it *MUST* be a message ordinal from the LOCKED message
; class).
;
; If you want to pass a message number in a register, and the message
; number is *NOT* for a locked message, then you must call one of the
; PUSH_XXX_SPRINTF macros, such as PUSH_INIT_SPRINTF.
;
; Returns: EAX -> output buffer (allocated from the stack)
;
; Uses: EAX, ESP, Flags
;
; WARNING! This services changes ESP by an unpredictable amount.
; Any ESP-based parameters and/or local variables will be inaccessible
; until you do a POP_SPRINTF.
PUSH_SPRINTF MACRO msgnum:REQ, params:VARARG
@MSG_numvars = 2
IFNB <params>
FOR i, <params>
@MSG_numvars = @MSG_numvars + 1
ENDM
ENDIF
@MSG_numvarbyteshi = (@MSG_numvars*4) SHL 16
IF (OPATTR(msgnum)) AND 010h ; if msg number is in a register
add msgnum, @MSG_numvarbyteshi
@MSG_callparams CATSTR <offset32 @MSG_LAB, msgnum, >, <params>
ELSE
@MSG_callparams textequ <ERROR: Bad message number>
% forc c, @MSG_CLASSNAMES
@MSG_Lsprintf_Helper c, <msgnum>
endm
@MSG_callparams CATSTR @MSG_callparams, \
<, @MSG_numvarbyteshi + (msgnum AND @MSG_MSGMASK), >, <params>
ENDIF
@MSG_PushCParams <%@MSG_callparams>
VMMCall _LocalizeStackSprintf
ENDM
;
; @MSG_PUSH_SPRINTF is a common worker for the PUSH_XXX_SPRINTF macros.
;
@MSG_PUSH_SPRINTF MACRO c:req, msgnum:REQ, params
@MSG_numvars = 2
IFNB <params>
FOR i, <params>
@MSG_numvars = @MSG_numvars + 1
ENDM
ENDIF
@MSG_numvarbyteshi = (@MSG_numvars*4) SHL 16
IF (OPATTR(msgnum)) AND 010h ; if msg number is in a register
add msgnum, @MSG_numvarbyteshi-@MSG_&c&CLASSMASK
@MSG_callparams CATSTR <offset32 @MSG_&c&AB, msgnum, >, <params>
ELSE
.erre (msgnum AND @MSG_CLASSMASK) EQ @MSG_&c&CLASSMASK
@MSG_callparams CATSTR <offset32 @MSG_&c&AB, @MSG_numvarbyteshi + msgnum -@MSG_&c&CLASSMASK, >, <params>
ENDIF
@MSG_PushCParams <%@MSG_callparams>
VMMCall _LocalizeStackSprintf
ENDM
;
; POP_SPRINTF
;
; Usage: POP_SPRINTF
;
; This cleans the stack after a previous PUSH_SPRINTF or
; PUSH_XXX_SPRINTF call.
;
; Returns: None
;
; Uses: Flags
POP_SPRINTF MACRO
;BUGBUG add signature and assertion for debug
add esp, [esp] ; Last item in block pushed is the size of the data block
ENDM
PUSHED_SPRINTF_LENGTH MACRO reg:REQ
;BUGBUG add signature and assertion for debug
mov ®, [esp+4] ; Next to last item pushed is the length of the string
ENDM
FATAL_ERROR_MSG MACRO MsgNum:REQ, ExitFlags
GET_MESSAGE_PTR <&MsgNum>, esi
IFB <ExitFlags>
xor eax, eax
ELSE
mov eax, ExitFlags
ENDIF
VMMcall Fatal_Error_Handler
ENDM
FATAL_ERROR_SQZD_MSG MACRO MsgNum:REQ, ExitFlags
PUSH_SPRINTF <&MsgNum>
xchg esi, eax
IFB <ExitFlags>
xor eax, eax
ELSE
mov eax, ExitFlags
ENDIF
VMMcall Fatal_Error_Handler
ENDM
;*** PushCParams
;
; Processes argument list
@MSG_PushCParams macro arglst
LOCAL count
LOCAL count2
count = 0 ;; number of dwords on stack (global)
FOR x,<arglst>
ifnb <x>
count = count + 1
@MSG_MakePush <x>,%count
endif
ENDM
count2 = count
REPEAT count
@MSG_DoPush <?AM>,%count2
count2 = count2 - 1
ENDM
ENDM
; Makes a macro that will push argment when invoke - used by cCall only
@MSG_MakePush macro name, num
.xcref
.xcref ?AM&num
.cref
?AM&num ¯o
push name
&endm
endm
.xcref @MSG_MakePush
; Concatenates, invokes and purges a macro name - used by PushCParams
@MSG_DoPush macro name1, name2
name1&name2
purge name1&name2
endm
.xcref @MSG_DoPush
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?