Rev 1148 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
589 | diamond | 1 | ; |
2 | ; project name: KFar_Arc - plugin for KFar, which supports various archives |
||
3 | ; target platform: KolibriOS |
||
4 | ; compiler: FASM 1.67.14 |
||
1148 | diamond | 5 | ; version: 0.17 |
6673 | IgorA | 6 | ; last update: 2016-11-04 (Nov 04, 2016) |
926 | diamond | 7 | ; minimal KFar version: 0.43 |
589 | diamond | 8 | ; minimal kernel: no limit |
9 | ; |
||
10 | ; author: Diamond |
||
11 | ; email: diamondz@land.ru |
||
1148 | diamond | 12 | ; web: http://diamond.kolibrios.org |
589 | diamond | 13 | ; |
14 | |||
15 | ; standard start of Kolibri dynamic library |
||
16 | format MS COFF |
||
17 | public EXPORTS |
||
18 | |||
19 | section '.flat' code readable align 16 |
||
20 | |||
21 | ; include auxiliary procedures |
||
6673 | IgorA | 22 | include 'kglobals.inc' ; iglobal/uglobal |
23 | include 'lang.inc' ; define language for localized strings |
||
24 | include 'crc.inc' ; CRC32 calculation |
||
25 | include 'sha256.inc' ; SHA-256 hash algorithm |
||
26 | include 'aes.inc' ; AES crypto algorithm |
||
589 | diamond | 27 | ; include main code for archives loading |
6673 | IgorA | 28 | include '7z.inc' ; *.7z |
29 | include 'lzma.inc' ; LZMA-decoder for *.7z |
||
30 | include 'ppmd.inc' ; PPMD-decoder for *.7z |
||
31 | include '7zbranch.inc' ; branch filters for *.7z |
||
32 | include '7zaes.inc' ; AES cryptor for *.7z |
||
33 | include 'zip.inc' ; *.zip |
||
34 | include 'deflate.inc' ; Deflate[64] decoder for *.7z and *.zip |
||
35 | include '../zlib/zlib.asm' ; deflate coder |
||
589 | diamond | 36 | |
37 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
||
38 | ;;;;;;;;;;;;;;; Interface for KFar ;;;;;;;;;;;;;; |
||
39 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
||
40 | virtual at 0 |
||
41 | kfar_info_struc: |
||
6673 | IgorA | 42 | .lStructSize dd ? |
43 | .kfar_ver dd ? |
||
44 | .open dd ? |
||
45 | .open2 dd ? |
||
46 | .read dd ? |
||
47 | .write dd ? |
||
48 | .seek dd ? |
||
49 | .tell dd ? |
||
50 | .flush dd ? |
||
51 | .filesize dd ? |
||
52 | .close dd ? |
||
53 | .pgalloc dd ? |
||
54 | .pgrealloc dd ? |
||
55 | .pgfree dd ? |
||
56 | .getfreemem dd ? |
||
57 | .pgalloc2 dd ? |
||
58 | .pgrealloc2 dd ? |
||
59 | .pgfree2 dd ? |
||
60 | .menu dd ? |
||
61 | .menu_centered_in dd ? |
||
62 | .DialogBox dd ? |
||
63 | .SayErr dd ? |
||
64 | .Message dd ? |
||
65 | .cur_console_size dd ? |
||
589 | diamond | 66 | end virtual |
67 | |||
68 | ; int __stdcall plugin_load(kfar_info* info); |
||
69 | ; Initialization of plugin + Save used KFar functions. |
||
70 | plugin_load: |
||
6673 | IgorA | 71 | mov eax, [esp+4] |
72 | mov [kfar_info], eax |
||
73 | push [eax+kfar_info_struc.open2] |
||
74 | pop [open2] |
||
75 | push [eax+kfar_info_struc.filesize] |
||
76 | pop [filesize] |
||
77 | push [eax+kfar_info_struc.read] |
||
78 | pop [read] |
||
79 | push [eax+kfar_info_struc.seek] |
||
80 | pop [seek] |
||
81 | push [eax+kfar_info_struc.close] |
||
82 | pop [close] |
||
83 | lea esi, [eax+kfar_info_struc.DialogBox] |
||
84 | mov edi, DialogBox |
||
85 | movsd |
||
86 | movsd |
||
87 | movsd |
||
88 | movsd |
||
89 | lea esi, [eax+kfar_info_struc.pgalloc] |
||
90 | mov edi, pgalloc |
||
91 | movsd |
||
92 | movsd |
||
93 | movsd |
||
94 | movsd |
||
95 | call init_crc_table |
||
96 | call init_aes |
||
97 | call init_ppmd |
||
98 | xor eax, eax ; success |
||
99 | ret 4 |
||
589 | diamond | 100 | |
631 | diamond | 101 | ; HANDLE __stdcall OpenFilePlugin(HANDLE basefile, |
102 | ; const void* attr, const void* data, int datasize, |
||
103 | ; int baseplugin_id, HANDLE baseplugin_instance, const char* name); |
||
589 | diamond | 104 | ; This function is called when user presses Enter (or Ctrl+PgDn) on file. |
105 | ; Plugin tests whether given file is of supported type |
||
106 | ; and if so, loads information and returns |
||
107 | ; handle to be used in subsequent calls to ReadFolder, SetFolder and so on. |
||
108 | OpenFilePlugin: |
||
6673 | IgorA | 109 | mov [bPasswordDefined], 0 |
110 | mov esi, [esp+12] |
||
111 | mov ebp, [esp+4] |
||
589 | diamond | 112 | ; test for 7z archive |
6673 | IgorA | 113 | cmp dword [esp+16], 20h ; minimal size of 7z archive is 20h bytes |
114 | jb .no_7z |
||
115 | cmp word [esi], '7z' ; signature, part 1 |
||
116 | jnz .no_7z |
||
117 | cmp dword [esi+2], 0x1C27AFBC ; signature, part 2 |
||
118 | jnz .no_7z |
||
119 | call open_7z |
||
120 | ret 28 |
||
589 | diamond | 121 | .no_7z: |
631 | diamond | 122 | ; test for zip archive |
6673 | IgorA | 123 | cmp dword [esp+16], 22 ; minimal size of zip archive is 22 bytes |
124 | jb .no_zip |
||
125 | cmp word [esi], 0x4B50 |
||
126 | jnz .no_zip |
||
127 | cmp word [esi+2], 0x0403 |
||
128 | jz .zip |
||
129 | cmp word [esi+2], 0x0201 |
||
130 | jz .zip |
||
131 | cmp word [esi+2], 0x0606 |
||
132 | jz .zip |
||
133 | cmp word [esi+2], 0x0706 |
||
134 | jz .zip |
||
135 | cmp word [esi+2], 0x0605 |
||
136 | jnz .no_zip |
||
631 | diamond | 137 | .zip: |
6673 | IgorA | 138 | call open_zip |
139 | ret 28 |
||
631 | diamond | 140 | .no_zip: |
6673 | IgorA | 141 | xor eax, eax |
142 | ret 28 |
||
589 | diamond | 143 | |
144 | ; Handle of plugin in kfar_arc is as follow: |
||
145 | virtual at 0 |
||
146 | handle_common: |
||
6673 | IgorA | 147 | .type dd ? |
148 | .root.subfolders dd ? |
||
149 | .root.subfolders.end dd ? |
||
150 | .root.subfiles dd ? |
||
151 | .root.subfiles.end dd ? |
||
152 | .root.NumSubItems dd ? |
||
153 | .curdir dd ? |
||
154 | .NumFiles dd ? |
||
589 | diamond | 155 | ; ... some plugin-specific data follows ... |
156 | end virtual |
||
157 | |||
158 | ; and for each archive item there is one file info structure, which begins as follow: |
||
159 | virtual at 0 |
||
160 | file_common: |
||
6673 | IgorA | 161 | .fullname dd ? ; pointer to cp866 string |
162 | .name dd ? ; name without path (end of .fullname) |
||
163 | .namelen dd ? ; strlen(.name) |
||
164 | .bIsDirectory db ? |
||
165 | .bPseudoFolder db ? |
||
166 | rb 2 |
||
167 | .parent dd ? ; pointer to parent directory record |
||
168 | .subfolders dd ? ; head of L2-list of subfolders [for folders] |
||
169 | .subfolders.end dd ? |
||
170 | .subfiles dd ? ; head of L2-list of files [for folders] |
||
171 | .subfiles.end dd ? |
||
172 | .NumSubItems dd ? |
||
173 | .next dd ? ; next item in list of subfolders/files |
||
174 | .prev dd ? ; previous item in list of subfolders/files |
||
175 | .stamp dd ? ; stamp for GetFiles |
||
589 | diamond | 176 | end virtual |
177 | |||
178 | ; void __stdcall ClosePlugin(HANDLE hPlugin); |
||
179 | ; This function frees all resources allocated in OpenFilePlugin. |
||
180 | ClosePlugin: |
||
6673 | IgorA | 181 | mov eax, [esp+4] ; get hPlugin |
182 | mov eax, [eax] ; hPlugin is pointer to internal data structure |
||
183 | ; first dword is archive type (type_xxx constants) |
||
184 | dec eax ; types start from 1 |
||
185 | jmp dword [ClosePluginTable+eax*4] |
||
589 | diamond | 186 | |
187 | ; int __stdcall ReadFolder(HANDLE hPlugin, |
||
188 | ; unsigned dirinfo_start, unsigned dirinfo_size, void* dirdata); |
||
189 | ReadFolder: |
||
631 | diamond | 190 | ; init header |
6673 | IgorA | 191 | mov edi, [esp+16] |
192 | mov ecx, 32/4 |
||
193 | xor eax, eax |
||
194 | rep stosd |
||
195 | mov byte [edi-32], 1 ; version |
||
196 | mov ebp, [esp+4] |
||
631 | diamond | 197 | ; get current directory |
6673 | IgorA | 198 | lea ebx, [ebp+handle_common.root.subfolders] |
199 | cmp [ebp+handle_common.curdir], 0 |
||
200 | jz @f |
||
201 | mov ebx, [ebp+handle_common.curdir] |
||
202 | add ebx, file_common.subfolders |
||
631 | diamond | 203 | @@: |
6673 | IgorA | 204 | mov ecx, [ebx+16] |
205 | mov [edi-24], ecx ; number of files |
||
631 | diamond | 206 | ; edi points to BDFE |
6673 | IgorA | 207 | push 6 ; assume EOF |
208 | pop eax |
||
209 | sub ecx, [esp+8] |
||
210 | ja @f |
||
211 | and dword [edi-28], 0 ; number of files read |
||
212 | ret 10h |
||
631 | diamond | 213 | @@: |
6673 | IgorA | 214 | cmp ecx, [esp+12] |
215 | jb @f |
||
216 | mov ecx, [esp+12] |
||
217 | xor eax, eax ; OK |
||
631 | diamond | 218 | @@: |
6673 | IgorA | 219 | mov [edi-28], ecx |
220 | push eax |
||
631 | diamond | 221 | ; copy files data |
6673 | IgorA | 222 | jecxz .done |
631 | diamond | 223 | ; seek to required item |
6673 | IgorA | 224 | mov eax, [esp+8+4] |
225 | mov esi, [ebx] |
||
631 | diamond | 226 | .0: |
6673 | IgorA | 227 | test esi, esi |
228 | jnz .1 |
||
229 | mov esi, [ebx+8] |
||
631 | diamond | 230 | .1: |
6673 | IgorA | 231 | add esi, ebp |
232 | dec eax |
||
233 | js .2 |
||
234 | mov esi, [esi+file_common.next] |
||
235 | jmp .0 |
||
631 | diamond | 236 | .2: |
237 | .copy: |
||
6673 | IgorA | 238 | pushad |
239 | mov eax, esi |
||
240 | mov ecx, [ebp] |
||
241 | call dword [getattrTable+(ecx-1)*4] |
||
242 | pop edi esi |
||
243 | push esi edi |
||
244 | add edi, 40 |
||
245 | mov ecx, [esi+file_common.namelen] |
||
246 | mov esi, [esi+file_common.name] |
||
247 | rep movsb |
||
248 | mov byte [edi], 0 |
||
249 | popad |
||
250 | add edi, 304 |
||
251 | mov esi, [esi+file_common.next] |
||
252 | test esi, esi |
||
253 | jnz @f |
||
254 | mov esi, [ebx+8] |
||
631 | diamond | 255 | @@: |
6673 | IgorA | 256 | add esi, ebp |
257 | loop .copy |
||
631 | diamond | 258 | .done: |
6673 | IgorA | 259 | pop eax |
260 | ret 10h |
||
589 | diamond | 261 | |
262 | ; bool __stdcall SetFolder(HANDLE hPlugin, |
||
263 | ; const char* relative_path, const char* absolute_path); |
||
264 | SetFolder: |
||
6673 | IgorA | 265 | mov ebp, [esp+4] |
266 | mov edx, [ebp+handle_common.curdir] |
||
267 | mov esi, [esp+8] |
||
268 | cmp dword [esi], '..' |
||
269 | jz .toparent |
||
270 | xor ecx, ecx |
||
631 | diamond | 271 | @@: |
6673 | IgorA | 272 | inc ecx |
273 | cmp byte [esi+ecx], 0 |
||
274 | jnz @b |
||
275 | mov ebx, [ebp+handle_common.root.subfolders] |
||
276 | test edx, edx |
||
277 | jz .scan |
||
278 | mov ebx, [edx+file_common.subfolders] |
||
631 | diamond | 279 | .scan: |
6673 | IgorA | 280 | test ebx, ebx |
281 | jz .err |
||
282 | add ebx, ebp |
||
283 | cmp [ebx+file_common.namelen], ecx |
||
284 | jnz .cont |
||
285 | push ecx esi |
||
286 | mov edi, [ebx+file_common.name] |
||
287 | repz cmpsb |
||
288 | pop esi ecx |
||
289 | jz .set |
||
631 | diamond | 290 | .cont: |
6673 | IgorA | 291 | mov ebx, [ebx+file_common.next] |
292 | jmp .scan |
||
631 | diamond | 293 | .toparent: |
6673 | IgorA | 294 | test edx, edx |
295 | jz .err |
||
296 | mov ebx, [edx+file_common.parent] |
||
297 | test ebx, ebx |
||
298 | jz @f |
||
299 | add ebx, ebp |
||
631 | diamond | 300 | @@: |
301 | .set: |
||
6673 | IgorA | 302 | mov [ebp+handle_common.curdir], ebx |
303 | mov al, 1 |
||
304 | ret 12 |
||
631 | diamond | 305 | .err: |
6673 | IgorA | 306 | xor eax, eax |
307 | ret 12 |
||
589 | diamond | 308 | |
631 | diamond | 309 | iglobal |
310 | cur_stamp dd 0 |
||
311 | endg |
||
312 | |||
313 | uglobal |
||
6673 | IgorA | 314 | tmp_bdfe rb 304 |
631 | diamond | 315 | endg |
316 | |||
589 | diamond | 317 | ; void __stdcall GetFiles(HANDLE hPlugin, int NumItems, void* items[], |
318 | ; void* addfile, void* adddir); |
||
319 | ; bool __stdcall addfile(const char* name, void* bdfe_info, HANDLE hFile); |
||
320 | ; bool __stdcall adddir(const char* name, void* bdfe_info); |
||
321 | GetFiles: |
||
6673 | IgorA | 322 | mov ebp, [esp+4] |
323 | mov ecx, [ebp+handle_common.NumFiles] |
||
324 | test ecx, ecx |
||
325 | jz .ret |
||
326 | mov ebx, ebp |
||
327 | mov eax, [ebx] |
||
328 | add ebx, [basesizes+(eax-1)*8] |
||
329 | inc [cur_stamp] |
||
631 | diamond | 330 | .loop: |
6673 | IgorA | 331 | push ecx |
332 | mov esi, [ebx+file_common.fullname] |
||
333 | mov edx, [ebp+handle_common.curdir] |
||
334 | test edx, edx |
||
335 | jz .incur |
||
336 | mov eax, [cur_stamp] |
||
337 | mov [edx+file_common.stamp], eax |
||
338 | mov edi, [edx+file_common.fullname] |
||
339 | mov ecx, [edx+file_common.namelen] |
||
340 | add ecx, [edx+file_common.name] |
||
341 | sub ecx, edi |
||
342 | repz cmpsb |
||
343 | jnz .cont |
||
631 | diamond | 344 | .incur: |
6673 | IgorA | 345 | cmp byte [esi], '/' |
346 | jnz @f |
||
347 | inc esi |
||
631 | diamond | 348 | @@: |
6673 | IgorA | 349 | mov ecx, [esp+12] ; NumItems |
350 | mov edx, [esp+16] ; items |
||
351 | cmp ecx, -1 |
||
352 | jz .ok |
||
631 | diamond | 353 | .check: |
6673 | IgorA | 354 | sub ecx, 1 |
355 | js .cont |
||
356 | push esi |
||
357 | mov edi, [edx] |
||
358 | add edi, 40 |
||
631 | diamond | 359 | @@: |
6673 | IgorA | 360 | lodsb |
361 | scasb |
||
362 | jnz @f |
||
363 | test al, al |
||
364 | jz .ok2 |
||
365 | jmp @b |
||
631 | diamond | 366 | @@: |
6673 | IgorA | 367 | pop esi |
368 | cmp al, '/' |
||
369 | jnz @f |
||
370 | cmp byte [edi-1], 0 |
||
371 | jz .ok |
||
631 | diamond | 372 | @@: |
6673 | IgorA | 373 | add edx, 4 |
374 | jmp .check |
||
631 | diamond | 375 | .ok2: |
6673 | IgorA | 376 | pop esi |
631 | diamond | 377 | .ok: |
378 | ; add all parents directories if needed |
||
379 | .parloope: |
||
6673 | IgorA | 380 | mov ecx, [ebx+file_common.parent] |
381 | jecxz .pardone |
||
382 | add ecx, ebp |
||
383 | mov eax, [cur_stamp] |
||
384 | cmp [ecx+file_common.stamp], eax |
||
385 | jz .pardone |
||
631 | diamond | 386 | .parloopi: |
6673 | IgorA | 387 | mov edx, ecx |
388 | mov ecx, [ecx+file_common.parent] |
||
389 | jecxz @f |
||
390 | add ecx, ebp |
||
391 | cmp [ecx+file_common.stamp], eax |
||
392 | jnz .parloopi |
||
631 | diamond | 393 | @@: |
6673 | IgorA | 394 | mov [edx+file_common.stamp], eax |
395 | push esi |
||
396 | mov ecx, [edx+file_common.name] |
||
397 | add ecx, [edx+file_common.namelen] |
||
398 | xor eax, eax |
||
399 | xchg al, [ecx] |
||
400 | push eax ecx |
||
401 | mov eax, edx |
||
402 | mov edi, tmp_bdfe |
||
403 | push edi |
||
404 | sub esi, [ebx+file_common.fullname] |
||
405 | add esi, [edx+file_common.fullname] |
||
406 | push esi |
||
407 | mov ecx, [ebp] |
||
408 | call dword [getattrTable+(ecx-1)*4] |
||
409 | mov eax, [esp+24+20] |
||
410 | call eax |
||
411 | pop ecx edx |
||
412 | mov [ecx], dl |
||
413 | pop esi |
||
414 | test al, al |
||
415 | jz .forced_exit |
||
416 | jmp .parloope |
||
631 | diamond | 417 | .pardone: |
6673 | IgorA | 418 | cmp [ebx+file_common.bIsDirectory], 0 |
419 | jz .addfile |
||
420 | mov eax, [cur_stamp] |
||
421 | cmp [ebx+file_common.stamp], eax |
||
422 | jz .cont |
||
423 | mov [ebx+file_common.stamp], eax |
||
424 | push esi |
||
425 | mov ecx, [ebx+file_common.name] |
||
426 | add ecx, [ebx+file_common.namelen] |
||
427 | xor eax, eax |
||
428 | xchg al, [ecx] |
||
429 | push eax ecx |
||
430 | mov eax, ebx |
||
431 | mov edi, tmp_bdfe |
||
432 | push edi |
||
433 | push esi |
||
434 | mov ecx, [ebp] |
||
435 | call dword [getattrTable+(ecx-1)*4] |
||
436 | mov eax, [esp+24+20] |
||
437 | call eax |
||
438 | pop ecx edx |
||
439 | mov [ecx], dl |
||
440 | pop esi |
||
441 | test al, al |
||
442 | jz .forced_exit |
||
443 | jmp .cont |
||
631 | diamond | 444 | .addfile: |
6673 | IgorA | 445 | push ebx esi ebp |
446 | push 11h |
||
447 | pop edi |
||
448 | mov eax, ebx |
||
449 | mov ecx, [ebp] |
||
450 | call dword [openTable+(ecx-1)*4] |
||
451 | pop ebp esi ebx |
||
452 | test eax, eax |
||
453 | jz .cont |
||
454 | push eax |
||
455 | push eax |
||
456 | mov edi, tmp_bdfe |
||
457 | push edi |
||
458 | push esi |
||
459 | mov eax, ebx |
||
460 | mov ecx, [ebp] |
||
461 | call dword [getattrTable+(ecx-1)*4] |
||
462 | mov eax, [esp+20+16] |
||
463 | call eax |
||
464 | pop ecx |
||
465 | push eax ebp |
||
466 | push ebx |
||
467 | push ecx |
||
468 | call myclose |
||
469 | pop ebx |
||
470 | pop ebp eax |
||
471 | test al, al |
||
472 | jz .forced_exit |
||
631 | diamond | 473 | .cont: |
6673 | IgorA | 474 | mov eax, [ebp] |
475 | add ebx, [basesizes+(eax-1)*8+4] |
||
476 | pop ecx |
||
477 | dec ecx |
||
478 | jnz .loop |
||
631 | diamond | 479 | .ret: |
6673 | IgorA | 480 | ret 20 |
631 | diamond | 481 | .forced_exit: |
6673 | IgorA | 482 | pop ecx |
483 | jmp .ret |
||
589 | diamond | 484 | |
485 | ; void __stdcall GetOpenPluginInfo(HANDLE hPlugin, OpenPluginInfo* info); |
||
486 | GetOpenPluginInfo: |
||
6673 | IgorA | 487 | mov eax, [esp+8] ; get info ptr |
488 | mov byte [eax], 3 ; flags: add non-existing '..' entry automatically |
||
489 | ; use GetFiles for copying |
||
490 | ret 8 |
||
589 | diamond | 491 | |
492 | ; int __stdcall getattr(HANDLE hPlugin, const char* filename, void* info); |
||
493 | mygetattr: |
||
6673 | IgorA | 494 | call lookup_file_name |
495 | test eax, eax |
||
496 | jz @f |
||
497 | mov edx, [ebp] |
||
498 | dec edx |
||
499 | mov edi, [esp+12] ; info ptr |
||
500 | call dword [getattrTable+edx*4] |
||
501 | xor eax, eax |
||
502 | ret 12 |
||
589 | diamond | 503 | @@: |
6673 | IgorA | 504 | mov al, 5 ; ERROR_FILE_NOT_FOUND |
505 | ret 12 |
||
589 | diamond | 506 | |
507 | ; HANDLE __stdcall open(HANDLE hPlugin, const char* filename, int mode); |
||
508 | myopen: |
||
6673 | IgorA | 509 | call lookup_file_name |
510 | test eax, eax |
||
511 | jz @f |
||
512 | mov edx, [ebp] |
||
513 | dec edx |
||
514 | mov edi, [esp+12] ; mode |
||
515 | call dword [openTable+edx*4] |
||
589 | diamond | 516 | @@: |
6673 | IgorA | 517 | ret 12 |
589 | diamond | 518 | |
519 | ; unsigned __stdcall read(HANDLE hFile, void* buf, unsigned size); |
||
520 | myread: |
||
6673 | IgorA | 521 | mov ebx, [esp+4] |
522 | mov eax, [ebx] |
||
523 | jmp dword [readTable+eax*4] |
||
589 | diamond | 524 | |
525 | ; void __stdcall setpos(HANDLE hFile, __int64 pos); |
||
526 | mysetpos: |
||
6673 | IgorA | 527 | mov ebx, [esp+4] |
528 | mov eax, [ebx] |
||
529 | jmp dword [setposTable+eax*4] |
||
589 | diamond | 530 | |
531 | ; void __stdcall close(HANDLE hFile); |
||
532 | myclose: |
||
6673 | IgorA | 533 | mov ebx, [esp+4] |
534 | mov eax, [ebx] |
||
535 | jmp dword [closeTable+eax*4] |
||
589 | diamond | 536 | |
537 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
||
538 | ;;;;;;;;;;;;;; Auxiliary procedures ;;;;;;;;;;;;; |
||
539 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
||
540 | |||
541 | ; return.err and return.clear are labels to jmp if something is invalid |
||
542 | ; the caller must previously define [_esp], [_ebp] and [error_proc], [clear_proc] |
||
543 | return.err: |
||
6673 | IgorA | 544 | mov esp, [_esp] |
545 | mov ebp, [_ebp] |
||
546 | jmp [error_proc] |
||
589 | diamond | 547 | return.clear: |
6673 | IgorA | 548 | mov esp, [_esp] |
549 | mov ebp, [_ebp] |
||
550 | jmp [clear_proc] |
||
589 | diamond | 551 | |
552 | ; data for following routine |
||
553 | iglobal |
||
554 | align 4 |
||
6673 | IgorA | 555 | _24 dd 24 |
556 | _60 dd 60 |
||
557 | _10000000 dd 10000000 |
||
558 | days400year dd 365*400+100-4+1 |
||
559 | days100year dd 365*100+25-1 |
||
560 | days4year dd 365*4+1 |
||
561 | days1year dd 365 |
||
562 | months dd 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 |
||
563 | months2 dd 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 |
||
564 | _400 dd 400 |
||
565 | _100 dd 100 |
||
589 | diamond | 566 | endg |
567 | |||
568 | ; Convert QWORD FILETIME to BDFE format. |
||
569 | ntfs_datetime_to_bdfe: |
||
570 | ; edx:eax = number of 100-nanosecond intervals since January 1, 1601, in UTC |
||
6673 | IgorA | 571 | push eax |
572 | mov eax, edx |
||
573 | xor edx, edx |
||
574 | div [_10000000] |
||
575 | xchg eax, [esp] |
||
576 | div [_10000000] |
||
577 | pop edx |
||
589 | diamond | 578 | ; edx:eax = number of seconds since January 1, 1601 |
6673 | IgorA | 579 | push eax |
580 | mov eax, edx |
||
581 | xor edx, edx |
||
582 | div [_60] |
||
583 | xchg eax, [esp] |
||
584 | div [_60] |
||
585 | mov [edi], dl |
||
586 | pop edx |
||
589 | diamond | 587 | ; edx:eax = number of minutes |
6673 | IgorA | 588 | div [_60] |
589 | mov [edi+1], dl |
||
589 | diamond | 590 | ; eax = number of hours (note that 2^64/(10^7*60*60) < 2^32) |
6673 | IgorA | 591 | xor edx, edx |
592 | div [_24] |
||
593 | mov [edi+2], dl |
||
594 | mov [edi+3], byte 0 |
||
589 | diamond | 595 | ; eax = number of days since January 1, 1601 |
6673 | IgorA | 596 | xor edx, edx |
597 | div [days400year] |
||
598 | imul eax, 400 |
||
599 | add eax, 1601 |
||
600 | mov [edi+6], ax |
||
601 | mov eax, edx |
||
602 | xor edx, edx |
||
603 | div [days100year] |
||
604 | cmp al, 4 |
||
605 | jnz @f |
||
606 | dec eax |
||
607 | add edx, [days100year] |
||
589 | diamond | 608 | @@: |
6673 | IgorA | 609 | imul eax, 100 |
610 | add [edi+6], ax |
||
611 | mov eax, edx |
||
612 | xor edx, edx |
||
613 | div [days4year] |
||
614 | shl eax, 2 |
||
615 | add [edi+6], ax |
||
616 | mov eax, edx |
||
617 | xor edx, edx |
||
618 | div [days1year] |
||
619 | cmp al, 4 |
||
620 | jnz @f |
||
621 | dec eax |
||
622 | add edx, [days1year] |
||
589 | diamond | 623 | @@: |
6673 | IgorA | 624 | add [edi+6], ax |
625 | push esi edx |
||
626 | mov esi, months |
||
627 | movzx eax, word [edi+6] |
||
628 | test al, 3 |
||
629 | jnz .noleap |
||
630 | xor edx, edx |
||
631 | push eax |
||
632 | div [_400] |
||
633 | pop eax |
||
634 | test edx, edx |
||
635 | jz .leap |
||
636 | xor edx, edx |
||
637 | div [_100] |
||
638 | test edx, edx |
||
639 | jz .noleap |
||
589 | diamond | 640 | .leap: |
6673 | IgorA | 641 | mov esi, months2 |
589 | diamond | 642 | .noleap: |
6673 | IgorA | 643 | pop edx |
644 | xor eax, eax |
||
645 | inc eax |
||
589 | diamond | 646 | @@: |
6673 | IgorA | 647 | sub edx, [esi] |
648 | jb @f |
||
649 | add esi, 4 |
||
650 | inc eax |
||
651 | jmp @b |
||
589 | diamond | 652 | @@: |
6673 | IgorA | 653 | add edx, [esi] |
654 | pop esi |
||
655 | inc edx |
||
656 | mov [edi+4], dl |
||
657 | mov [edi+5], al |
||
658 | add edi, 8 |
||
659 | ret |
||
589 | diamond | 660 | |
661 | ; By given array of files information, initialize links between them |
||
662 | ; ("[folder] contains [item]" relations). |
||
663 | ; Information structure must be compatible with 'file_common'. |
||
664 | ; Size of information structure is in [esp+4]. |
||
665 | init_file_links: |
||
666 | ; in: edx->file infos, ebx = number of files, [esp+4] = size, |
||
667 | ; edi->{dd root.subfolders, dd root.subfolders.end, |
||
668 | ; dd root.subfiles, dd root.subfiles.end, dd root.NumItems} |
||
6673 | IgorA | 669 | xor eax, eax |
670 | mov [.free], eax |
||
671 | push edi |
||
672 | stosd |
||
673 | stosd |
||
674 | stosd |
||
675 | stosd |
||
676 | stosd |
||
677 | pop edi |
||
589 | diamond | 678 | ; Loop through all files |
679 | .mainloop: |
||
6673 | IgorA | 680 | dec ebx |
681 | js .mainloopdone |
||
589 | diamond | 682 | ; Parse file name |
683 | ; esi->current character in name |
||
684 | ; dword [esp] = start of current component in file name |
||
685 | ; ecx->{dd curdir.subfolders, dd curdir.subfolders.end, |
||
686 | ; dd curdir.subfiles, dd curdir.subfiles.end} |
||
6673 | IgorA | 687 | mov esi, [edx+file_common.fullname] |
688 | mov ecx, edi |
||
589 | diamond | 689 | .parseloop: |
6673 | IgorA | 690 | push esi |
589 | diamond | 691 | .parsename: |
6673 | IgorA | 692 | lodsb |
693 | test al, al |
||
694 | jz @f |
||
695 | cmp al, '/' |
||
696 | jnz .parsename |
||
589 | diamond | 697 | @@: |
698 | ; we have found next component of current name; look for it in current directory |
||
6673 | IgorA | 699 | sub esi, [esp] |
700 | dec esi ; esi = strlen(component) |
||
701 | cmp esi, 259 |
||
702 | jbe @f |
||
703 | push ContinueBtn |
||
704 | push 1 |
||
705 | push aNameTooLong_ptr |
||
706 | push 1 |
||
707 | call [SayErr] |
||
708 | jmp return.clear |
||
589 | diamond | 709 | @@: |
6673 | IgorA | 710 | push ecx |
711 | mov eax, [ecx] ; eax->subfolders list |
||
712 | mov ecx, esi |
||
589 | diamond | 713 | .scansubfolders: |
6673 | IgorA | 714 | test eax, eax |
715 | jz .nofolder |
||
716 | add eax, [hOut] |
||
717 | cmp [eax+file_common.namelen], ecx |
||
718 | jnz .scancont |
||
719 | mov esi, [esp+4] |
||
720 | push ecx edi |
||
721 | mov edi, [eax+file_common.name] |
||
722 | repz cmpsb |
||
723 | pop edi ecx |
||
724 | jz .subfound |
||
589 | diamond | 725 | .scancont: |
6673 | IgorA | 726 | mov eax, [eax+file_common.next] |
727 | jmp .scansubfolders |
||
589 | diamond | 728 | .subfound: |
729 | ; found subfolder, set it as current and continue parsing name |
||
6673 | IgorA | 730 | add [esp+4], ecx |
731 | pop ecx |
||
732 | lea ecx, [eax+file_common.subfolders] |
||
733 | pop esi |
||
734 | lodsb |
||
735 | test al, al |
||
736 | jnz .parseloop |
||
589 | diamond | 737 | ; that was the last component of the name, and we have found subfolder |
738 | ; so found subfolder is a virtual subfolder and must be replaced with current |
||
739 | ; name |
||
6673 | IgorA | 740 | mov eax, [ecx-file_common.subfolders+file_common.namelen] |
741 | mov [edx+file_common.namelen], eax |
||
742 | sub esi, eax |
||
743 | dec esi |
||
744 | mov [edx+file_common.name], esi |
||
745 | sub edx, [hOut] ; convert pointer to relative |
||
589 | diamond | 746 | ; replace item in L2-list |
6673 | IgorA | 747 | mov eax, [ecx-file_common.subfolders+file_common.prev] |
748 | test eax, eax |
||
749 | jnz .1 |
||
750 | mov eax, [ecx-file_common.subfolders+file_common.parent] |
||
751 | sub eax, file_common.next - file_common.subfolders |
||
752 | jnc .1 |
||
753 | lea eax, [edi-file_common.next] |
||
754 | jmp .2 |
||
589 | diamond | 755 | .1: |
6673 | IgorA | 756 | add eax, [hOut] |
589 | diamond | 757 | .2: |
6673 | IgorA | 758 | mov [eax+file_common.next], edx |
759 | mov eax, [ecx-file_common.subfolders+file_common.next] |
||
760 | test eax, eax |
||
761 | jnz .3 |
||
762 | mov eax, [ecx-file_common.subfolders+file_common.parent] |
||
763 | sub eax, file_common.prev - file_common.subfolders.end |
||
764 | jnc .3 |
||
765 | lea eax, [edi-file_common.prev+4] |
||
766 | jmp .4 |
||
589 | diamond | 767 | .3: |
6673 | IgorA | 768 | add eax, [hOut] |
589 | diamond | 769 | .4: |
6673 | IgorA | 770 | mov [eax+file_common.prev], edx |
589 | diamond | 771 | ; correct parent links in childrens |
6673 | IgorA | 772 | mov eax, [ecx] |
589 | diamond | 773 | @@: |
6673 | IgorA | 774 | test eax, eax |
775 | jz @f |
||
776 | add eax, [hOut] |
||
777 | mov [eax+file_common.parent], edx |
||
778 | mov eax, [eax+file_common.next] |
||
779 | jmp @b |
||
589 | diamond | 780 | @@: |
6673 | IgorA | 781 | mov eax, [ecx+8] |
589 | diamond | 782 | @@: |
6673 | IgorA | 783 | test eax, eax |
784 | jz @f |
||
785 | add eax, [hOut] |
||
786 | mov [eax+file_common.parent], edx |
||
787 | mov eax, [eax+file_common.next] |
||
788 | jmp @b |
||
589 | diamond | 789 | @@: |
6673 | IgorA | 790 | add edx, [hOut] |
589 | diamond | 791 | ; set children links |
6673 | IgorA | 792 | mov eax, [ecx] |
793 | mov [edx+file_common.subfolders], eax |
||
794 | mov eax, [ecx+4] |
||
795 | mov [edx+file_common.subfolders.end], eax |
||
796 | mov eax, [ecx+8] |
||
797 | mov [edx+file_common.subfiles], eax |
||
798 | mov eax, [ecx+12] |
||
799 | mov [edx+file_common.subfiles.end], eax |
||
800 | mov eax, [ecx+16] |
||
801 | mov [edx+file_common.NumSubItems], eax |
||
589 | diamond | 802 | ; set prev/next links |
6673 | IgorA | 803 | mov eax, [ecx-file_common.subfolders+file_common.next] |
804 | mov [edx+file_common.next], eax |
||
805 | mov eax, [ecx-file_common.subfolders+file_common.prev] |
||
806 | mov [edx+file_common.prev], eax |
||
589 | diamond | 807 | ; add old item to list of free items |
808 | uglobal |
||
809 | align 4 |
||
6673 | IgorA | 810 | init_file_links.free dd ? |
589 | diamond | 811 | endg |
6673 | IgorA | 812 | sub ecx, file_common.subfolders |
813 | mov eax, [.free] |
||
814 | mov [ecx], eax |
||
815 | sub ecx, [hOut] |
||
816 | mov [.free], ecx |
||
817 | jmp .mainloopcont |
||
589 | diamond | 818 | .nofolder: |
6673 | IgorA | 819 | mov eax, edx |
820 | mov esi, [esp+4] |
||
821 | cmp byte [esi+ecx], 0 |
||
822 | jz .newitem |
||
589 | diamond | 823 | ; the current item is as 'dir1/item1' and 'dir1' has not been found |
824 | ; allocate virtual subfolder 'dir1' |
||
6673 | IgorA | 825 | mov eax, [init_file_links.free] |
826 | test eax, eax |
||
827 | jz .realloc |
||
828 | add eax, [hOut] |
||
829 | push dword [eax] |
||
830 | pop [init_file_links.free] |
||
831 | jmp .allocated |
||
589 | diamond | 832 | .realloc: |
833 | ; there is no free space, so reallocate [hOut] block |
||
6673 | IgorA | 834 | mov eax, [hOut] |
835 | sub [esp], eax ; make pointers relative |
||
836 | sub edx, eax |
||
837 | sub edi, eax |
||
838 | push ecx |
||
839 | mov ecx, [hOut.allocated] |
||
840 | add ecx, [esp+12+4] |
||
841 | mov [hOut.allocated], ecx |
||
842 | push ecx |
||
843 | and ecx, 0xFFF |
||
844 | cmp ecx, [esp+16+4] |
||
845 | pop ecx |
||
846 | ja @f |
||
847 | push edx |
||
848 | mov edx, eax |
||
849 | call [pgrealloc] |
||
850 | pop edx |
||
851 | test eax, eax |
||
852 | jnz @f |
||
853 | mov ecx, [hOut] |
||
854 | call [pgfree] |
||
855 | mov esp, [_esp] |
||
856 | or eax, -1 |
||
857 | ret |
||
589 | diamond | 858 | @@: |
6673 | IgorA | 859 | pop ecx |
860 | mov [hOut], eax |
||
861 | add [esp], eax ; make pointers absolute |
||
862 | add edx, eax |
||
863 | add edi, eax |
||
864 | add eax, [hOut.allocated] |
||
865 | sub eax, [esp+8+4] |
||
589 | diamond | 866 | .allocated: |
867 | ; eax -> new item |
||
6673 | IgorA | 868 | mov [eax+file_common.bIsDirectory], 1 |
869 | mov [eax+file_common.bPseudoFolder], 1 |
||
589 | diamond | 870 | .newitem: |
6673 | IgorA | 871 | mov [eax+file_common.namelen], ecx |
644 | diamond | 872 | ; !!! in this case .fullname is not null-terminated !!! |
6673 | IgorA | 873 | mov ecx, [edx+file_common.fullname] |
874 | mov [eax+file_common.fullname], ecx |
||
875 | push edi eax |
||
876 | lea edi, [eax+file_common.parent] |
||
877 | xor eax, eax |
||
878 | push 7 |
||
879 | pop ecx |
||
880 | rep stosd |
||
881 | pop eax edi |
||
882 | pop ecx |
||
883 | pop esi |
||
589 | diamond | 884 | ; ecx = parent item, eax = current item |
6673 | IgorA | 885 | mov [eax+file_common.name], esi |
886 | inc dword [ecx+16] ; new item in parent folder |
||
887 | push ecx |
||
589 | diamond | 888 | ; add new item to end of L2-list |
6673 | IgorA | 889 | cmp [eax+file_common.bIsDirectory], 0 |
890 | jnz @f |
||
891 | add ecx, 8 |
||
589 | diamond | 892 | @@: |
6673 | IgorA | 893 | push eax |
894 | sub eax, [hOut] |
||
895 | cmp dword [ecx], 0 |
||
896 | jnz @f |
||
897 | mov [ecx], eax |
||
589 | diamond | 898 | @@: |
6673 | IgorA | 899 | xchg eax, [ecx+4] |
900 | xchg eax, ecx |
||
901 | pop eax |
||
902 | mov [eax+file_common.prev], ecx |
||
903 | jecxz @f |
||
904 | add ecx, [hOut] |
||
905 | sub eax, [hOut] |
||
906 | mov [ecx+file_common.next], eax |
||
907 | add eax, [hOut] |
||
589 | diamond | 908 | @@: |
6673 | IgorA | 909 | pop ecx |
589 | diamond | 910 | ; set parent link |
6673 | IgorA | 911 | cmp ecx, edi |
912 | jz @f |
||
913 | sub ecx, file_common.subfolders |
||
914 | sub ecx, [hOut] |
||
915 | mov [eax+file_common.parent], ecx |
||
589 | diamond | 916 | @@: |
917 | ; set current directory to current item |
||
6673 | IgorA | 918 | lea ecx, [eax+file_common.subfolders] |
589 | diamond | 919 | ; if that was not last component, continue parse name |
6673 | IgorA | 920 | add esi, [eax+file_common.namelen] |
921 | lodsb |
||
922 | test al, al |
||
923 | jnz .parseloop |
||
589 | diamond | 924 | .mainloopcont: |
925 | ; continue main loop |
||
6673 | IgorA | 926 | add edx, [esp+4] |
927 | jmp .mainloop |
||
589 | diamond | 928 | .mainloopdone: |
929 | ; Loop done. |
||
6673 | IgorA | 930 | ret 4 |
589 | diamond | 931 | |
932 | ; This subroutine is called by getattr and open. |
||
933 | ; This subroutine looks for file name and returns NULL or pointer to file info record. |
||
934 | lookup_file_name: |
||
6673 | IgorA | 935 | mov ebp, [esp+8] ; hPlugin |
936 | mov esi, [esp+12] ; filename |
||
937 | lea edi, [ebp+handle_common.root.subfolders] |
||
938 | xor eax, eax |
||
589 | diamond | 939 | ; KFar operates with absolute names, skip first '/' |
6673 | IgorA | 940 | cmp byte [esi], '/' |
941 | jnz .notfound |
||
942 | inc esi |
||
589 | diamond | 943 | .mainloop: |
944 | ; get next component of name |
||
6673 | IgorA | 945 | push -1 |
946 | pop ecx |
||
589 | diamond | 947 | @@: |
6673 | IgorA | 948 | inc ecx |
949 | cmp byte [esi+ecx], '/' |
||
950 | jz @f |
||
951 | cmp byte [esi+ecx], 0 |
||
952 | jnz @b |
||
589 | diamond | 953 | @@: |
954 | ; esi->component, ecx=length |
||
955 | ; scan for required item in subfolders list |
||
6673 | IgorA | 956 | push -1 |
957 | mov eax, [edi] ; .subfolders |
||
589 | diamond | 958 | .scan1: |
6673 | IgorA | 959 | test eax, eax |
960 | jz .notfound1 |
||
961 | add eax, ebp |
||
962 | cmp [eax+file_common.namelen], ecx |
||
963 | jnz .cont1 |
||
964 | push ecx esi edi |
||
965 | mov edi, [eax+file_common.name] |
||
966 | repz cmpsb |
||
967 | pop edi esi ecx |
||
968 | jz .found1 |
||
589 | diamond | 969 | .cont1: |
6673 | IgorA | 970 | mov eax, [eax+file_common.next] |
971 | jmp .scan1 |
||
589 | diamond | 972 | .notfound1: |
6673 | IgorA | 973 | pop edx |
589 | diamond | 974 | ; if this is last component in file name, scan in subfiles list |
6673 | IgorA | 975 | cmp byte [esi+ecx], al |
976 | jnz .notfound |
||
977 | inc edx |
||
978 | jnz .notfound |
||
979 | mov eax, [edi+8] ; .subfiles |
||
980 | push edx |
||
981 | jmp .scan1 |
||
589 | diamond | 982 | .found1: |
6673 | IgorA | 983 | pop edi |
589 | diamond | 984 | ; item is found, go to next component |
6673 | IgorA | 985 | lea edi, [eax+file_common.subfolders] |
986 | lea esi, [esi+ecx+1] |
||
987 | cmp byte [esi-1], 0 |
||
988 | jnz .mainloop |
||
589 | diamond | 989 | ; this was the last component |
990 | .notfound: |
||
6673 | IgorA | 991 | ret |
589 | diamond | 992 | |
993 | ; Memory streams handling. |
||
994 | ; Archive handlers create memory stream for small files: |
||
995 | ; size of which is not greater than (free RAM size)/4 and |
||
996 | ; not greater than following constant... |
||
997 | ;LIMIT_FOR_MEM_STREAM = 2*1024*1024 |
||
998 | ; ...if it is defined. Now the definition is commented: |
||
999 | ; if user has many physical memory, why not to use it? |
||
1000 | |||
1001 | virtual at 0 |
||
1002 | mem_stream: |
||
6673 | IgorA | 1003 | .type dd ? ; type_mem_stream |
1004 | .size dd ? |
||
1005 | .pos dd ? |
||
589 | diamond | 1006 | .buf: |
1007 | end virtual |
||
1008 | |||
1009 | ; unsigned __stdcall read(ebx = HANDLE hFile, void* buf, unsigned size); |
||
1010 | read_mem_stream: |
||
6673 | IgorA | 1011 | mov eax, [esp+12] |
1012 | mov ecx, [ebx+mem_stream.size] |
||
1013 | sub ecx, [ebx+mem_stream.pos] |
||
1014 | jnc @f |
||
1015 | xor ecx, ecx |
||
589 | diamond | 1016 | @@: |
6673 | IgorA | 1017 | cmp eax, ecx |
1018 | jb @f |
||
1019 | mov eax, ecx |
||
589 | diamond | 1020 | @@: |
6673 | IgorA | 1021 | mov ecx, eax |
1022 | lea esi, [ebx+mem_stream.buf] |
||
1023 | add esi, [ebx+mem_stream.pos] |
||
1024 | add [ebx+mem_stream.pos], eax |
||
1025 | mov edi, [esp+8] |
||
1026 | mov edx, ecx |
||
1027 | shr ecx, 2 |
||
1028 | rep movsd |
||
1029 | mov ecx, edx |
||
1030 | and ecx, 3 |
||
1031 | rep movsb |
||
1032 | ret 12 |
||
589 | diamond | 1033 | |
1034 | ; void __stdcall setpos(ebx = HANDLE hFile, __int64 pos); |
||
1035 | setpos_mem_stream: |
||
6673 | IgorA | 1036 | mov eax, [esp+8] |
1037 | mov [ebx+mem_stream.pos], eax |
||
1038 | ret 12 |
||
589 | diamond | 1039 | |
1040 | ; void __stdcall close(ebx = HANDLE hFile); |
||
1041 | close_mem_stream: |
||
6673 | IgorA | 1042 | mov ecx, ebx |
1043 | call [pgfree] |
||
1044 | ret 4 |
||
589 | diamond | 1045 | |
1046 | ; Allocate handle for file |
||
1047 | ; esi -> handle table, ecx = size of handle |
||
1048 | alloc_handle: |
||
1049 | ; Handle table is L2-list of allocated pages. |
||
1050 | ; Scan for free entry |
||
6673 | IgorA | 1051 | mov edx, esi |
589 | diamond | 1052 | @@: |
6673 | IgorA | 1053 | mov edx, [edx] |
1054 | cmp edx, esi |
||
1055 | jz .alloc_new |
||
1056 | mov eax, [edx+8] ; head of L1-list of free entries |
||
1057 | test eax, eax ; has free entry? |
||
1058 | jz @b |
||
589 | diamond | 1059 | ; we have found allocated page with free entry; allocate entry and return |
6673 | IgorA | 1060 | inc dword [edx+12] ; number of busy entries |
1061 | push dword [eax] |
||
1062 | pop dword [edx+8] |
||
589 | diamond | 1063 | .ret: |
6673 | IgorA | 1064 | ret |
589 | diamond | 1065 | .alloc_new: |
1066 | ; no free pages; get new page and initialize |
||
6673 | IgorA | 1067 | push ecx |
1068 | mov ecx, 0x1000 |
||
1069 | call [pgalloc] |
||
1070 | pop ecx |
||
1071 | test eax, eax |
||
1072 | jz .ret |
||
589 | diamond | 1073 | ; insert new page to start of L2-list |
6673 | IgorA | 1074 | mov edx, [esi] |
1075 | mov [eax], edx |
||
1076 | mov [esi], eax |
||
1077 | mov [eax+4], esi |
||
1078 | mov [edx+4], eax |
||
1079 | mov dword [eax+12], 1 ; 1 allocated entry |
||
589 | diamond | 1080 | ; initialize list of free entries |
6673 | IgorA | 1081 | lea edx, [eax+16] |
1082 | push edx ; save return value |
||
1083 | add edx, ecx |
||
1084 | mov [eax+8], edx |
||
1085 | add eax, 0x1000 |
||
589 | diamond | 1086 | @@: |
6673 | IgorA | 1087 | mov esi, edx |
1088 | add edx, ecx |
||
1089 | mov [esi], edx |
||
1090 | cmp edx, eax |
||
1091 | jb @b |
||
1092 | and dword [esi], 0 |
||
1093 | pop eax |
||
1094 | ret |
||
589 | diamond | 1095 | |
1096 | ; Free handle allocated in previous procedure |
||
1097 | ; esi = handle |
||
1098 | free_handle: |
||
6673 | IgorA | 1099 | mov ecx, esi |
1100 | and ecx, not 0xFFF ; get page |
||
589 | diamond | 1101 | ; add entry to head of L1-list of free entries |
6673 | IgorA | 1102 | mov eax, [ecx+8] |
1103 | mov [esi], eax |
||
1104 | mov [ecx+8], esi |
||
1105 | dec dword [ecx+12] ; decrement number of allocated entries |
||
1106 | jnz .ret |
||
589 | diamond | 1107 | ; delete page from common L2-list |
6673 | IgorA | 1108 | mov eax, [ecx] |
1109 | mov edx, [ecx+4] |
||
1110 | mov [eax+4], edx |
||
1111 | mov [edx], eax |
||
589 | diamond | 1112 | ; free page |
6673 | IgorA | 1113 | call [pgfree] |
589 | diamond | 1114 | .ret: |
6673 | IgorA | 1115 | ret |
589 | diamond | 1116 | |
1117 | ; Ask user to enter password. |
||
1118 | ; Out: ZF set <=> user pressed Esc |
||
1119 | ; 'password_ansi', 'password_unicode', 'password_size' filled |
||
1120 | query_password: |
||
6673 | IgorA | 1121 | cmp [bPasswordDefined], 0 |
1122 | jnz .ret |
||
1123 | mov edi, password_data |
||
1124 | mov eax, password_maxlen |
||
1125 | stosd ; maximum length |
||
1126 | xor eax, eax |
||
1127 | stosd ; start of visible part |
||
1128 | stosd ; position of cursor |
||
1129 | stosb ; initial state: empty string |
||
1130 | mov eax, [cur_console_size] |
||
1131 | mov eax, [eax] ; get current console width |
||
1132 | sub eax, 12 |
||
1133 | mov edi, password_dlg |
||
1134 | mov [edi+password_dlg.width-password_dlg], eax |
||
1135 | dec eax |
||
1136 | dec eax |
||
1137 | mov [edi+password_dlg.width1-password_dlg], eax |
||
1138 | mov [edi+password_dlg.width2-password_dlg], eax |
||
1139 | push edi |
||
1140 | call [DialogBox] |
||
1141 | inc eax |
||
1142 | jz .ret |
||
589 | diamond | 1143 | ; convert ANSI-cp866 to UNICODE string; also calculate 'password_size' |
6673 | IgorA | 1144 | mov esi, password_ansi |
1145 | mov edi, password_unicode |
||
1146 | or [password_size], -1 |
||
589 | diamond | 1147 | .cvt: |
6673 | IgorA | 1148 | inc [password_size] |
1149 | lodsb |
||
1150 | mov ah, 0 |
||
589 | diamond | 1151 | ; 0x00-0x7F - trivial map |
6673 | IgorA | 1152 | cmp al, 0x80 |
1153 | jb .symb |
||
589 | diamond | 1154 | ; 0x80-0xAF -> 0x410-0x43F |
6673 | IgorA | 1155 | cmp al, 0xB0 |
1156 | jae @f |
||
1157 | add ax, 0x410-0x80 |
||
1158 | jmp .symb |
||
589 | diamond | 1159 | @@: |
1160 | ; 0xE0-0xEF -> 0x440-0x44F |
||
6673 | IgorA | 1161 | cmp al, 0xE0 |
1162 | jb .unk |
||
1163 | cmp al, 0xF0 |
||
1164 | jae @f |
||
1165 | add ax, 0x440-0xE0 |
||
1166 | jmp .symb |
||
589 | diamond | 1167 | @@: |
1168 | ; 0xF0 -> 0x401 |
||
1169 | ; 0xF1 -> 0x451 |
||
6673 | IgorA | 1170 | cmp al, 'Ё' |
1171 | jz .yo1 |
||
1172 | cmp al, 'ё' |
||
1173 | jz .yo2 |
||
589 | diamond | 1174 | .unk: |
6673 | IgorA | 1175 | mov al, '_' |
1176 | jmp .symb |
||
589 | diamond | 1177 | .yo1: |
6673 | IgorA | 1178 | mov ax, 0x401 |
1179 | jmp .symb |
||
589 | diamond | 1180 | .yo2: |
6673 | IgorA | 1181 | mov ax, 0x451 |
589 | diamond | 1182 | .symb: |
6673 | IgorA | 1183 | stosw |
1184 | test al, al |
||
1185 | jnz .cvt |
||
1186 | inc [bPasswordDefined] ; clears ZF flag |
||
589 | diamond | 1187 | .ret: |
6673 | IgorA | 1188 | ret |
589 | diamond | 1189 | |
1190 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
||
1022 | diamond | 1191 | ;;;;;;;;;;;;; API for other programs ;;;;;;;;;;;; |
1192 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
||
1193 | ; void* __stdcall deflate_unpack(void* packed_data, unsigned* pLength) |
||
1194 | deflate_unpack: |
||
1195 | push dword [esp+8] |
||
6673 | IgorA | 1196 | push esp |
1197 | push deflate_unpack_cb |
||
1198 | call deflate_unpack2 |
||
1199 | ret 8 |
||
1022 | diamond | 1200 | |
1201 | deflate_unpack_cb: |
||
6673 | IgorA | 1202 | mov edx, [esp+4] |
1203 | push edx |
||
1204 | mov edx, [edx+12] |
||
1205 | mov edx, [edx] |
||
1206 | mov eax, [esp+8+4] |
||
1207 | mov [eax], edx |
||
1208 | pop edx |
||
1209 | xor eax, eax |
||
1210 | xchg eax, [edx+8] |
||
1211 | ret 8 |
||
1022 | diamond | 1212 | |
1213 | ; void* __stdcall deflate_unpack2(void* get_next_chunk, void* parameter, unsigned* pUnpackedLength) |
||
6673 | IgorA | 1214 | ; void* __stdcall get_next_chunk(void* parameter, unsigned* pLength) |
1022 | diamond | 1215 | deflate_unpack2: |
6673 | IgorA | 1216 | pusha |
1217 | mov ecx, 0x11000 |
||
1218 | call mypgalloc |
||
1219 | test eax, eax |
||
1220 | jz .ret |
||
1221 | or dword [eax+streamInfo.fullSize], -1 |
||
1222 | or dword [eax+streamInfo.fullSize+4], -1 |
||
1223 | and dword [eax+streamInfo.bufSize], 0 |
||
1224 | mov dword [eax+streamInfo.fillBuf], .fillBuf |
||
1225 | mov edx, [esp+32+4] |
||
1226 | mov [eax+streamInfo.size], edx |
||
1227 | mov edx, [esp+32+8] |
||
1228 | mov [eax+streamInfo.size+4], edx |
||
1229 | mov [eax+streamInfo.size+8+deflate_decoder.inStream], eax |
||
1230 | add eax, streamInfo.size+8 |
||
1231 | lea edi, [eax+deflate_decoder.size] |
||
1232 | mov [eax+streamInfo.bufPtr], edi |
||
1233 | mov ebp, eax |
||
1234 | call deflate_init_decoder |
||
1235 | xor edx, edx |
||
1236 | mov ecx, 10000h |
||
1022 | diamond | 1237 | .loop: |
6673 | IgorA | 1238 | push @f |
1239 | pushad |
||
1240 | mov [_esp], esp |
||
1241 | mov [_ebp], ebp |
||
1242 | mov [error_proc], .error |
||
1243 | mov ecx, 10000h |
||
1244 | jmp [eax+streamInfo.fillBuf] |
||
1022 | diamond | 1245 | @@: |
6673 | IgorA | 1246 | push SF_SYS_MISC |
1247 | pop eax |
||
1248 | push SSF_MEM_REALLOC |
||
1249 | pop ebx |
||
1250 | int 0x40 |
||
1251 | test eax, eax |
||
1252 | jz .nomem |
||
1253 | mov edx, eax |
||
1254 | mov eax, ebp |
||
1255 | mov esi, edi |
||
1256 | push edi |
||
1257 | lea edi, [edx+ecx-0x10000] |
||
1258 | push ecx |
||
1259 | mov ecx, 0x10000/4 |
||
1260 | rep movsd |
||
1261 | pop ecx |
||
1262 | pop edi |
||
1263 | add ecx, 0x10000 |
||
1264 | jmp .loop |
||
1022 | diamond | 1265 | .error: |
6673 | IgorA | 1266 | pop eax |
1267 | push edi |
||
1268 | popad |
||
1269 | pop eax |
||
1270 | mov eax, ebp |
||
1271 | lea esi, [eax+deflate_decoder.size] |
||
1272 | sub ecx, 0x10000 |
||
1273 | sub edi, esi |
||
1274 | add ecx, edi |
||
1275 | mov eax, [esp+32+12] |
||
1276 | test eax, eax |
||
1277 | jz @f |
||
1278 | mov [eax], ecx |
||
1022 | diamond | 1279 | @@: |
6673 | IgorA | 1280 | test ecx, ecx |
1281 | jnz @f |
||
1282 | inc ecx |
||
1022 | diamond | 1283 | @@: |
6673 | IgorA | 1284 | push SF_SYS_MISC |
1285 | pop eax |
||
1286 | push SSF_MEM_REALLOC |
||
1287 | pop ebx |
||
1288 | int 0x40 |
||
1289 | test eax, eax |
||
1290 | jz .nomem |
||
1291 | sub ecx, edi |
||
1292 | mov edx, edi |
||
1293 | lea edi, [eax+ecx] |
||
1294 | mov ecx, edx |
||
1295 | shr ecx, 2 |
||
1296 | rep movsd |
||
1297 | mov ecx, edx |
||
1298 | and ecx, 3 |
||
1299 | rep movsb |
||
1300 | push eax |
||
1301 | push SF_SYS_MISC |
||
1302 | pop eax |
||
1303 | push SSF_MEM_FREE |
||
1304 | pop ebx |
||
1305 | lea ecx, [ebp-streamInfo.size-8] |
||
1306 | int 40h |
||
1307 | pop eax |
||
1308 | jmp .ret |
||
1022 | diamond | 1309 | .nomem: |
6673 | IgorA | 1310 | push SF_SYS_MISC |
1311 | pop eax |
||
1312 | push SSF_MEM_FREE |
||
1313 | pop ebx |
||
1314 | test edx, edx |
||
1315 | jz @f |
||
1316 | mov ecx, edx |
||
1317 | push eax |
||
1318 | int 0x40 |
||
1319 | pop eax |
||
1022 | diamond | 1320 | @@: |
6673 | IgorA | 1321 | lea ecx, [ebp-streamInfo.size-8] |
1322 | int 0x40 |
||
1323 | xor eax, eax |
||
1022 | diamond | 1324 | .ret: |
6673 | IgorA | 1325 | mov [esp+28], eax |
1326 | popa |
||
1327 | ret 12 |
||
1022 | diamond | 1328 | .fillBuf: |
6673 | IgorA | 1329 | push eax |
1330 | push eax |
||
1331 | push esp |
||
1332 | push dword [eax+streamInfo.size+4] |
||
1333 | call dword [eax+streamInfo.size] |
||
1334 | pop edx |
||
1335 | pop ebp |
||
1336 | mov [ebp+streamInfo.bufPtr], eax |
||
1337 | and [ebp+streamInfo.bufDataLen], 0 |
||
1338 | test eax, eax |
||
1339 | jz @f |
||
1340 | mov [ebp+streamInfo.bufDataLen], edx |
||
1022 | diamond | 1341 | @@: |
6673 | IgorA | 1342 | popad |
1343 | ret |
||
1022 | diamond | 1344 | |
1345 | mypgalloc: |
||
6673 | IgorA | 1346 | push SF_SYS_MISC |
1347 | pop eax |
||
1348 | push SSF_MEM_ALLOC |
||
1349 | pop ebx |
||
1350 | int 0x40 |
||
1351 | ret |
||
1022 | diamond | 1352 | |
1353 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
||
589 | diamond | 1354 | ;;;;;;;;;;;;;;;; Initialized data ;;;;;;;;;;;;;;; |
1355 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
||
1356 | |||
1357 | ; export table |
||
1358 | align 4 |
||
1359 | EXPORTS: |
||
6673 | IgorA | 1360 | dd aVersion, 3 |
1361 | dd aPluginLoad, plugin_load |
||
1362 | dd aOpenFilePlugin,OpenFilePlugin |
||
1363 | dd aClosePlugin, ClosePlugin |
||
1364 | dd aReadFolder, ReadFolder |
||
1365 | dd aSetFolder, SetFolder |
||
1366 | dd aGetFiles, GetFiles |
||
1367 | dd aGetOpenPluginInfo, GetOpenPluginInfo |
||
1368 | dd aGetattr, mygetattr |
||
1369 | dd aOpen, myopen |
||
1370 | dd aRead, myread |
||
1371 | dd aSetpos, mysetpos |
||
1372 | dd aClose, myclose |
||
1373 | dd aDeflateUnpack, deflate_unpack |
||
1374 | dd aDeflateUnpack2,deflate_unpack2 |
||
1375 | dd adeflateInit, deflateInit |
||
1376 | dd adeflateInit2, deflateInit2 |
||
1377 | dd adeflateReset, deflateReset |
||
1378 | dd adeflate, deflate |
||
1379 | dd adeflateEnd, deflateEnd |
||
1380 | dd azError, zError |
||
1381 | dd acalc_crc32, calc_crc32 |
||
1382 | dd 0 |
||
589 | diamond | 1383 | |
1384 | ; exported names |
||
6673 | IgorA | 1385 | aVersion db 'version',0 |
1386 | aPluginLoad db 'plugin_load',0 |
||
1387 | aOpenFilePlugin db 'OpenFilePlugin',0 |
||
1388 | aClosePlugin db 'ClosePlugin',0 |
||
1389 | aReadFolder db 'ReadFolder',0 |
||
1390 | aSetFolder db 'SetFolder',0 |
||
1391 | aGetFiles db 'GetFiles',0 |
||
1392 | aGetOpenPluginInfo db 'GetOpenPluginInfo',0 |
||
1393 | aGetattr db 'getattr',0 |
||
1394 | aOpen db 'open',0 |
||
1395 | aRead db 'read',0 |
||
1396 | aSetpos db 'setpos',0 |
||
1397 | aClose db 'close',0 |
||
1398 | aDeflateUnpack db 'deflate_unpack',0 |
||
1399 | aDeflateUnpack2 db 'deflate_unpack2',0 |
||
1400 | adeflateInit db 'deflateInit',0 |
||
1401 | adeflateInit2 db 'deflateInit2',0 |
||
1402 | adeflateReset db 'deflateReset',0 |
||
1403 | adeflate db 'deflate',0 |
||
1404 | adeflateEnd db 'deflateEnd',0 |
||
1405 | azError db 'zError',0 |
||
1406 | acalc_crc32 db 'calc_crc32',0 |
||
589 | diamond | 1407 | |
1408 | ; common strings |
||
1409 | if lang eq ru |
||
6673 | IgorA | 1410 | aContinue db 'Продолжить',0 |
1411 | aCancel db 'Отмена',0 |
||
1412 | aHeaderError db 'Ошибка в заголовке архива',0 |
||
1413 | aReadError db 'Ошибка чтения',0 |
||
1414 | aNoFreeRam db 'Недостаточно свободной оперативной памяти',0 |
||
1415 | aEncodingProblem db 'Проблема с кодировкой',0 |
||
589 | diamond | 1416 | aEncodingProblem_str db 'Имена некоторых файлов в архиве содержат символы,',0 |
6673 | IgorA | 1417 | .2 db 'не представимые в кодировке cp866.',0 |
1418 | .3 db 'Эти символы будут заменены на подчёркивания.',0 |
||
1419 | aEnterPassword db 'Введите пароль:',0 |
||
589 | diamond | 1420 | aEnterPasswordLen = $ - aEnterPassword - 1 |
6673 | IgorA | 1421 | aEnterPasswordTitle db 'Ввод пароля',0 |
1422 | aArchiveDataError db 'Ошибка в данных архива',0 |
||
589 | diamond | 1423 | aArchiveDataErrorPass db 'Ошибка в данных архива или неверный пароль',0 |
6673 | IgorA | 1424 | aChangePass db 'Ввести пароль',0 |
1425 | aNameTooLong db 'Слишком длинное имя',0 |
||
1426 | aCannotOpenFile db 'Не могу открыть файл',0 |
||
589 | diamond | 1427 | else |
6673 | IgorA | 1428 | aContinue db 'Continue',0 |
1429 | aCancel db 'Cancel',0 |
||
1430 | aHeaderError db 'Invalid archive header',0 |
||
1431 | aReadError db 'Read error',0 |
||
1432 | aNoFreeRam db 'There is not enough of free RAM',0 |
||
1433 | aEncodingProblem db 'Encoding problem',0 |
||
589 | diamond | 1434 | aEncodingProblem_str db 'The names of some files in the archive contain',0 |
6673 | IgorA | 1435 | .2 db 'characters which can not be represented in cp866.',0 |
1436 | .3 db 'Such characters will be replaced to underscores.',0 |
||
1437 | aEnterPassword db 'Enter password:',0 |
||
589 | diamond | 1438 | aEnterPasswordLen = $ - aEnterPassword - 1 |
6673 | IgorA | 1439 | aEnterPasswordTitle db 'Get password',0 |
1440 | aArchiveDataError db 'Error in archive data',0 |
||
589 | diamond | 1441 | aArchiveDataErrorPass db 'Error in archive data or incorrect password',0 |
6673 | IgorA | 1442 | aChangePass db 'Enter password',0 |
1443 | aNameTooLong db 'Name is too long',0 |
||
1444 | aCannotOpenFile db 'Cannot open file',0 |
||
589 | diamond | 1445 | end if |
1446 | |||
631 | diamond | 1447 | ; kfar_arc supports many archive types. |
589 | diamond | 1448 | ; OpenFilePlugin looks for supported archive signature and gives control |
1449 | ; to concrete handler if found. |
||
631 | diamond | 1450 | ; Other functions just determine type of opened archive and jump to corresponding handler. |
6673 | IgorA | 1451 | type_mem_stream = 0 ; memory stream - for file handles (returned from 'open') |
589 | diamond | 1452 | type_7z = 1 |
631 | diamond | 1453 | type_zip = 2 |
589 | diamond | 1454 | |
1455 | ; archive functions (types start from type_7z) |
||
1456 | align 4 |
||
1457 | ClosePluginTable: |
||
6673 | IgorA | 1458 | dd close_7z |
1459 | dd close_zip |
||
589 | diamond | 1460 | getattrTable: |
6673 | IgorA | 1461 | dd getattr_7z |
1462 | dd getattr_zip |
||
589 | diamond | 1463 | openTable: |
6673 | IgorA | 1464 | dd open_file_7z |
1465 | dd open_file_zip |
||
631 | diamond | 1466 | basesizes: |
6673 | IgorA | 1467 | dd handle_7z.basesize, file_in_7z.size |
1468 | dd handle_zip.basesize, file_in_zip.size |
||
589 | diamond | 1469 | |
1470 | ; file functions (types start from type_mem_stream) |
||
1471 | readTable: |
||
6673 | IgorA | 1472 | dd read_mem_stream |
1473 | dd read_7z |
||
1474 | dd read_zip |
||
589 | diamond | 1475 | setposTable: |
6673 | IgorA | 1476 | dd setpos_mem_stream |
1477 | dd setpos_7z |
||
1478 | dd setpos_zip |
||
589 | diamond | 1479 | closeTable: |
6673 | IgorA | 1480 | dd close_mem_stream |
1481 | dd close_file_7z |
||
1482 | dd close_file_zip |
||
589 | diamond | 1483 | |
1484 | ; pointers for SayErr and Message |
||
6673 | IgorA | 1485 | ContinueBtn dd aContinue |
1486 | HeaderError_ptr dd aHeaderError |
||
1487 | aReadError_ptr dd aReadError |
||
1488 | aNoFreeRam_ptr dd aNoFreeRam |
||
589 | diamond | 1489 | aEncodingProblem_str_ptr: |
6673 | IgorA | 1490 | dd aEncodingProblem_str |
1491 | dd aEncodingProblem_str.2 |
||
1492 | dd aEncodingProblem_str.3 |
||
1493 | aNameTooLong_ptr dd aNameTooLong |
||
589 | diamond | 1494 | aArchiveDataError_ptr dd aArchiveDataError |
1495 | aArchiveDataErrorPass_ptr dd aArchiveDataErrorPass |
||
6673 | IgorA | 1496 | CancelPassBtn dd aCancel |
1497 | dd aChangePass |
||
589 | diamond | 1498 | |
1499 | ; "enter password" dialog for KFar |
||
1500 | password_dlg: |
||
6673 | IgorA | 1501 | dd 1 ; use standard dialog colors |
1502 | dd -1 ; center window by x |
||
1503 | dd -1 ; center window by y |
||
1504 | .width dd ? ; width (will be filled according to current console width) |
||
1505 | dd 2 ; height |
||
1506 | dd 4, 2 ; border size |
||
1507 | dd aEnterPasswordTitle ; title |
||
1508 | dd ? ; colors (will be set by KFar) |
||
1509 | dd 0 ; used internally by dialog manager, ignored |
||
1510 | dd 0, 0 ; reserved for DlgProc |
||
1511 | dd 2 ; 2 controls |
||
589 | diamond | 1512 | ; the string "enter password" |
6673 | IgorA | 1513 | dd 1 ; type: static |
1514 | dd 1,0 ; upper-left position |
||
1515 | .width1 dd ?,0 ; bottom-right position |
||
1516 | dd aEnterPassword ; data |
||
1517 | dd 0 ; flags |
||
589 | diamond | 1518 | ; editbox for password |
6673 | IgorA | 1519 | dd 3 ; type: edit |
1520 | dd 1,1 ; upper-left position |
||
1521 | .width2 dd ?,0 ; bottom-right position |
||
1522 | dd password_data ; data |
||
1523 | dd 2Ch ; flags |
||
589 | diamond | 1524 | |
1525 | IncludeIGlobals |
||
1526 | |||
1527 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
||
1528 | ;;;;;;;;;;;;;;; Uninitialized data ;;;;;;;;;;;;;; |
||
1529 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
||
6673 | IgorA | 1530 | purge data ;used in 'macros.inc' |
1531 | purge section ;used in 'macros.inc' |
||
589 | diamond | 1532 | |
1533 | section '.udata' data readable writable align 16 |
||
6673 | IgorA | 1534 | kfar_info dd ? |
1535 | crc_table rd 256 |
||
1536 | _esp dd ? |
||
1537 | _ebp dd ? |
||
1538 | bufsize dd ? |
||
1539 | bufptr dd ? |
||
1540 | bufend dd ? |
||
1541 | buffer rb 1024 |
||
1542 | inStream dd ? |
||
1543 | hOut dd ? |
||
1544 | .allocated dd ? |
||
589 | diamond | 1545 | |
6673 | IgorA | 1546 | error_proc dd ? |
1547 | clear_proc dd ? |
||
589 | diamond | 1548 | |
1549 | ; import from kfar |
||
6673 | IgorA | 1550 | open2 dd ? |
1551 | filesize dd ? |
||
1552 | read dd ? |
||
1553 | seek dd ? |
||
1554 | close dd ? |
||
1555 | pgalloc dd ? |
||
1556 | pgrealloc dd ? |
||
1557 | pgfree dd ? |
||
1558 | getfreemem dd ? |
||
1559 | DialogBox dd ? |
||
1560 | SayErr dd ? |
||
1561 | Message dd ? |
||
1562 | cur_console_size dd ? |
||
589 | diamond | 1563 | |
1564 | ; data for editbox in kfar dialog |
||
1565 | password_maxlen = 512 |
||
1566 | password_data: |
||
6673 | IgorA | 1567 | .maxlen dd ? |
1568 | .pos dd ? |
||
1569 | .start dd ? |
||
1570 | password_ansi rb password_maxlen+1 |
||
1571 | bPasswordDefined db ? |
||
589 | diamond | 1572 | |
1573 | ; converted password |
||
6673 | IgorA | 1574 | password_unicode rw password_maxlen+1 |
1575 | password_size dd ? |
||
589 | diamond | 1576 | |
1577 | IncludeUGlobals |
||
1578 | |||
6673 | IgorA | 1579 | bWasWarning db ?=>> |