Subversion Repositories Kolibri OS

Rev

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