Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
7389 theonlymir 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
; Hot Angles ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4
; Compile with FASM
7416 theonlymir 5
; Version 0.3.3: Sep 25, 2018
7389 theonlymir 6
 
7
; Copyright (c) 2018, Efremenkov Sergey aka TheOnlyMirage
8
; All rights reserved.
9
; Redistribution and use in source and binary forms, with or without modification,
10
; are permitted provided that the following conditions are met:
11
;    * Redistributions of source code must retain the above copyright notice, this
12
;    list of conditions and the following disclaimer.
13
;    * Redistributions in binary form must reproduce the above copyright  notice,
14
;    this list of conditions and the following disclaimer in the documentation and/or
15
;    other materials provided with the distribution.
16
;    * Neither the name of the  nor the names of its contributors may
17
;    be used to endorse or promote products derived from this software without
18
;    specific prior written permission.
19
 
20
; THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
21
; INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
22
; PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
23
; HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
24
; OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25
; SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26
; --------------------------------------------------------------------------------------
27
 
28
format binary as "" ;"kex"
29
use32
30
org 0x0    ; базовый адрес размещения кода, всегда 0x0
31
 
32
UNLOCKd = 0
33
LOCKd = 1
34
 
35
; заголовок
36
db 'MENUET01'     ;магический идентификатор
37
dd 0x01           ;версия
38
dd START_DEBUG          ;адрес точки старта программы
39
dd I_END          ;адрес конца, по факту размер файла программы
40
dd 0x100000       ;требуемое кол-во памяти для загрузки программы
41
dd 0x7fff0        ;начальное значение регистра esp - адрес конца области стэка так как стэк растет в сторону меньших адресов
42
dd 0, 0           ;адрес строки параметров и адрес строки пути исполняемого файла
43
 
44
 
45
include '../../macros.inc'
46
 
47
START_DEBUG:
48
   call copyKill         ;простейшая защита от повторного запуска
49
   mcall  68, 11         ;инициализация кучи
50
   call loadConfig       ;загружаем конфигурацию приложения
51
   mov ebx, 00000100000000000000000000100000b ;подписываемся на интересные нам события
52
   mcall 40
53
 
54
START:
55
  mov     eax, 10                 ; function 10 : wait until event
56
  mcall                           ; event type is returned in eax
57
 
58
  cmp   eax, 6           ;обработка перемещений и нажатия мыши
59
  je    mouse
60
 
61
  jmp START
62
 
63
mouse:
64
  ;основной цикл программы
65
  call get_mouse_pos ;получаем текущие координаты мыши
66
 
67
  cmp eax, 0 ;левый верхний угол
68
  jne @f
69
  ; -- здесь вызываем соотв. вызов для левого верхнего угла  (X=0, Y=0)
70
  push ecx
71
  mov ecx, 0
72
  call run_command
73
  pop ecx
74
 
75
  jmp START ;finish
76
@@:
77
  call get_screen_size ;иначе обновляем размеры экрана
78
 
79
  cmp ax, word[screen.height]    ;Ymouse = Yscreen ?
80
  je Ytrue
81
  ;если Y не равны, то нас интересует Y=0 и X=ScreenWidth (правый верхний угол)
82
 
83
  cmp ax, 0
84
  jne unlockend
85
  shr eax, 16
86
  cmp ax, word[screen.width]
87
  jne unlockend
88
  ; -- здесь вызываем для правого верхенего угла
89
  push ecx
90
  mov ecx, 2
91
  call run_command
92
  pop ecx
93
 
94
  jmp START
95
Ytrue:
96
  ;если Y равны, то нас интересует X=0 (левый нижний угол) или X=ScreenWidth (правый нижний)
97
  shr eax, 16
98
  cmp ax, 0
99
  jne @f
100
  ; -- X=0, Y = Height  (левый нижний угол)
101
  push ecx
102
  mov ecx, 1
103
  call run_command
104
  pop ecx
105
  jmp START
106
@@:
107
  cmp ax, word[screen.width]
108
  jne unlockend
109
  ; -- (правый нижний угол)
110
  push ecx
111
  mov ecx, 3
112
  call run_command
113
  pop ecx
114
 
115
  jmp START
116
 
117
unlockend:
118
  mov byte[state], UNLOCKd
119
  jmp START
120
 
121
 
122
;структурка данных для хранения параметров экрана
123
screen:
124
   .width  dw 0
125
   .height dw 0
126
;получить размер экрана
127
get_screen_size:
128
   push eax
129
   mcall 14
130
   ;теперь в eax = [xsize]*65536 + [ysize]
131
   ;mov dword[screen], eax
132
   mov word[screen.height], ax
133
   shr eax, 16
134
   mov word[screen.width], ax
135
   pop eax
136
   ret
137
 
138
 
139
;получить позицию мыши
140
get_mouse_pos:
141
   ;push eax
142
   push ebx
143
   mcall 37, 0
144
   pop ebx
145
   ;pop eax
146
   ret
147
 
148
 
149
;запуск приложения: ecx - активный угол: lu=0, ld=1, ru=2, rd=3
150
run_command:
151
   cmp byte[state], UNLOCKd
152
   jne run_command.end
153
 
154
   push eax
155
   push ebx
156
   push ecx
157
 
158
 
159
   cmp ecx, 0
160
   jne @f
161
   mov eax, dword[newData.lu] ;testData.lu
162
   mov dword[struct70.path_adr], eax
163
   jmp .end_set_path
164
@@:
165
   cmp ecx, 1
166
   jne @f
167
   mov eax, dword[newData.ld]
168
   mov dword[struct70.path_adr], eax
169
   jmp .end_set_path
170
@@:
171
   cmp ecx, 2
172
   jne @f
173
   mov eax, dword[newData.ru]
174
   mov dword[struct70.path_adr], eax
175
   jmp .end_set_path
176
@@:
177
   cmp ecx, 3
178
   jne .end_set_path
179
   mov eax, dword[newData.rd]
180
   mov dword[struct70.path_adr], eax
181
   jmp .end_set_path
182
.end_set_path:
183
 
184
   ;параметры
185
   ;mov dword[struct.adr],
186
 
7416 theonlymir 187
;если адрес 0, то ничего не делать
7389 theonlymir 188
   cmp dword[struct70.path_adr], 0
189
   jne .next
7416 theonlymir 190
   ;mov eax, testData.ld
191
   ;mov dword[struct70.path_adr], eax
192
   jmp @f
7389 theonlymir 193
.next:
194
;конец кода для замены
195
 
196
   mcall 70, struct70
7416 theonlymir 197
@@:
7389 theonlymir 198
   mov byte[state], LOCKd
199
 
200
   pop ecx
201
   pop ebx
202
   pop eax
203
.end:
204
   ret
205
 
206
struct70: ;Формат информационной структуры
207
  .func       dd 7 ; номер подфункции
208
  .mask       dd 0
209
  .param_adr  dd 0 ; указатель на ASCIIZ-строку с параметрами
210
  .other      dd 0, 0
211
  .path       db 0 ; "/rd/1/TINYPAD",0 ; путь
7416 theonlymir 212
  .path_adr   dd 0 ;testData.lu
7389 theonlymir 213
 
214
 
215
state: db 0 ; 0=unlock, 1=lock
7416 theonlymir 216
mode: db 0  ;режим работы (для будущего расширения функционала)
7389 theonlymir 217
 
7416 theonlymir 218
;testData:
219
;  .lu db '/rd/1/SHELL', 0
220
;  .ld db '/rd/1/RUN', 0
221
;  .ru db "/rd/1/TINYPAD", 0
222
;  .rd db '/rd/1/File Managers/EOLITE', 0
7389 theonlymir 223
 
224
newData:  ;табличка адресов командных строк
225
  .lu dd 0
226
  .ld dd 0
227
  .ru dd 0
228
  .rd dd 0
229
newDataEnd:
230
 
231
;имя конфигурационного файла
7416 theonlymir 232
fileName: db 'SETTINGS/HOTANGLES.CFG', 0
7389 theonlymir 233
 
234
loadConfig:
7416 theonlymir 235
   push eax ebx ecx edx
7389 theonlymir 236
   mcall 68, 27, fileName   ;загружаем конфигурационный файл в ОЗУ
237
   cmp eax, 0
238
   je loadConfig.exit       ;если файла конфигурации нет, то завершаем работу приложения
239
   ;иначе данные загружены в ОЗУ, размер в edx
240
   cmp edx, 0               ;если файл пуст, в нём нет данных, то завершаем работу
241
   je loadConfig.exit
242
 
243
   add edx, eax             ;иначе кладём в edx - адрес конца файла
244
 
245
   cmp byte[eax], 121 ;'y'  ;если параметр активности приложения имеет статус: не активно
246
   jne loadConfig.exit      ;то завершаем работу приложения
247
 
248
   push edi
249
   push esi
