📄 protogen.bat
字号:
mov uProtoMargin, eax
Fix
; invoke Sort, esi, uNumberOfSymbols, CC_CDECL
xor ebx, ebx
.while ebx < uNumberOfSymbols
Fix make it possible to generate __imp_ protos
.if [esi].dwFlags & FF_SYM___IMP_
; skip this symbol
jmp @F
.endif
IFDEF DEBUG
; invoke DbgPrintImportTypes, [esi][ebx*(sizeof SYM_ENTRY)].pSymbolName, [esi][ebx*(sizeof SYM_ENTRY)].dwFlagsAndIndex
ENDIF
IFDEF GENERATE_INVOKE
Fix Generate invoke only for masm
invoke fCopyMemory, g_pIncludeCurrent, addr g_szInvoke, sizeof g_szInvoke
add g_pIncludeCurrent, sizeof g_szInvoke
ENDIF
; Write undecorated symbol name
invoke fCopyMemory, g_pIncludeCurrent, [esi].pUndecSymbolNameStart, [esi].ccUndecSymbolNameLength
mov eax, [esi].ccUndecSymbolNameLength
add g_pIncludeCurrent, eax
; fill with spaces untill proto margin
mov eax, uProtoMargin
sub eax, [esi].ccUndecSymbolNameLength
IFNDEF GENERATE_INVOKE
; not sure we need to do this check here but who cares...
.if !SIGN?
push eax
invoke fFillMemory, g_pIncludeCurrent, eax, ' '
pop eax
add g_pIncludeCurrent, eax
.endif
ENDIF
IFNDEF GENERATE_INVOKE
; write proto
invoke fCopyMemory, g_pIncludeCurrent, $CTA(" proto c :VARARG", g_szProtoCDecl), sizeof g_szProtoCDecl
add g_pIncludeCurrent, sizeof g_szProtoCDecl
ENDIF
.if [esi].dwFlags & FF_SYM_VARIABLE
invoke fCopyMemory, g_pIncludeCurrent, addr g_szExportedVariable, sizeof g_szExportedVariable
add g_pIncludeCurrent, sizeof g_szExportedVariable
.endif
NewLine g_pIncludeCurrent
IFDEF DEBUG
inc uPrintedSymbols
ENDIF
;IFDEF DEBUG
; .else
; invoke wsprintf, addr g_acDebugMessage, $CTA0("Skip: %s\n"), [esi].pSymbolName
; invoke PrintConsole, addr g_acDebugMessage, 0
;ENDIF
; .endif
@@:
add esi, sizeof SYM_ENTRY
inc ebx ; next symbol
.endw
IFDEF DEBUG
; Print how many symbols were prototyped
invoke wsprintf, addr g_acDebugMessage, $CTA0("\nProtos for %u cdecl symbols generated\n\n"), uPrintedSymbols
invoke PrintConsole, addr g_acDebugMessage, 0
ENDIF
Fix
; invoke GenerateEquationsCDecl, pSymEntries, uNumberOfSymbols
ret
GenerateProtoCDecl endp
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; GenerateProtoFastCall
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
GenerateProtoFastCall proc uses esi edi ebx pSymEntries:PTR SYM_ENTRY, uNumberOfSymbols:UINT
IFDEF DEBUG
local uPrintedSymbols:UINT
ENDIF
local acUndecSymbolName[256]:CHAR
local acBuffer[512]:CHAR
.if uNumberOfSymbols != 0
; write banner
invoke GenerateBanner, \
$CTA(";: FASTCALL ::\n", g_szFastCallProtoBanner), sizeof g_szFastCallProtoBanner
; mov g_pIncludeCurrent, eax ; update the pointer
.else
Fix
ret
.endif
IFDEF DEBUG
and uPrintedSymbols, 0
ENDIF
mov esi, pSymEntries
assume esi:ptr SYM_ENTRY
Fix
; invoke Sort, esi, uNumberOfSymbols, CC_FASTCALL
xor ebx, ebx
.while ebx < uNumberOfSymbols
Fix make it possible to generate __imp_ protos
.if [esi].dwFlags & FF_SYM___IMP_
; skip this symbol
jmp @F
.endif
IFDEF GENERATE_INVOKE
Fix Generate invoke only for masm
invoke fCopyMemory, g_pIncludeCurrent, addr g_szInvoke, sizeof g_szInvoke
add g_pIncludeCurrent, sizeof g_szInvoke
; Write undecorated symbol name
invoke fCopyMemory, g_pIncludeCurrent, [esi].pUndecSymbolNameStart, [esi].ccUndecSymbolNameLength
mov eax, [esi].ccUndecSymbolNameLength
add g_pIncludeCurrent, eax
mov edi, [esi].uNumberOfParameters
.if edi > 0
.while edi > 0
invoke fCopyMemory, g_pIncludeCurrent, addr g_szZero, sizeof g_szZero
add g_pIncludeCurrent, sizeof g_szDWORD
dec edi
.endw
.endif
ELSE ; Generate Proto
comment ^
invoke fCopyMemory, g_pIncludeCurrent, $CTA("externdef syscall ", g_szExterndefSyscall, 4), sizeof g_szExterndefSyscall
add g_pIncludeCurrent, sizeof g_szExterndefSyscall
invoke fstrlen, [esi].pSymbolName
push eax
invoke fCopyMemory, g_pIncludeCurrent, [esi].pSymbolName, eax
pop eax
add g_pIncludeCurrent, eax
invoke fCopyMemory, g_pIncludeCurrent, [esi].pUndecSymbolNameStart, [esi].ccUndecSymbolNameLength
mov eax, [esi].ccUndecSymbolNameLength
add g_pIncludeCurrent, eax
^
invoke fCopyMemory, addr acUndecSymbolName, [esi].pUndecSymbolNameStart, [esi].ccUndecSymbolNameLength
lea eax, acUndecSymbolName
add eax, [esi].ccUndecSymbolNameLength
mov byte ptr [eax], 0 ; terminate with zero
invoke wsprintf, addr acBuffer, $CTA0("externdef syscall %s:proc\n%s textequ \[%s\]\n"), \
[esi].pSymbolName, addr acUndecSymbolName, [esi].pSymbolName
push eax
invoke fCopyMemory, g_pIncludeCurrent, addr acBuffer, eax
pop eax
add g_pIncludeCurrent, eax
ENDIF
Fix If invoking generated variables should be different
.if [esi].dwFlags & FF_SYM_VARIABLE
invoke fCopyMemory, g_pIncludeCurrent, addr g_szExportedVariable, sizeof g_szExportedVariable
add g_pIncludeCurrent, sizeof g_szExportedVariable
.endif
NewLine g_pIncludeCurrent
IFDEF DEBUG
inc uPrintedSymbols
ENDIF
@@:
add esi, sizeof SYM_ENTRY
inc ebx ; next symbol
.endw
IFDEF DEBUG
; Print how many symbols were prototyped
invoke wsprintf, addr g_acDebugMessage, $CTA0("\nProtos for %u fastcall symbols generated\n\n"), uPrintedSymbols
invoke PrintConsole, addr g_acDebugMessage, 0
ENDIF
Fix
; invoke GenerateEquationsFastCall, pSymEntries, uNumberOfSymbols
ret
GenerateProtoFastCall endp
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; GenerateProto
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
GenerateProto proc uses esi
lea esi, g_paCcEntries
assume esi:ptr CC_ENTRY
IFDEF DEBUG
invoke DbgPrintSymbolsInfo, CC_STDCALL
ENDIF
; stdcall processing
mov eax, CC_STDCALL
invoke GenerateProtoStdCall, [esi][eax*(sizeof CC_ENTRY)].pSymEntries, [esi][eax*(sizeof CC_ENTRY)].uNumEntries
IFDEF DEBUG
invoke DbgPrintSymbolsInfo, CC_CDECL
ENDIF
; cdecl processing
mov eax, CC_CDECL
invoke GenerateProtoCDecl, [esi][eax*(sizeof CC_ENTRY)].pSymEntries, [esi][eax*(sizeof CC_ENTRY)].uNumEntries
IFDEF DEBUG
invoke DbgPrintSymbolsInfo, CC_FASTCALL
ENDIF
; fastcall processing
mov eax, CC_FASTCALL
invoke GenerateProtoFastCall, [esi][eax*(sizeof CC_ENTRY)].pSymEntries, [esi][eax*(sizeof CC_ENTRY)].uNumEntries
assume esi:nothing
return g_pIncludeCurrent
GenerateProto endp
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; GenerateEquation
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
GenerateEquation proc uses esi pSymEntry:PTR SYM_ENTRY, uEquMargin:UINT
; AddAtom equ <AddAtomW>
mov esi, pSymEntry
assume esi:ptr SYM_ENTRY
invoke fCopyMemory, g_pIncludeCurrent, $CTA0(" "), 4
add g_pIncludeCurrent, 4
mov eax, [esi].ccUndecSymbolNameLength
dec eax ; not including 'A' or 'W'
invoke fCopyMemory, g_pIncludeCurrent, [esi].pUndecSymbolNameStart, eax
mov eax, [esi].ccUndecSymbolNameLength
dec eax
add g_pIncludeCurrent, eax
; fill with spaces untill proto margin
mov eax, uEquMargin
sub eax, [esi].ccUndecSymbolNameLength
inc eax
; not sure we need to do this check here but who cares...
.if !SIGN?
push eax
invoke fFillMemory, g_pIncludeCurrent, eax, ' '
pop eax
add g_pIncludeCurrent, eax
.endif
invoke fCopyMemory, g_pIncludeCurrent, $CTA0("equ \["), 5
add g_pIncludeCurrent, 5
invoke fCopyMemory, g_pIncludeCurrent, [esi].pUndecSymbolNameStart, [esi].ccUndecSymbolNameLength
mov eax, [esi].ccUndecSymbolNameLength
add g_pIncludeCurrent, eax
invoke fCopyMemory, g_pIncludeCurrent, $CTA0("\]"), 1
add g_pIncludeCurrent, 1
NewLine g_pIncludeCurrent
ret
GenerateEquation endp
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; IsSpecialCase
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
IsSpecialCase proc uses esi edi ebx pSymEntries:PTR SYM_ENTRY, uNumberOfSymbols:UINT, pSymEntry:PTR SYM_ENTRY
local fRet:BOOL
IFDEF DEBUG
local buffer[128]:CHAR
ENDIF
; pSymEntry points to SYM_ENTRY for ANSI or UNICODE symbol
; We need to do some check while generating equations.
; If we meet one of such case we return TRUE or FALSE otherwise.
and fRet, FALSE ; assume no special cases
.if uNumberOfSymbols != 0
mov edi, pSymEntry
assume edi:ptr SYM_ENTRY
mov eax, [edi].dwFlags
and eax, FF_SYM_ANSI + FF_SYM_UNICODE
.if !ZERO? ; Make sure is pSymEntry really points to ANSI or UNICODE entry.
; We need this check because we going to trancate symbol name at 'A' or 'W'
mov esi, pSymEntries
assume esi:ptr SYM_ENTRY
; *** SPECIAL CASE #1
; user32.lib
; BroadcastSystemMessage
; BroadcastSystemMessageA
; BroadcastSystemMessageW
;
; So we must not equate BroadcastSystemMessage to BroadcastSystemMessageA and to BroadcastSystemMessageW
; otherwise we'll get symbol redefinition error
xor ebx, ebx
.while ebx < uNumberOfSymbols
.if esi != edi ; skip comparing with the same symbol
; Compare only symbols that have the same name lenght
mov eax, [edi].ccUndecSymbolNameLength
dec eax
.if [esi].ccUndecSymbolNameLength == eax
invoke strncmp, [esi].pUndecSymbolNameStart, [edi].pUndecSymbolNameStart, eax
.if eax == 0
IFDEF DEBUG
invoke RtlZeroMemory, addr g_acDebugMessage, sizeof g_acDebugMessage
invoke lstrcpy, addr g_acDebugMessage, $CTA0("Special case #1 found: ")
invoke fCopyMemory, addr buffer, [edi].pUndecSymbolNameStart, [edi].ccUndecSymbolNameLength
invoke lstrcat, addr g_acDebugMessage, addr buffer
invoke lstrcat, addr g_acDebugMessage, $CTA0(" has corresponding ")
invoke fCopyMemory, addr buffer, [esi].pUndecSymbolNameStart, [esi].ccUndecSymbolNameLength
invoke lstrcat, addr g_acDebugMessage, addr buffer
invoke lstrcat, addr g_acDebugMessage, $CTA0("\n")
invoke PrintConsole, addr g_acDebugMessage, 0
ENDIF
mov fRet, TRUE ; found special case #1
jmp RetFromIsSpecialCase
.endif
.endif
.endif
add esi, sizeof SYM_ENTRY
inc ebx ; next symbol
.endw
Fix add check
; *** SPECIAL CASE #2
; sulwapi.lib
; StrFormatByteSize64A doesn't have corresponding StrFormatByteSize64W symbol
; but doesn't not have StrFormatByteSizeW
; So we have to equate StrFormatByteSize to StrFormatByteSizeA
.endif ; if FF_SYM_ANSI or FF_SYM_UNICODE
assume esi:nothing
assume edi:nothing
.endif ; if uNumberOfSymbols != 0
comment ^
; make symbol unicode and trancate at '@' pos
; _GetStringTypeA@20 -> _GetStringTypeW
; We have to search for symbol this way because of:
; _GetStringTypeA@20
; _GetStringTypeW@16
; Now we have to check to see whether we encounter something like this:
; _MoveFileW _MoveFileWithProgressW
; Mmm... It can be so btw:
; _SomeFuncW _SomeFuncW@SomeSuffix but not for the system library
; But it will only work till we meet something like this:
; _SomeSymbol@10 != _SomeSymbolA@14
; I'm not shure if it can be, but who cares...
^
RetFromIsSpecialCase:
mov eax, fRet
ret
IsSpecialCase endp
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; GenerateEquationsStdCall
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
GenerateEquationsStdCall proc uses esi edi ebx pSymEntries:PTR SYM_ENTRY, uNumberOfSymbols:UINT
local uUnicodeEquMargin:UINT
local uAnsiEquMargin:UINT
local acMessage[256]:CHAR
.if uNumberOfSymbols != 0
; write banner
invoke GenerateBanner, \
$CTA(";: STDCALL EQUATIONS
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -