-
Notifications
You must be signed in to change notification settings - Fork 3
/
Arg_GetArgumentW.asm
173 lines (150 loc) · 4.16 KB
/
Arg_GetArgumentW.asm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
;==============================================================================
;
; UASM64 Library
;
; https://github.com/mrfearless/UASM64-Library
;
;==============================================================================
.686
.MMX
.XMM
.x64
option casemap : none
IF @Platform EQ 1
option win64 : 11
ENDIF
option frame : auto
include UASM64.inc
.CODE
UASM64_ALIGN
;------------------------------------------------------------------------------
; Arg_GetArgumentW
;
; Return the contents of an argument from an argument list by its number.
;
; Parameters:
;
; * lpszArgumentList - The address of the zero terminated argument list.
;
; * lpszDestination - The address of the destination buffer.
;
; * nArgument - The number of the argument to return.
;
; * qwNotUsed - Not used, for compatibility with Masm32 ArgByNumber and
; Arg_GetArgumentA, using same amount of parameters for each.
;
; Returns:
;
; The return value is the updated next read offset in the source if it is
; greater than zero.
;
; The three possible return values are:
; > 1 = The next read offset in the source.
; 0 = The end of the argument list has been reached.
; -1 = A non matching quotation error has occurred in the source.
;
; Notes:
;
; This function supports double quoted text and it is delimited by the space
; character, a tab or a comma or any combination of these three. It may be used
; in two separate modes, single argument mode and streaming mode.
;
; In separate argument mode you specify the argument you wish to obtain with
; the nArgument parameter and you set the qwArgumentListReadOffset parameter to
; zero.
;
; In streaming mode you set a variable to zero and pass it as the 4th parameter
; qwArgumentListReadOffset and save the RAX return value back into this variable
; for the next call to the function. The nArgument parameter in streaming mode
; should be set to one "1"
;
; To support the notation of an empty pair of double quotes in an argument list
; the parser in this algorithm return an empty destination buffer that has an
; ascii zero as it first character.
;
; This function as based on the MASM32 Library function: ucArgByNum
;
; See Also:
;
; Arg_GetCommandLineW, Arg_GetCommandLineExW
;
;------------------------------------------------------------------------------
Arg_GetArgumentW PROC FRAME USES RBX RCX RDX RDI RSI lpszArgumentList:QWORD, lpszDestination:QWORD, nArgument:QWORD, qwNotUsed:QWORD
mov rsi, lpszArgumentList
mov rcx, 1
xor rax, rax
mov rdx, lpszDestination
mov WORD PTR [rdx], 0
; ------------------------------------
; handle src as pointer to NULL string
; ------------------------------------
cmp WORD PTR [rsi], 0
jne next1
jmp bailout
next1:
sub rsi, 2
ftrim:
add rsi, 2
mov ax, WORD PTR [rsi]
cmp ax, 32
je ftrim
cmp ax, 9
je ftrim
cmp ax, 0
je bailout ; exit on empty string (only white space)
cmp WORD PTR [rsi], 34
je quoted
sub rsi, 2
; ----------------------------
unquoted:
add rsi, 2
mov ax, WORD PTR [rsi]
test ax, ax
jz scanout
cmp ax, 32
je wordend
mov WORD PTR [rdx], ax
add rdx, 2
jmp unquoted
wordend:
cmp rcx, nArgument
je scanout
add rcx, 1
mov rdx, lpszDestination
mov WORD PTR [rdx], 0
jmp ftrim
; ----------------------------
quoted:
add rsi, 2
mov ax, WORD PTR [rsi]
test ax, ax
jz scanout
cmp ax, 34
je quoteend
mov WORD PTR [rdx], ax
add rdx, 2
jmp quoted
quoteend:
add rdi, 2
cmp rcx, nArgument
je scanout
add rcx, 1
mov rdx, lpszDestination
mov WORD PTR [rdx], 0
jmp ftrim
; ----------------------------
scanout:
.if nArgument > rcx
bailout: ; error exit
mov rdx, lpszDestination ; reload dest address
mov WORD PTR [rdx], 0 ; zero dest buffer
xor rax, rax ; zero return value
jmp quit
.else ; normal exit
mov WORD PTR [rdx], 0 ; terminate output buffer
mov rax, rcx ; set the return value
.endif
quit:
ret
Arg_GetArgumentW ENDP
END