MS Windows 32bit Application Programming Interface macros.
This library contains macros for some basic OS interactions: retrieving of environment and command-line arguments, standard I/O, program termination, invocation of 32bit MS Windows Application Programming Interface.
Most macro names in this 32bit librarywinapi.htmare identical with macros from 64bit library winabi.htm and other API libraries. If you really need to include both libraries in one common source file, definitions of those macros should be forgotten before inclusion of the other library with%DROPMACRO GetArg,GetArgCount,PutEnv,StdInput,StdOutput,TerminateProgram
or with%DROPMACRO *
in order to prevent warning W2512 Overwriting macro "!1S" previously defined at !2@.
winapi HEAD INCLUDE1 winansi.htm ; Make sure that %WinANSI is assigned before WinAPI invocation.
%Param6 %SET EBP+56 %Param5 %SET EBP+52 %Param4 %SET EBP+48 %Param3 %SET EBP+44 %Param2 %SET EBP+40 %Param1 %SET EBP+36 %ReturnEAX %SET EBP+28 %ReturnECX %SET EBP+24 %ReturnEDX %SET EBP+20 %ReturnEBX %SET EBP+16 %ReturnESP %SET EBP+12 %ReturnEBP %SET EBP+08 %ReturnESI %SET EBP+04 %ReturnEDI %SET EBP+00
This macroinstruction invokes Function exported from 32bit MS Windows by [WindowsAPI].
The macro is similar to StdCall's Invoke with two subtle differences:
Lib=
.WinAPI functions require Direction Flag be zero on input and they do not change its value.
32bit Windows functions do not keep the original contents of flags, ECX, EDX,
but when this macro WinAPI is invoked with keyword Fastmode=No
(default), it preserves all registers except for EAX.
When you want to switch on the Fastmode for all WinAPI invokations, you don't have to appendLib= is the name of dynamic linked library (quoted or unquoted, always without path) which exports the invoked Function. This parameter may be empty or omitted,Fastmode=Yes
to every invokation ofWinAPI
if you set preprocessing %variable in the beginning of your program:%Fastmode %SETB On
.
kernel32.dll, or
IMPORT Function, LIB=user32.dll
, orFastmode=Yes
winabi.htm.
WinAPI %MACRO Function, Argument1, Argument2,,,,Lib=, Fastmode=%Fastmode, Lib= %IF %Fastmode ; Do not save scratch registers in fast mode. %ELSE PUSH ECX,EDX ; Save scratch registers when Fastmode=off. %ENDIF %ArgNr %SETA %# ; Number of ordinal operands. %WHILE %ArgNr > 1 PUSHD %*{%ArgNr} ; Push Function arguments on stack, begin with the last. %ArgNr %SETA %ArgNr-1 %ENDWHILE %suffix %SET ; Assume no A|W suffix (variable %suffix is empty). noreg %IF TYPE#%Function != 'R'; If the function is specified by name (not in GPR). fn %FOR %WinANSI ; Examine whether %Function is on the list %WinANSI. %IF "%fn" === "%Function" %suffix %SETC ('W' & (%^UNICODE)) + ('A' & ~(%^UNICODE)) %EXITFOR fn ; Break further examination when the %Function name was found. %ENDIF %ENDFOR fn IMPORT %Function%suffix, Lib=%Lib %ENDIF noreg CALL %Function%suffix %IF %Fastmode %ELSE POP EDX,ECX ; Restore scratch registers when Fastmode=off. %ENDIF %ENDMACRO WinAPI
Macro GetArg retrieves ArgNumber-th parameter provided on command line.
Parameters on the command line may be separated with unquoted
white spaces or commas. Single aphostrophe cannot be used as quote.
Macro returns the executable name itself when ArgNumber is 0.
It is taken verbatim from the console window or, if launched
from Explorer, it may be expanded to a full pathname.
The returned argument is not zero terminated and it is not writable.
If you need to modify it, make a copy in local memory or use
PutArg.
Value of EUROASM UNICODE=
option specifies whether the returned string will be ANSI or WIDE.
GetArg %MACRO ArgNumber, Unicode=%^UNICODE PUSHD %ArgNumber AorW %IF %Unicode CALL GetArgWin32W@RT GetArgWin32W@RT:: PROC1 ; Stdcalled with %Param1=ArgNumber. PUSHAD MOV EBP,ESP CMPD [%Param1],-1 ADCD [%Param1],0 IMPORT GetCommandLineW CALL GetCommandLineW MOV ESI,EAX MOV EDI,EAX MOV EBX,EAX XOR EAX,EAX CMP EAX,ESI STC JE .90: ; If GetCommandLine returned FALSE. XOR ECX,ECX DEC ECX REPNE SCASW LEA EDX,[EDI-2] ; EDX points to the end of command line. SUB ECX,ECX ; ECX will keep the ordinal number of parsed cmdline argument. .10:MOV EDI,ESI ; EDI is brutto end of current argument. CMP ECX,[%Param1] ; %Par1 is the number of requested argument. JAE .50: .20:CMP ESI,EDX JNB .50: ; No more arguments available. LODSW CMP AX,' ' JBE .20: DEC ESI,ESI INC ECX MOV EBX,ESI ; EBX is brutto beginning of ECX-th argument. MOV EDI,ESI .30:CMP ESI,EDX JNB .10: LODSW CMP AX,'"' JNE .40: .35:CMP ESI,EDX CMC JC .90: ; Syntax error - unpaired quotes. LODSW CMP AX,'"' JNE .35: JMP .30: .40:CMP AX,',' JE .10: CMP AX,' ' JA .30: .45:CMP ESI,EDX JNB .10: LODSW CMP AX,' ' JNA .45: CMP AX,',' JE .10: DEC ESI,ESI JMP .10: .50:CMPD [%Param1],-1 ; Test if invoked from GetArgCount with ArgNr= -1. JNE .60: DEC ECX ; Omit the 0-th argument (the executable itself). MOV [%ReturnECX],ECX JMP .80: .60:MOVD [%ReturnECX],0 CMP ECX,[%Param1] STC JNE .90: MOV ESI,EBX ; Brutto ECX-th argument found at ESI..EDI. Trim spaces and commas. .65:CMP ESI,EDI JNB .75: LODSW CMP AX,' ' JBE .65: CMP AX,',' JE .65: DEC ESI,ESI .70:DEC EDI,EDI MOV AX,[EDI] CMP AX,' ' JBE .70: CMP AX,',' JE .70: INC EDI,EDI ; Netto argument is now at ESI..EDI. .75 MOV [%ReturnESI],ESI SUB EDI,ESI JC .80: MOV [%ReturnECX],EDI .80:CLC .90:POPAD RET 4 ENDP1 GetArgWin32W@RT %ELSE AorW CALL GetArgWin32A@RT GetArgWin32A@RT:: PROC1 ; Stdcalled with %Param1=ArgNumber. PUSHAD MOV EBP,ESP CMPD [%Param1],-1 ADCD [%Param1],0 IMPORT GetCommandLineA CALL GetCommandLineA MOV ESI,EAX MOV EDI,EAX MOV EBX,EAX XOR EAX,EAX CMP EAX,ESI STC JE .90: ; If GetCommandLine returned FALSE. STC SBB ECX,ECX REPNE SCASB LEA EDX,[EDI-1] ; EDX points to the end of command line. SUB ECX,ECX ; ECX will keep the ordinal number of parsed cmdline argument. .10:MOV EDI,ESI ; EDI is brutto end of current argument. CMP ECX,[%Param1] ; %Par1 is the number of requested argument. JAE .50: .20:CMP ESI,EDX JNB .50: ; No more arguments available. LODSB CMP AL,' ' JBE .20: DEC ESI INC ECX MOV EBX,ESI ; EBX is brutto beginning of ECX-th argument. MOV EDI,ESI .30:CMP ESI,EDX JNB .10: LODSB CMP AL,'"' JNE .40: .35:CMP ESI,EDX CMC JC .90: ; Syntax error - unpaired quotes. LODSB CMP AL,'"' JNE .35: JMP .30: .40:CMP AL,',' JE .10: CMP AL,' ' JA .30: .45:CMP ESI,EDX JNB .10: LODSB CMP AL,' ' JNA .45: CMP AL,',' JE .10: DEC ESI JMP .10: .50:CMPD [%Param1],-1 ; Test if invoked from GetArgCount with ArgNr= -1. JNE .60: DEC ECX ; Omit the 0-th argument (the executable itself). MOV [%ReturnECX],ECX JMP .80: .60:MOVD [%ReturnECX],0 CMP ECX,[%Param1] STC JNE .90: MOV ESI,EBX ; Brutto ECX-th argument found at ESI..EDI. Trim spaces and commas. .65:CMP ESI,EDI JNB .75: LODSB CMP AL,' ' JBE .65: CMP AL,',' JE .65: DEC ESI .70:DEC EDI MOV AL,[EDI] CMP AL,' ' JBE .70: CMP AL,',' JE .70: INC EDI ; Netto argument is now at ESI..EDI. .75 MOV [%ReturnESI],ESI SUB EDI,ESI JC .80: MOV [%ReturnECX],EDI .80:CLC .90:POPAD RET 4 ENDP1 GetArgWin32A@RT:: %ENDIF AorW %ENDMACRO GetArg
GetArgCount %MACRO Unicode=%^UNICODE GetArg -1, Unicode=%Unicode %ENDMACRO GetArgCount
Macro PutArg retrieves ArgNumber-th argument from command-line, copies its content to the memory specified by BufPtr, BufSize and appends one NUL character at its end.
SIZE# %BufPtr
will be used instead.
EUROASM UNICODE=
.
When the argument value expects e.g. not more than 10 characters andUNICODE=Yes
, you should reserve BufSize at least 22 bytes (10+1 WIDE characters).
In €ASM you can define the output buffer asOutBuffer D (11 >> %^UNICODE) * BYTE
, which will assemble asOutBuffer D 11 * BYTE
whenUNICODE=0
and asOutBuffer D (11 << 1) * BYTE
whenUNICODE= -1
, always reserving room for 10+1 characters.
PutArg %MACRO ArgNumber, BufPtr, BufSize, Unicode=%^UNICODE sized? %IF %# = 2 mem? %IF %^PASS > 1 && TYPE#(SEGMENT# %BufPtr) != 'A' %ERROR ID=5814, 'Please specify the size of output buffer.' %EXITMACRO PutEnv %ELSE mem? ; BufPtr is specified as a memory variable with size. %PutArgSize %SETA SIZE# %BufPtr %ENDIF mem? %ELSE sized? ; BufSize is explicitly specified. %PutArgSize %SET %BufSize %ENDIF sized? PUSH EDX,ESI,EDI SUB EDX,EDX GetArg %ArgNumber,Unicode=%Unicode JC PutArgY%.: MOV EDX,%PutArgSize MOV EDI,%BufPtr INC ECX %IF %Unicode INC ECX %ENDIF CMP EDX,ECX JAE PutArgX%.: MOV ECX,EDX REP MOVSB JMP PutArgY%.: PutArgX%.:DEC ECX %IF %Unicode DEC ECX MOV EDX,ECX REP MOVSB MOV [EDI],CX %ELSE MOV EDX,ECX REP MOVSB MOV [EDI],CL %ENDIF PutArgY%.:MOV ECX,EDX POP EDI,ESI,EDX %ENDMACRO PutArg
Macro PutEnv retrieves environment-variable with specified zero-terminated name EnvName$ at run-time, and copies its content to the memory specified by BufPtr, BufSize, including the NUL character at its end.
SIZE# %BufPtr
will be used instead.
EUROASM UNICODE=
.
When the environment value expects e.g. not more than 10 characters andUNICODE=Yes
, you should reserve BufSize at least 22 bytes (10+1 WIDE characters).
In €ASM you can define the output buffer asOutBuffer D (11 >> %^UNICODE) * BYTE
, which will assemble asOutBuffer D 11 * BYTE
whenUNICODE=0
and asOutBuffer D (11 << 1) * BYTE
whenUNICODE= -1
, always reserving room for 10+1 characters.
PutEnv %MACRO EnvName$, BufPtr, BufSize, IgnoreCase=Yes, Unicode=%^UNICODE sized? %IF %# = 2 mem? %IF %^PASS > 1 && TYPE#(SEGMENT# %BufPtr) != 'A' %ERROR ID=5814, 'Please specify the size of output buffer.' %EXITMACRO PutEnv %ELSE mem? ; BufPtr is specified as a memory variable with size. %PutEnvSize %SETA SIZE# %BufPtr %ENDIF mem? %ELSE sized? ; BufSize is explicitly specified. %PutEnvSize %SET %BufSize %ENDIF sized? %PutEnvCase %SETB %IgnoreCase PUSHD %PutEnvCase, %PutEnvSize, %BufPtr, %EnvName$ ansi? %IF %Unicode CALL PutEnvWin32W@RT:: PutEnvWin32W@RT::PROC1 PUSHAD MOV EBP,ESP %PutEnvNameSize %SET EBP-4 %PutEnvBlock %SET EBP-8 SUB ESP,2*4 ; Room for two local %variables. XOR ECX,ECX XOR EAX,EAX MOV EDX,[%Param2] ; BufPtr. MOV EDI,[%Param1] ; EnvName$. MOV [%ReturnECX],EAX MOV [EDX],AX ; Prepare for the case when EnvName$ not found. NOT ECX MOV ESI,EDI REPNE SCASW NOT ECX MOV [%PutEnvNameSize],ECX ; Size in unichars including the terminating NUL. LEA EDX,[2*ECX+3] AND EDX,-4 ; Round EDX up to DWORD. SUB ESP,EDX ; Room for lowercase EnvName. MOV EDI,ESP .10: LODSW CMP AX,'A' JB .20: CMP AX,'Z' JA .20: OR AL,'x'^'X' ; Convert character to lowercase. .20: STOSW DEC ECX JNZ .10: IMPORT GetEnvironmentStringsW,FreeEnvironmentStringsW CALL GetEnvironmentStringsW:: MOV [%PutEnvBlock],EAX MOV EBX,EAX .30: MOV EDI,EBX XOR ECX,ECX XOR EAX,EAX NOT ECX MOV ESI,EDI CMP [EDI],AX ; Test the end of environment block. JZ .90: ; Return with ECX=0, CF=0, ZF=1. REPNE SCASW MOV EBX,EDI NOT ECX ; ESI..EDI is ASCIIZ string EnvName=EnvVal, brutto size in unichars=ECX. MOV EDI,ESI MOV AX,'=' REPNE SCASW JNE .30: SUB EDI,ESI SHR EDI,1 CMP EDI,[%PutEnvNameSize] JNE .30: LEA ECX,[EDI-1] ; ECX is unichar-size of netto string EnvName. TESTB [%Param4],1 ; PutEnvCase. JNZ .40: MOV EDI,[%Param1] ; Case sensitive search. REP CMPSW JNE .30: JMP .70: .40: MOV EDI,ESP ; Case insensitive search. .50: LODSW CMP AX,'A' JB .60: CMP AX,'Z' JA .60: OR AL,'x'^'X' ; Convert character to lowercase. .60: CMP AX,[EDI] JNE .30: INC EDI,EDI DEC ECX JNZ .50: .70: INC ESI,ESI ; EnvName was found. ESI is now ASCIIZ EnvVal. MOV EDI,ESI XOR ECX,ECX XOR EAX,EAX NOT ECX REPNE SCASW SUB EDI,ESI ; EDI= required-by-value brutto size of EnvVal in bytes. DEC EDI,EDI MOV [%ReturnECX],EDI ; Return ECX=netto size of EnvVal in bytes. INC EDI,EDI MOV ECX,[%Param3] ; BufSize. EnvVal allocated-by-user brutto size in bytes. CMP ECX,EDI XCHG ECX,EDI JAE .80: XCHG EDI,ECX .80: MOV EDI,[%Param2] ; BufPtr. REP MOVSB .90: PUSHFD PUSH [%PutEnvBlock] CALL FreeEnvironmentStringsW:: POPFD MOV ESP,EBP POPAD RET 4*4 ENDP1 PutEnvWin32W@RT:: %ELSE ansi? CALL PutEnvWin32A@RT:: PutEnvWin32A@RT::PROC1 PUSHAD MOV EBP,ESP %PutEnvNameSize %SET EBP-4 %PutEnvBlock %SET EBP-8 SUB ESP,2*4 ; Room for two local %variables. XOR ECX,ECX XOR EAX,EAX MOV EDX,[%Param2] ; BufPtr. MOV EDI,[%Param1] ; EnvName$. MOV [%ReturnECX],ECX MOV [EDX],AL ; Prepare for the case when EnvName$ not found. NOT ECX MOV ESI,EDI REPNE SCASB NOT ECX MOV [%PutEnvNameSize],ECX ; Including the terminating NUL. LEA EDX,[ECX+3] AND EDX,-4 ; Round EDX up to DWORD. SUB ESP,EDX ; Room for lowercase EnvName. MOV EDI,ESP .10: LODSB CMP AL,'A' JB .20: CMP AL,'Z' JA .20: OR AL,'x'^'X' ; Convert character to lowercase. .20: STOSB DEC ECX JNZ .10: IMPORT GetEnvironmentStringsA,FreeEnvironmentStringsA CALL GetEnvironmentStringsA:: MOV [%PutEnvBlock],EAX MOV EBX,EAX .30: MOV EDI,EBX XOR ECX,ECX XOR EAX,EAX NOT ECX MOV ESI,EDI CMP [EDI],AL ; Test the end of environment block. JZ .90: ; Return with ECX=0, CF=0, ZF=1. REPNE SCASB MOV EBX,EDI NOT ECX ; ESI..EDI is ASCIIZ string EnvName=EnvVal, brutto size=ECX. MOV EDI,ESI MOV AL,'=' REPNE SCASB JNE .30: SUB EDI,ESI CMP EDI,[%PutEnvNameSize] JNE .30: LEA ECX,[EDI-1] ; ESI,ECX is netto string EnvName. TESTB [%Param4],1 ; PutEnvCase. JNZ .40: MOV EDI,[%Param1] ; Case sensitive search. REP CMPSB JNE .30: JMP .70: .40: MOV EDI,ESP ; Case insensitive search. .50: LODSB CMP AL,'A' JB .60: CMP AL,'Z' JA .60: OR AL,'x'^'X' ; Convert character to lowercase. .60: CMP AL,[EDI] JNE .30: INC EDI DEC ECX JNZ .50: .70: INC ESI ; EnvName was found. ESI is now ASCIIZ EnvVal. MOV EDI,ESI XOR ECX,ECX XOR EAX,EAX NOT ECX REPNE SCASB SUB EDI,ESI ; EDI= required-by-value brutto size of EnvVal. DEC EDI MOV [%ReturnECX],EDI ; Return ECX=netto size of EnvVal. INC EDI MOV ECX,[%Param3] ; BufSize. EnvVal allocated-by-user brutto size. CMP ECX,EDI XCHG ECX,EDI JAE .80: XCHG EDI,ECX .80: MOV EDI,[%Param2] ; BufPtr. REP MOVSB .90: PUSHFD PUSH [%PutEnvBlock] CALL FreeEnvironmentStringsA:: POPFD MOV ESP,EBP POPAD RET 4*4 ENDP1 PutEnvWin32A@RT:: %ENDIF ansi? %ENDMACRO PutEnv
Macro StdOutput writes one or more concatenated strings to the standard output or to other equipment specified with the Handle identifier.
Strings are either zero-terminated, or the keyword Size= must specify its size in bytes. The terminating NUL character is never written.
If keyword Eol=Yes, macro writes CR+LF after all strings.
The output device is by default treated as a file (when Console=No
)
Such output is redirectable, but it writes WIDE string as is;
in OEM console are the UTF-16 encoded characters displayed as interlaced.
Output produced with Console=Yes
cannot be redirected by command-line operators
|, > or >but it accepts WIDE Unicode strings and displays
the text in TrueType console properly, including non-English characters.
Unicode= %^UNICODE is boolean specification whether the Strings are in WIDE (UTF-16) encoding. By default (if omitted) it copies the global optionWhen you want to use the Console (nondefault) mode in all StdOutput and StdInput invokations, you don't have to append
,Console=Yes
to every invokation ofStdOutput
andStdInput
if you set preprocessing %variable in the beginning of your program:%StdConsole %SETB Yes
.
EUROASM Unicode=
.StdOutput %MACRO String1,String2,,,Size=-1, Handle=-11, Eol=No, Console=%StdConsole, Unicode=%^UNICODE C %IF %Console U %IF %Unicode %StdOutputFlags %SETA 2 + 1 %ELSE U %StdOutputFlags %SETA 2 + 0 %ENDIF U %ELSE C W %IF %Unicode %StdOutputFlags %SETA 0 + 1 %ELSE W %StdOutputFlags %SETA 0 + 0 %ENDIF W %ENDIF C ArgNr %FOR 1..%#, STEP=1 ; Call the runtime for each String. PUSHD %StdOutputFlags, %1, %Size, %Handle CALL StdOutputWin32@RT %SHIFT 1 ; The next string to output. %ENDFOR ArgNr Eol %IF %Eol U %IF %Unicode PUSHD %StdOutputFlags+4, 0, 4, %Handle %ELSE U PUSHD %StdOutputFlags+4, 0, 2, %Handle %ENDIF U CALL StdOutputWin32@RT %ENDIF Eol StdOutputWin32@RT:: PROC1 ; Invoked in stdcall convention with parameters Handle,Size,Addr,Flags. PUSHAD MOV EBP,ESP SUB ESP,4+4 ; Room for Eol and address of characters-written. MOV [ESP],ESP WinAPI GetStdHandle,[%Param1],Fastmode=Yes ; %Param1=Handle. MOV EBX,EAX INC EAX STC JZ .90: ; Abort with CF when INVALID_HANDLE_VALUE (-1). MOV ECX,[%Param2] ; String maximal size. MOV EDI,[%Param3] ; String pointer. MOV EAX,[%Param4] ; Status flags. Bits 0=Unicode, 1=Console, 2=Eol. IMPORT WriteFile,WriteConsoleA,WriteConsoleW MOV EDX,WriteFile TEST AL,2 ; Select File or Console mode. JZ .10: MOV EDX,WriteConsoleA TEST AL,1 JZ .10: MOV EDX,WriteConsoleW .10:TEST AL,4 JZ .20: LEA EDI,[EBP-4] ; EOL is requested instead of string. MOVD [EDI],0x000A_000D ; WIDE EOL. TEST AL,1 JNZ .20: MOVW [EDI],0x0A0D ; ANSI EOL. .20:XOR EAX,EAX ; EDI,ECX is string to write MOV ESI,EDI TESTB [%Param4],1 ; ASCII | WIDE. JZ .40: SHR ECX,1 ; Convert size to length in characters. REPNE SCASW ; Find the WIDE zero terminator. JNE .50: DEC EDI,EDI ; Omit the zero terminator. JMP .50: .40:REPNE SCASB ; Find the ANSI zero terminator. JNE .50: DEC EDI .50:SUB EDI,ESI ; EDI is now string size in bytes. MOV EAX,[%Param4] ; Status flags. AND AL,3 XOR AL,3 JNZ .60: SHR EDI,1 ; EDI is now string size in WIDE characters for Console. .60:WinAPI EDX,EBX,ESI,EDI,[EBP-8],0,Fastmode=on CMP [EBP-8],EDI ; Set CF if not all characters were written. .90:MOV ESP,EBP POPAD RET 4*4 ENDP1 StdOutputWin32@RT:: %ENDMACRO StdOutput
Macro StdInput reads a line of text terminated with CR (Enter) from standard input device (usually the keyboard) specified by the Handle identifier.
The input device is by default treated as a file (when Console=No
). Such input is redirectable by command-line operators
< or | but it treats input characters as bytes. Console mode
uses console input buffer (no redirection works here) but it interprets WIDE characters properly.
When you want to use the Console (nondefault) mode in all StdOutput and StdInput invokations, you don't have to appendUnicode=%^UNICODE is boolean specification whether the characters read from console should be in WIDE (UTF-16) encoding.,Console=Yes
to every invokation ofStdOutput
andStdInput
if you set preprocessing %variable in the beginning of your program:%StdConsole %SETB Yes
.
StdInput %MACRO Buffer, Size=, Handle=-10, Console=%StdConsole, Unicode=%^UNICODE %IF "%Size" === "" PUSHD %Handle, SIZE# %Buffer, %Buffer %ELSE PUSHD %Handle, %Size, %Buffer %ENDIF XOR ECX,ECX ; ECX=0 when characters are 8bit ANSI. %IF %Console %IF %Unicode ; ReadConsole WIDE variant. IMPORT ReadConsoleW PUSHD ReadConsoleW INC ECX ; ECX=1 when characters are 16bit WIDE. %ELSE ; ReadConsole ANSI variant. IMPORT ReadConsoleA PUSHD ReadConsoleA %ENDIF %ELSE ; ReadFile variant. Ignores Unicode. IMPORT ReadFile PUSHD ReadFile %ENDIF ; %StdInputRT is now the name of runtime PROC1. CALL StdInputWin32@RT StdInputWin32@RT:: PROC1 ; StdCalled with parameters Function,Addr,Size,Handle,ECX. PUSHAD MOV EBP,ESP WinAPI GetStdHandle,[%Param4],Fastmode=on ; Get input handle. MOV ECX,EAX INC ECX STC JZ .90: ; Abort with CF when EAX=-1 (INVALID_HANDLE_VALUE). MOV ESI,[%Param1] ; Function. MOV EBX,[%Param3] ; Size. MOV ECX,[%ReturnECX] ; 0=ANSI or 1=WIDE. LEA EDX,[%ReturnECX] ; Address of number of characters read. MOV EDI,ECX ; Save 0 or 1 to EDI. SHR EBX,CL ; Convert Size in bytes to length in characters. WinAPI ESI,EAX,[%Param2],EBX,EDX,0,Fastmode=on XCHG ECX,EDI ; Restore 0 or 1 to CL. SHLD [%ReturnECX],CL ; Convert read length in characters to bytes. SUB EAX,1 ; Return CF if WinAPI returned FALSE (EAX=0). .90:POPAD RET 4*4 ENDPROC1 StdInputWin32@RT:: %ENDMACRO StdInput
Errorlevel=
, this value may also be specified as an ordinal operand.
TerminateProgram %MACRO Errorlevel=0 %IF %# = 1 ; If Errorlevel is provided as an ordinal. PUSHD %1 %ELSE PUSHD %Errorlevel ; If Errorlevel is provided as a keyword. %ENDIF IMPORT ExitProcess, Lib="kernel32.dll" CALL ExitProcess %ENDMACRO TerminateProgram
ENDHEAD winapi