-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcommand_handler.asm
243 lines (225 loc) · 5.92 KB
/
command_handler.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
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
.486
.model flat, stdcall
option casemap:none
include command_handler.inc
include msvcrt.inc
MAXLENGTH = 128 ; max length of a console input
.data
key_input KEY_INPUT <>
console_input_string_length DWORD 0 ; current string length
console_cursor_index DWORD 0 ; console cursor index
console_input_string BYTE MAXLENGTH + 1 DUP(?) ; inpur string
process_result BYTE MAXLENGTH DUP (?)
process_result_length DWORD ?
_command_arg BYTE MAXLENGTH DUP(?)
_response_file_save BYTE 'file saved as %s', 0
_response_file_save_fail BYTE 'failed to save file', 0
_response_file_open BYTE 'open file %s', 0
_response_file_open_fail BYTE 'failed to open file', 0
_response_unknow_command BYTE 'unknown command', 0
.code
InitCommandHandler PROTO
AddACharFromConsole PROTO
AdjustDirectionLeft PROTO
AdjustDirectionRight PROTO
CommandBackHandler PROTO
CommandDeleteHandler PROTO
ProcessCommand PROTO
CopyArg PROTO
;分发函数 判断字符的类型
; case 1:是 "enter"键
; case 2:是 左键或者右键
; case 3:是 可接收的字符
; case 4:其它字符,忽略
InitCommandHandler PROC
mov console_cursor_index, 0
mov console_input_string_length, 0
ret
InitCommandHandler ENDP
CommandHandler PROC user_input:KEY_INPUT
; 不是特殊按键,是可以添加的字符
mov_m2m key_input.is_special, user_input.is_special
mov_m2m key_input.virtual_key, user_input.virtual_key
mov al, user_input.ascii_char
mov key_input.ascii_char, al
.IF (key_input.is_special == 0)
Invoke AddACharFromConsole
; 是特殊按键
.ELSE
;是左键
.IF(key_input.virtual_key == VK_LEFT)
Invoke AdjustDirectionLeft
;是右键
.ELSEIF(key_input.virtual_key == VK_RIGHT)
Invoke AdjustDirectionRight
; 是Backspace键
.ELSEIF(key_input.virtual_key == VK_BACK)
Invoke CommandBackHandler
; 是delete键
.ELSEIF(key_input.virtual_key == VK_DELETE)
Invoke CommandDeleteHandler
;是Enter键
.ELSEIF(key_input.virtual_key == VK_RETURN)
Invoke ProcessCommand
.ENDIF
.ENDIF
ret
CommandHandler ENDP
; case 2:是 左键,调整逻辑鼠标位
AdjustDirectionLeft PROC
.IF console_cursor_index != 0
dec console_cursor_index
.ENDIF
ret
AdjustDirectionLeft ENDP
; case 3:是 右键,调整逻辑鼠标位
AdjustDirectionRight PROC
mov ebx,console_cursor_index
.IF(ebx != console_input_string_length)
inc console_cursor_index
.ENDIF
ret
AdjustDirectionRight ENDP
; backspace 键逻辑
CommandBackHandler PROC
mov ebx,console_input_string_length
; 在最开头
.IF(console_cursor_index == 0)
ret
; 若否
.ELSE
mov edi, OFFSET console_input_string
add edi, console_cursor_index
dec edi
mov esi, edi
inc esi
mov ecx, console_input_string_length
sub ecx, console_cursor_index
cld
rep movsb
dec console_input_string_length
dec console_cursor_index
comment~
; 在末位加0
mov esi, OFFSET console_input_string
add esi, console_input_string_length
mov BYTE PTR [esi], 0
~
.ENDIF
ret
CommandBackHandler ENDP
; delete 键逻辑
CommandDeleteHandler PROC
mov ebx,console_input_string_length
; 在最右端,无法删除
.IF(ebx == console_cursor_index )
ret
.ELSE
mov edi,OFFSET console_input_string
add edi,console_cursor_index
mov esi,edi
inc esi
mov ecx,console_input_string_length
sub ecx,console_cursor_index
dec ecx
cld
rep movsb
dec console_input_string_length
; 补 0
mov esi, OFFSET console_input_string
add esi, console_input_string_length
mov BYTE PTR [esi], 0
.ENDIF
ret
CommandDeleteHandler ENDP
; case 4:是 可接收的字符
AddACharFromConsole PROC
mov ebx,console_cursor_index
.IF console_input_string_length == MAXLENGTH
ret
.ELSE
; 把在index和length之间的字符全部后移一位
mov esi, OFFSET console_input_string
add esi, console_input_string_length
mov edi, esi
dec esi
mov ecx, console_input_string_length
sub ecx, console_cursor_index
std
rep movsb
; 插入要插的那个字符
mov esi, OFFSET console_input_string
add esi, console_cursor_index
mov [esi],al
; 鼠标位置与输入字符串长度均+1
inc console_input_string_length
inc console_cursor_index
.ENDIF
ret
AddACharFromConsole ENDP
; 接收到enter键,去处理指令,要去实现的命令如下
; :w 将缓冲区写入文件,即保存修改,参数表示文件名
; :q 退出,如果对缓冲区进行过修改,则会提示
; :e 打开文件
ProcessCommand PROC
mov esi, OFFSET console_input_string
.IF (BYTE PTR [esi]) == 'w'
invoke CopyArg
;调用保存函数
invoke WriteListToFile, addr _command_arg
.IF eax == 0
pushad
invoke crt_sprintf, addr process_result, addr _response_file_save, OFFSET _command_arg
invoke crt_strlen, addr process_result
mov process_result_length, eax
popad
.ELSE
pushad
invoke crt_sprintf, addr process_result, addr _response_file_save_fail, OFFSET _command_arg
invoke crt_strlen, addr process_result
mov process_result_length, eax
popad
.ENDIF
.ELSEIF (BYTE PTR [esi]) == 'e'
invoke CopyArg
;调用打开函数
invoke DestroyList, addr text_list
invoke ReadFileToList, addr _command_arg
.IF eax == 0
pushad
invoke crt_sprintf, addr process_result, addr _response_file_open, OFFSET _command_arg
invoke crt_strlen, addr process_result
mov process_result_length, eax
popad
.ELSE
pushad
invoke crt_sprintf, addr process_result, addr _response_file_open_fail
invoke crt_strlen, addr process_result
mov process_result_length, eax
popad
.ENDIF
.ELSEIF BYTE PTR [esi] == 'q'
;直接退出
invoke ExitProcess, 0
.ELSE
pushad
invoke crt_sprintf, addr process_result, addr _response_unknow_command
invoke crt_strlen, addr process_result
mov process_result_length, eax
popad
.ENDIF
ret
ProcessCommand ENDP
CopyArg PROC
mov edi, OFFSET _command_arg
mov esi, OFFSET console_input_string
add esi, 2 ;假定命令从第二个起
.IF console_input_string_length >=2
mov ecx, console_input_string_length
sub ecx, 2
rep movsb
.ENDIF
mov BYTE PTR [edi], 0
ret
CopyArg ENDP
END