250
   ; сохраняем в edi указатель на начало таблицы адресов наших команд
251
   mov edi, newData
252
   ; сохраняем адреса строк и добавляем 0 в конце
253
   mov esi, eax
254
.block:
255
   inc esi
256
   cmp byte[esi], 10         ;если очередной код символа 10 или 13, то пропускаем символы
257
   je loadConfig.propusk     ;до первого отличного от них
258
   cmp byte[esi], 13
259
   je loadConfig.propusk
260
 
7416 theonlymir 261
   ; символ отличен от переноса строки и возврата каретки - если это на знак минус, то запоминаем его
7389 theonlymir 262
   mov dword[edi], esi
263
   add edi, 4
264
 
265
   ;идём до конца этой строки: пока не встретим очередной 10, 13, 0 или file end
266
.while:
267
   inc esi
268
   cmp esi, edx           ;тут будет проблема - тк файл закончился, а нуля не было !!! исправить
269
   jae loadConfig.fileend
270
   cmp byte[esi], 10
271
   je loadConfig.ura
272
   cmp byte[esi], 0
273
   je loadConfig.ura
274
   cmp byte[esi], 13
275
   jne loadConfig.while
276
.ura:
277
   mov byte[esi], 0
278
 
7416 theonlymir 279
   ;cmp byte[esi-1], '-'
280
   ;jne @f
281
   push esi  ;если это был знак минус, то меняем адрес на ноль
282
   mov esi, dword[edi-4]
283
   cmp byte[esi], '-'
284
   jne @f
285
   cmp byte[esi+1], 0
286
   jne @f
287
   mov dword[edi-4], 0
288
@@:
289
   pop esi
290
 
7389 theonlymir 291
   cmp edi, newDataEnd ;newData.end      ;если вся таблица адресов заполнена, то выходим из цикла
292
   jb loadConfig.block
293
.fileend:
294
 
295
   pop esi
296
   pop edi
297
 
298
   jmp loadConfig.end
299
 
300
.propusk:
301
   mov byte[esi], 0
302
   jmp loadConfig.block
303
.exit:
7416 theonlymir 304
   pop edx ecx ebx eax
7389 theonlymir 305
   mcall -1 ;закрыть эту программу
306
.end:
7416 theonlymir 307
   pop edx ecx ebx eax
7389 theonlymir 308
   ret
309
 
310
 
311
 
312
 
313
;Вынести код ниже в отдельный общий модуль
314
selfName db '@HOTANGLES',0
315
selfNameSize = 10 ;до 11 byte
316
;
317
compareBytes:
318
   push edi esi ecx ebx
319
   mov eax, 0 ;xor eax, eax
320
   mov ecx, selfNameSize    ;max размер строк 11
321
@@:
322
   mov bl, byte[edi]
323
   cmp bl, byte[esi]
324
   jne compareBytes.no
325
   inc edi
326
   inc esi
327
   cmp ecx, 0
328
   je @f
329
   dec ecx
330
   jmp @b
331
.no:
332
   mov eax, 1
333
@@:
334
   pop ebx ecx esi edi
335
   ret
336
;
337
slotMax dd 0
338
selfPID dd 0
339
buf db 1024 dup(0)
340
copyKill:
341
   push eax ebx ecx esi edi
342
 
343
   ;сперва прочтём свою информацию
344
   mcall 9, buf, -1
345
   mov eax, dword[buf+30]
346
   mov dword[selfPID], eax
347
 
348
   ;указатели, которые никогда не меняются:
349
   mov esi, selfName       ;первая строка - имя текущего приложения
350
   mov edi, buf            ;вторая строка - имя текущего слота
351
   add edi, 10
352
 
353
   mov ecx, 1
354
@@:
355
   mcall 9, buf, ecx
356
   mov dword[slotMax], eax
357
 
358
   ;если это мы сами, то пропускаем проверку
359
   mov eax, dword[buf+30]
360
   cmp eax, dword[selfPID]
361
   je copyKill.propusk
362
 
363
   call compareBytes   ;сравниваем 11 байт строк, результат в eax
364
 
365
   cmp eax, 0
366
   je copyKill.selfKill
367
 
368
.propusk:
369
   inc ecx
370
   cmp ecx, dword[slotMax]
371
   ja @f
372
   jmp @b
373
 
374
.selfKill:
375
   pop edi esi ecx ebx eax
376
   mcall -1
377
   ret
378
@@:
379
   pop edi esi ecx ebx eax
380
   ret
381
 
382
 
383
 
384
I_END: