Subversion Repositories Kolibri OS

Rev

Rev 1122 | 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
1148 diamond 5
; version:              0.17
6
; last update:          2009-09-03 (Sep 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
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
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
1148 diamond 874
        push    edi eax
875
        lea     edi, [eax+file_common.parent]
876
        xor     eax, eax
877
        push    7
589 diamond 878
        pop     ecx
1148 diamond 879
        rep     stosd
880
        pop     eax edi
881
        pop     ecx
589 diamond 882
        pop     esi
883
; ecx = parent item, eax = current item
884
        mov     [eax+file_common.name], esi
885
        inc     dword [ecx+16]  ; new item in parent folder
886
        push    ecx
887
; add new item to end of L2-list
888
        cmp     [eax+file_common.bIsDirectory], 0
889
        jnz     @f
890
        add     ecx, 8
891
@@:
892
        push    eax
893
        sub     eax, [hOut]
894
        cmp     dword [ecx], 0
895
        jnz     @f
896
        mov     [ecx], eax
897
@@:
898
        xchg    eax, [ecx+4]
899
        xchg    eax, ecx
900
        pop     eax
901
        mov     [eax+file_common.prev], ecx
902
        jecxz   @f
903
        add     ecx, [hOut]
904
        sub     eax, [hOut]
905
        mov     [ecx+file_common.next], eax
906
        add     eax, [hOut]
907
@@:
908
        pop     ecx
909
; set parent link
910
        cmp     ecx, edi
911
        jz      @f
912
        sub     ecx, file_common.subfolders
913
        sub     ecx, [hOut]
914
        mov     [eax+file_common.parent], ecx
915
@@:
916
; set current directory to current item
917
        lea     ecx, [eax+file_common.subfolders]
918
; if that was not last component, continue parse name
919
        add     esi, [eax+file_common.namelen]
920
        lodsb
921
        test    al, al
922
        jnz     .parseloop
923
.mainloopcont:
924
; continue main loop
925
        add     edx, [esp+4]
926
        jmp     .mainloop
927
.mainloopdone:
928
; Loop done.
929
        ret     4
930
 
931
; This subroutine is called by getattr and open.
932
; This subroutine looks for file name and returns NULL or pointer to file info record.
933
lookup_file_name:
934
        mov     ebp, [esp+8]    ; hPlugin
935
        mov     esi, [esp+12]   ; filename
936
        lea     edi, [ebp+handle_common.root.subfolders]
937
        xor     eax, eax
938
; KFar operates with absolute names, skip first '/'
939
        cmp     byte [esi], '/'
940
        jnz     .notfound
941
        inc     esi
942
.mainloop:
943
; get next component of name
944
        push    -1
945
        pop     ecx
946
@@:
947
        inc     ecx
948
        cmp     byte [esi+ecx], '/'
949
        jz      @f
950
        cmp     byte [esi+ecx], 0
951
        jnz     @b
952
@@:
953
; esi->component, ecx=length
954
; scan for required item in subfolders list
955
        push    -1
956
        mov     eax, [edi]      ; .subfolders
957
.scan1:
958
        test    eax, eax
959
        jz      .notfound1
960
        add     eax, ebp
961
        cmp     [eax+file_common.namelen], ecx
962
        jnz     .cont1
963
        push    ecx esi edi
964
        mov     edi, [eax+file_common.name]
965
        repz    cmpsb
966
        pop     edi esi ecx
967
        jz      .found1
968
.cont1:
969
        mov     eax, [eax+file_common.next]
970
        jmp     .scan1
971
.notfound1:
972
        pop     edx
973
; if this is last component in file name, scan in subfiles list
974
        cmp     byte [esi+ecx], al
975
        jnz     .notfound
976
        inc     edx
977
        jnz     .notfound
978
        mov     eax, [edi+8]    ; .subfiles
979
        push    edx
980
        jmp     .scan1
981
.found1:
982
        pop     edi
983
; item is found, go to next component
984
        lea     edi, [eax+file_common.subfolders]
985
        lea     esi, [esi+ecx+1]
986
        cmp     byte [esi-1], 0
987
        jnz     .mainloop
988
; this was the last component
989
.notfound:
990
        ret
991
 
992
; Memory streams handling.
993
; Archive handlers create memory stream for small files:
994
; size of which is not greater than (free RAM size)/4 and
995
; not greater than following constant...
996
;LIMIT_FOR_MEM_STREAM = 2*1024*1024
997
; ...if it is defined. Now the definition is commented:
998
; if user has many physical memory, why not to use it?
999
 
1000
virtual at 0
1001
mem_stream:
1002
.type   dd      ?       ; type_mem_stream
1003
.size   dd      ?
1004
.pos    dd      ?
1005
.buf:
1006
end virtual
1007
 
1008
; unsigned __stdcall read(ebx = HANDLE hFile, void* buf, unsigned size);
1009
read_mem_stream:
1010
        mov     eax, [esp+12]
1011
        mov     ecx, [ebx+mem_stream.size]
1012
        sub     ecx, [ebx+mem_stream.pos]
1013
        jnc     @f
1014
        xor     ecx, ecx
1015
@@:
1016
        cmp     eax, ecx
1017
        jb      @f
1018
        mov     eax, ecx
1019
@@:
1020
        mov     ecx, eax
1021
        lea     esi, [ebx+mem_stream.buf]
1022
        add     esi, [ebx+mem_stream.pos]
1023
        add     [ebx+mem_stream.pos], eax
1024
        mov     edi, [esp+8]
1025
        mov     edx, ecx
1026
        shr     ecx, 2
1027
        rep     movsd
1028
        mov     ecx, edx
1029
        and     ecx, 3
1030
        rep     movsb
1031
        ret     12
1032
 
1033
; void __stdcall setpos(ebx = HANDLE hFile, __int64 pos);
1034
setpos_mem_stream:
1035
        mov     eax, [esp+8]
1036
        mov     [ebx+mem_stream.pos], eax
1037
        ret     12
1038
 
1039
; void __stdcall close(ebx = HANDLE hFile);
1040
close_mem_stream:
1041
        mov     ecx, ebx
1042
        call    [pgfree]
1043
        ret     4
1044
 
1045
; Allocate handle for file
1046
; esi -> handle table, ecx = size of handle
1047
alloc_handle:
1048
; Handle table is L2-list of allocated pages.
1049
; Scan for free entry
1050
        mov     edx, esi
1051
@@:
1052
        mov     edx, [edx]
1053
        cmp     edx, esi
1054
        jz      .alloc_new
1055
        mov     eax, [edx+8]            ; head of L1-list of free entries
1056
        test    eax, eax                ; has free entry?
1057
        jz      @b
1058
; we have found allocated page with free entry; allocate entry and return
1059
        inc     dword [edx+12]          ; number of busy entries
1060
        push    dword [eax]
1061
        pop     dword [edx+8]
1062
.ret:
1063
        ret
1064
.alloc_new:
1065
; no free pages; get new page and initialize
1066
        push    ecx
1067
        mov     ecx, 0x1000
1068
        call    [pgalloc]
1069
        pop     ecx
1070
        test    eax, eax
1071
        jz      .ret
1072
; insert new page to start of L2-list
1073
        mov     edx, [esi]
1074
        mov     [eax], edx
1075
        mov     [esi], eax
1076
        mov     [eax+4], esi
1077
        mov     [edx+4], eax
1078
        mov     dword [eax+12], 1       ; 1 allocated entry
1079
; initialize list of free entries
1080
        lea     edx, [eax+16]
1081
        push    edx     ; save return value
1082
        add     edx, ecx
1083
        mov     [eax+8], edx
1084
        add     eax, 0x1000
1085
@@:
1086
        mov     esi, edx
1087
        add     edx, ecx
1088
        mov     [esi], edx
1089
        cmp     edx, eax
1090
        jb      @b
1091
        and     dword [esi], 0
1092
        pop     eax
1093
        ret
1094
 
1095
; Free handle allocated in previous procedure
1096
; esi = handle
1097
free_handle:
1098
        mov     ecx, esi
1099
        and     ecx, not 0xFFF  ; get page
1100
; add entry to head of L1-list of free entries
1101
        mov     eax, [ecx+8]
1102
        mov     [esi], eax
1103
        mov     [ecx+8], esi
1104
        dec     dword [ecx+12]  ; decrement number of allocated entries
1105
        jnz     .ret
1106
; delete page from common L2-list
1107
        mov     eax, [ecx]
1108
        mov     edx, [ecx+4]
1109
        mov     [eax+4], edx
1110
        mov     [edx], eax
1111
; free page
1112
        call    [pgfree]
1113
.ret:
1114
        ret
1115
 
1116
; Ask user to enter password.
1117
; Out: ZF set <=> user pressed Esc
1118
;      'password_ansi', 'password_unicode', 'password_size' filled
1119
query_password:
1120
        cmp     [bPasswordDefined], 0
1121
        jnz     .ret
1122
        mov     edi, password_data
1123
        mov     eax, password_maxlen
1124
        stosd           ; maximum length
1125
        xor     eax, eax
1126
        stosd           ; start of visible part
1127
        stosd           ; position of cursor
1128
        stosb           ; initial state: empty string
1129
        mov     eax, [cur_console_size]
1130
        mov     eax, [eax]      ; get current console width
1131
        sub     eax, 12
1132
        mov     edi, password_dlg
1133
        mov     [edi+password_dlg.width-password_dlg], eax
1134
        dec     eax
1135
        dec     eax
1136
        mov     [edi+password_dlg.width1-password_dlg], eax
1137
        mov     [edi+password_dlg.width2-password_dlg], eax
1138
        push    edi
1139
        call    [DialogBox]
1140
        inc     eax
1141
        jz      .ret
1142
; convert ANSI-cp866 to UNICODE string; also calculate 'password_size'
1143
        mov     esi, password_ansi
1144
        mov     edi, password_unicode
1145
        or      [password_size], -1
1146
.cvt:
1147
        inc     [password_size]
1148
        lodsb
1149
        mov     ah, 0
1150
; 0x00-0x7F - trivial map
1151
        cmp     al, 0x80
1152
        jb      .symb
1153
; 0x80-0xAF -> 0x410-0x43F
1154
        cmp     al, 0xB0
1155
        jae     @f
1156
        add     ax, 0x410-0x80
1157
        jmp     .symb
1158
@@:
1159
; 0xE0-0xEF -> 0x440-0x44F
1160
        cmp     al, 0xE0
1161
        jb      .unk
1162
        cmp     al, 0xF0
1163
        jae     @f
1164
        add     ax, 0x440-0xE0
1165
        jmp     .symb
1166
@@:
1167
; 0xF0 -> 0x401
1168
; 0xF1 -> 0x451
1169
        cmp     al, 'Ё'
1170
        jz      .yo1
1171
        cmp     al, 'ё'
1172
        jz      .yo2
1173
.unk:
1174
        mov     al, '_'
1175
        jmp     .symb
1176
.yo1:
1177
        mov     ax, 0x401
1178
        jmp     .symb
1179
.yo2:
1180
        mov     ax, 0x451
1181
.symb:
1182
        stosw
1183
        test    al, al
1184
        jnz     .cvt
1185
        inc     [bPasswordDefined]      ; clears ZF flag
1186
.ret:
1187
        ret
1188
 
1189
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1022 diamond 1190
;;;;;;;;;;;;; API for other programs ;;;;;;;;;;;;
1191
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1192
; void* __stdcall deflate_unpack(void* packed_data, unsigned* pLength)
1193
deflate_unpack:
1194
	push	dword [esp+8]
1195
        push    esp
1196
        push    deflate_unpack_cb
1197
        call    deflate_unpack2
1198
        ret     8
1199
 
1200
deflate_unpack_cb:
1201
        mov     edx, [esp+4]
1202
        push    edx
1203
        mov     edx, [edx+12]
1204
        mov     edx, [edx]
1205
        mov     eax, [esp+8+4]
1206
        mov     [eax], edx
1207
        pop     edx
1208
        xor     eax, eax
1209
        xchg    eax, [edx+8]
1210
        ret     8
1211
 
1212
; void* __stdcall deflate_unpack2(void* get_next_chunk, void* parameter, unsigned* pUnpackedLength)
1213
;	void* __stdcall get_next_chunk(void* parameter, unsigned* pLength)
1214
deflate_unpack2:
1215
        pusha
1216
        mov     ecx, 0x11000
1217
        call    mypgalloc
1218
        test    eax, eax
1219
        jz      .ret
1220
        or      dword [eax+streamInfo.fullSize], -1
1221
        or      dword [eax+streamInfo.fullSize+4], -1
1222
        and     dword [eax+streamInfo.bufSize], 0
1223
        mov     dword [eax+streamInfo.fillBuf], .fillBuf
1224
        mov     edx, [esp+32+4]
1225
        mov     [eax+streamInfo.size], edx
1226
        mov     edx, [esp+32+8]
1227
        mov     [eax+streamInfo.size+4], edx
1228
        mov     [eax+streamInfo.size+8+deflate_decoder.inStream], eax
1229
        add     eax, streamInfo.size+8
1230
        lea     edi, [eax+deflate_decoder.size]
1231
        mov     [eax+streamInfo.bufPtr], edi
1232
        mov     ebp, eax
1233
        call    deflate_init_decoder
1234
        xor     edx, edx
1235
        mov     ecx, 10000h
1236
.loop:
1237
        push    @f
1238
        pushad
1239
        mov     [_esp], esp
1240
        mov     [_ebp], ebp
1241
        mov     [error_proc], .error
1242
        mov     ecx, 10000h
1243
        jmp     [eax+streamInfo.fillBuf]
1244
@@:
1245
        push    68
1246
        pop     eax
1247
        push    20
1248
        pop     ebx
1249
        int     0x40
1250
        test    eax, eax
1251
        jz      .nomem
1252
        mov     edx, eax
1253
        mov     eax, ebp
1254
        mov     esi, edi
1255
        push    edi
1256
        lea     edi, [edx+ecx-0x10000]
1257
        push    ecx
1258
        mov     ecx, 0x10000/4
1259
        rep     movsd
1260
        pop     ecx
1261
        pop     edi
1262
        add     ecx, 0x10000
1263
        jmp     .loop
1264
.error:
1265
        pop     eax
1266
        push    edi
1267
        popad
1268
        pop     eax
1269
        mov     eax, ebp
1270
        lea     esi, [eax+deflate_decoder.size]
1271
        sub     ecx, 0x10000
1272
        sub     edi, esi
1273
        add     ecx, edi
1274
        mov     eax, [esp+32+12]
1275
        test    eax, eax
1276
        jz      @f
1277
        mov     [eax], ecx
1278
@@:
1279
        test    ecx, ecx
1280
        jnz     @f
1281
        inc     ecx
1282
@@:
1283
        push    68
1284
        pop     eax
1285
        push    20
1286
        pop     ebx
1287
        int     0x40
1288
        test    eax, eax
1289
        jz      .nomem
1290
        sub     ecx, edi
1291
        mov     edx, edi
1292
        lea     edi, [eax+ecx]
1293
        mov     ecx, edx
1294
        shr     ecx, 2
1295
        rep     movsd
1296
        mov     ecx, edx
1297
        and     ecx, 3
1298
        rep     movsb
1299
        push    eax
1300
        push    68
1301
        pop     eax
1302
        push    13
1303
        pop     ebx
1304
        lea     ecx, [ebp-streamInfo.size-8]
1305
        int     40h
1306
        pop     eax
1307
        jmp     .ret
1308
.nomem:
1309
        push    68
1310
        pop     eax
1311
        push    13
1312
        pop     ebx
1313
        test    edx, edx
1314
        jz      @f
1315
        mov     ecx, edx
1316
        push    eax
1317
        int     0x40
1318
        pop     eax
1319
@@:
1320
        lea     ecx, [ebp-streamInfo.size-8]
1321
        int     0x40
1322
        xor     eax, eax
1323
.ret:
1324
        mov     [esp+28], eax
1325
        popa
1326
        ret     12
1327
.fillBuf:
1328
        push    eax
1329
        push    eax
1330
        push    esp
1331
        push    dword [eax+streamInfo.size+4]
1332
        call    dword [eax+streamInfo.size]
1333
        pop     edx
1334
        pop     ebp
1335
        mov     [ebp+streamInfo.bufPtr], eax
1336
        and     [ebp+streamInfo.bufDataLen], 0
1337
        test    eax, eax
1338
        jz      @f
1339
        mov     [ebp+streamInfo.bufDataLen], edx
1340
@@:
1341
        popad
1342
        ret
1343
 
1344
mypgalloc:
1345
        push    68
1346
        pop     eax
1347
        push    12
1348
        pop     ebx
1349
        int     0x40
1350
        ret
1351
 
1352
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
589 diamond 1353
;;;;;;;;;;;;;;;; Initialized data ;;;;;;;;;;;;;;;
1354
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1355
 
1356
; export table
1357
align 4
1358
EXPORTS:
926 diamond 1359
        dd      aVersion,       3
589 diamond 1360
        dd      aPluginLoad,    plugin_load
1361
        dd      aOpenFilePlugin,OpenFilePlugin
1362
        dd      aClosePlugin,   ClosePlugin
1363
        dd      aReadFolder,    ReadFolder
1364
        dd      aSetFolder,     SetFolder
1365
        dd      aGetFiles,      GetFiles
1366
        dd      aGetOpenPluginInfo, GetOpenPluginInfo
1367
        dd      aGetattr,       mygetattr
1368
        dd      aOpen,          myopen
1369
        dd      aRead,          myread
1370
        dd      aSetpos,        mysetpos
1371
        dd      aClose,         myclose
1022 diamond 1372
        dd      aDeflateUnpack, deflate_unpack
1373
        dd      aDeflateUnpack2,deflate_unpack2
589 diamond 1374
        dd      0
1375
 
1376
; exported names
1377
aVersion        db      'version',0
1378
aPluginLoad     db      'plugin_load',0
1379
aOpenFilePlugin db      'OpenFilePlugin',0
1380
aClosePlugin    db      'ClosePlugin',0
1381
aReadFolder     db      'ReadFolder',0
1382
aSetFolder      db      'SetFolder',0
1383
aGetFiles       db      'GetFiles',0
1384
aGetOpenPluginInfo db   'GetOpenPluginInfo',0
1385
aGetattr        db      'getattr',0
1386
aOpen           db      'open',0
1387
aRead           db      'read',0
1388
aSetpos         db      'setpos',0
1389
aClose          db      'close',0
1022 diamond 1390
aDeflateUnpack  db      'deflate_unpack',0
1391
aDeflateUnpack2 db      'deflate_unpack2',0
589 diamond 1392
 
1393
; common strings
1394
if lang eq ru
1395
aContinue       db      'Продолжить',0
1396
aCancel         db      'Отмена',0
1397
aHeaderError    db      'Ошибка в заголовке архива',0
1398
aReadError      db      'Ошибка чтения',0
1399
aNoFreeRam      db      'Недостаточно свободной оперативной памяти',0
1400
aEncodingProblem db     'Проблема с кодировкой',0
1401
aEncodingProblem_str db 'Имена некоторых файлов в архиве содержат символы,',0
1402
.2              db      'не представимые в кодировке cp866.',0
1403
.3              db      'Эти символы будут заменены на подчёркивания.',0
1404
aEnterPassword  db      'Введите пароль:',0
1405
aEnterPasswordLen = $ - aEnterPassword - 1
1406
aEnterPasswordTitle db  'Ввод пароля',0
1407
aArchiveDataError db    'Ошибка в данных архива',0
1408
aArchiveDataErrorPass db 'Ошибка в данных архива или неверный пароль',0
1409
aChangePass     db      'Ввести пароль',0
1410
aNameTooLong    db      'Слишком длинное имя',0
631 diamond 1411
aCannotOpenFile db      'Не могу открыть файл',0
589 diamond 1412
else
1413
aContinue       db      'Continue',0
1414
aCancel         db      'Cancel',0
1415
aHeaderError    db      'Invalid archive header',0
1416
aReadError      db      'Read error',0
1417
aNoFreeRam      db      'There is not enough of free RAM',0
1418
aEncodingProblem db     'Encoding problem',0
1419
aEncodingProblem_str db 'The names of some files in the archive contain',0
1420
.2              db      'characters which can not be represented in cp866.',0
1421
.3              db      'Such characters will be replaced to underscores.',0
1422
aEnterPassword  db      'Enter password:',0
1423
aEnterPasswordLen = $ - aEnterPassword - 1
1424
aEnterPasswordTitle db  'Get password',0
1425
aArchiveDataError db    'Error in archive data',0
1426
aArchiveDataErrorPass db 'Error in archive data or incorrect password',0
1427
aChangePass     db      'Enter password',0
1428
aNameTooLong    db      'Name is too long',0
631 diamond 1429
aCannotOpenFile db      'Cannot open file',0
589 diamond 1430
end if
1431
 
631 diamond 1432
; kfar_arc supports many archive types.
589 diamond 1433
; OpenFilePlugin looks for supported archive signature and gives control
1434
;   to concrete handler if found.
631 diamond 1435
; Other functions just determine type of opened archive and jump to corresponding handler.
589 diamond 1436
type_mem_stream = 0     ; memory stream - for file handles (returned from 'open')
1437
type_7z = 1
631 diamond 1438
type_zip = 2
589 diamond 1439
 
1440
; archive functions (types start from type_7z)
1441
align 4
1442
ClosePluginTable:
1443
        dd      close_7z
631 diamond 1444
        dd      close_zip
589 diamond 1445
getattrTable:
1446
        dd      getattr_7z
631 diamond 1447
        dd      getattr_zip
589 diamond 1448
openTable:
1449
        dd      open_file_7z
631 diamond 1450
        dd      open_file_zip
1451
basesizes:
1452
        dd      handle_7z.basesize, file_in_7z.size
1453
        dd      handle_zip.basesize, file_in_zip.size
589 diamond 1454
 
1455
; file functions (types start from type_mem_stream)
1456
readTable:
1457
        dd      read_mem_stream
1458
        dd      read_7z
631 diamond 1459
        dd      read_zip
589 diamond 1460
setposTable:
1461
        dd      setpos_mem_stream
1462
        dd      setpos_7z
631 diamond 1463
        dd      setpos_zip
589 diamond 1464
closeTable:
1465
        dd      close_mem_stream
1466
        dd      close_file_7z
631 diamond 1467
        dd      close_file_zip
589 diamond 1468
 
1469
; pointers for SayErr and Message
1470
ContinueBtn     dd      aContinue
1471
HeaderError_ptr dd      aHeaderError
1472
aReadError_ptr  dd      aReadError
1473
aNoFreeRam_ptr  dd      aNoFreeRam
1474
aEncodingProblem_str_ptr:
1475
                dd      aEncodingProblem_str
1476
                dd      aEncodingProblem_str.2
1477
                dd      aEncodingProblem_str.3
1478
aNameTooLong_ptr dd     aNameTooLong
1479
aArchiveDataError_ptr dd aArchiveDataError
1480
aArchiveDataErrorPass_ptr dd aArchiveDataErrorPass
1481
CancelPassBtn   dd      aCancel
1482
                dd      aChangePass
1483
 
1484
; "enter password" dialog for KFar
1485
password_dlg:
1486
        dd      1       ; use standard dialog colors
1487
        dd      -1      ; center window by x
1488
        dd      -1      ; center window by y
1489
.width  dd      ?       ; width (will be filled according to current console width)
1490
        dd      2       ; height
1491
        dd      4, 2    ; border size
1492
        dd      aEnterPasswordTitle     ; title
1493
        dd      ?       ; colors (will be set by KFar)
926 diamond 1494
        dd      0       ; used internally by dialog manager, ignored
589 diamond 1495
        dd      0, 0    ; reserved for DlgProc
1496
        dd      2       ; 2 controls
1497
; the string "enter password"
1498
        dd      1       ; type: static
1499
        dd      1,0     ; upper-left position
1500
.width1 dd      ?,0     ; bottom-right position
1501
        dd      aEnterPassword  ; data
1502
        dd      0       ; flags
1503
; editbox for password
1504
        dd      3       ; type: edit
1505
        dd      1,1     ; upper-left position
1506
.width2 dd      ?,0     ; bottom-right position
1507
        dd      password_data   ; data
1508
        dd      2Ch     ; flags
1509
 
1510
IncludeIGlobals
1511
 
1512
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1513
;;;;;;;;;;;;;;; Uninitialized data ;;;;;;;;;;;;;;
1514
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1515
 
1516
section '.udata' data readable writable align 16
1517
kfar_info       dd      ?
1518
crc_table       rd      256
1519
_esp            dd      ?
1520
_ebp            dd      ?
1521
bufsize         dd      ?
1522
bufptr          dd      ?
1523
bufend          dd      ?
1524
buffer          rb      1024
1525
inStream        dd      ?
1526
hOut            dd      ?
1527
.allocated      dd      ?
1528
 
1529
error_proc      dd      ?
1530
clear_proc      dd      ?
1531
 
1532
; import from kfar
631 diamond 1533
open2           dd      ?
1534
filesize        dd      ?
589 diamond 1535
read            dd      ?
1536
seek            dd      ?
1537
close           dd      ?
1538
pgalloc         dd      ?
1539
pgrealloc       dd      ?
1540
pgfree          dd      ?
1541
getfreemem      dd      ?
1542
DialogBox       dd      ?
1543
SayErr          dd      ?
1544
Message         dd      ?
1545
cur_console_size dd     ?
1546
 
1547
; data for editbox in kfar dialog
1548
password_maxlen = 512
1549
password_data:
1550
.maxlen         dd      ?
1551
.pos            dd      ?
1552
.start          dd      ?
1553
password_ansi   rb      password_maxlen+1
1554
bPasswordDefined db     ?
1555
 
1556
; converted password
1557
password_unicode rw     password_maxlen+1
1558
password_size   dd      ?
1559
 
1560
IncludeUGlobals
1561
 
1562
bWasWarning     db      ?