Subversion Repositories Kolibri OS

Rev

Rev 589 | Rev 644 | 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
631 diamond 5
; version:              0.11
6
; last update:          2007-09-20 (Sep 20, 2007)
7
; minimal KFar version: 0.41
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
395
        mov     eax, edx
396
        mov     edi, tmp_bdfe
397
        push    edi
398
        sub     esi, [ebx+file_common.fullname]
399
        add     esi, [edx+file_common.fullname]
400
        push    esi
401
        mov     ecx, [ebp]
402
        call    dword [getattrTable+(ecx-1)*4]
403
        mov     eax, [esp+16+20]
404
        call    eax
405
        pop     esi
406
        test    al, al
407
        jz      .forced_exit
408
        jmp     .parloope
409
.pardone:
410
        cmp     [ebx+file_common.bIsDirectory], 0
411
        jz      .addfile
412
        mov     eax, [cur_stamp]
413
        cmp     [ebx+file_common.stamp], eax
414
        jz      .cont
415
        mov     [ebx+file_common.stamp], eax
416
        push    esi
417
        mov     eax, ebx
418
        mov     edi, tmp_bdfe
419
        push    edi
420
        push    esi
421
        mov     ecx, [ebp]
422
        call    dword [getattrTable+(ecx-1)*4]
423
        mov     eax, [esp+16+20]
424
        call    eax
425
        pop     esi
426
        test    al, al
427
        jz      .forced_exit
428
        jmp     .cont
429
.addfile:
430
        push    ebx esi ebp
431
        push    11h
432
        pop     edi
433
        mov     eax, ebx
434
        mov     ecx, [ebp]
435
        call    dword [openTable+(ecx-1)*4]
436
        pop     ebp esi ebx
437
        test    eax, eax
438
        jz      .cont
439
        push    eax
440
        push    eax
441
        mov     edi, tmp_bdfe
442
        push    edi
443
        push    esi
444
        mov     eax, ebx
445
        mov     ecx, [ebp]
446
        call    dword [getattrTable+(ecx-1)*4]
447
        mov     eax, [esp+20+16]
448
        call    eax
449
        pop     ecx
450
        push    eax ebp
451
        push    ebx
452
        push    ecx
453
        call    myclose
454
        pop     ebx
455
        pop     ebp eax
456
        test    al, al
457
        jz      .forced_exit
458
.cont:
589 diamond 459
        mov     eax, [ebp]
631 diamond 460
        add     ebx, [basesizes+(eax-1)*8+4]
461
        pop     ecx
462
        dec     ecx
463
        jnz     .loop
464
.ret:
465
        ret     20
466
.forced_exit:
467
        pop     ecx
468
        jmp     .ret
589 diamond 469
 
470
; void __stdcall GetOpenPluginInfo(HANDLE hPlugin, OpenPluginInfo* info);
471
GetOpenPluginInfo:
472
        mov     eax, [esp+8]    ; get info ptr
473
        mov     byte [eax], 3   ; flags: add non-existing '..' entry automatically
474
                                ;        use GetFiles for copying
475
        ret     8
476
 
477
; int __stdcall getattr(HANDLE hPlugin, const char* filename, void* info);
478
mygetattr:
479
        call    lookup_file_name
480
        test    eax, eax
481
        jz      @f
482
        mov     edx, [ebp]
483
        dec     edx
484
        mov     edi, [esp+12]   ; info ptr
485
        call    dword [getattrTable+edx*4]
486
        xor     eax, eax
487
        ret     12
488
@@:
489
        mov     al, 5   ; ERROR_FILE_NOT_FOUND
490
        ret     12
491
 
492
; HANDLE __stdcall open(HANDLE hPlugin, const char* filename, int mode);
493
myopen:
494
        call    lookup_file_name
495
        test    eax, eax
496
        jz      @f
497
        mov     edx, [ebp]
498
        dec     edx
499
        mov     edi, [esp+12]   ; mode
500
        call    dword [openTable+edx*4]
501
@@:
502
        ret     12
503
 
504
; unsigned __stdcall read(HANDLE hFile, void* buf, unsigned size);
505
myread:
506
        mov     ebx, [esp+4]
507
        mov     eax, [ebx]
508
        jmp     dword [readTable+eax*4]
509
 
510
; void __stdcall setpos(HANDLE hFile, __int64 pos);
511
mysetpos:
512
        mov     ebx, [esp+4]
513
        mov     eax, [ebx]
514
        jmp     dword [setposTable+eax*4]
515
 
516
; void __stdcall close(HANDLE hFile);
517
myclose:
518
        mov     ebx, [esp+4]
519
        mov     eax, [ebx]
520
        jmp     dword [closeTable+eax*4]
521
 
522
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
523
;;;;;;;;;;;;;; Auxiliary procedures ;;;;;;;;;;;;;
524
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
525
 
526
; return.err and return.clear are labels to jmp if something is invalid
527
; the caller must previously define [_esp], [_ebp] and [error_proc], [clear_proc]
528
return.err:
529
        mov     esp, [_esp]
530
        mov     ebp, [_ebp]
531
        jmp     [error_proc]
532
return.clear:
533
        mov     esp, [_esp]
534
        mov     ebp, [_ebp]
535
        jmp     [clear_proc]
536
 
537
; data for following routine
538
iglobal
539
align 4
540
_24             dd      24
541
_60             dd      60
542
_10000000       dd      10000000
543
days400year     dd      365*400+100-4+1
544
days100year     dd      365*100+25-1
545
days4year       dd      365*4+1
546
days1year       dd      365
547
months          dd      31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
548
months2         dd      31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
549
_400            dd      400
550
_100            dd      100
551
endg
552
 
553
; Convert QWORD FILETIME to BDFE format.
554
ntfs_datetime_to_bdfe:
555
; edx:eax = number of 100-nanosecond intervals since January 1, 1601, in UTC
556
        push    eax
557
        mov     eax, edx
558
        xor     edx, edx
559
        div     [_10000000]
560
        xchg    eax, [esp]
561
        div     [_10000000]
562
        pop     edx
563
; edx:eax = number of seconds since January 1, 1601
564
        push    eax
565
        mov     eax, edx
566
        xor     edx, edx
567
        div     [_60]
568
        xchg    eax, [esp]
569
        div     [_60]
570
        mov     [edi], dl
571
        pop     edx
572
; edx:eax = number of minutes
573
        div     [_60]
574
        mov     [edi+1], dl
575
; eax = number of hours (note that 2^64/(10^7*60*60) < 2^32)
576
        xor     edx, edx
577
        div     [_24]
578
        mov     [edi+2], dl
579
        mov     [edi+3], byte 0
580
; eax = number of days since January 1, 1601
581
        xor     edx, edx
582
        div     [days400year]
583
        imul    eax, 400
584
        add     eax, 1601
585
        mov     [edi+6], ax
586
        mov     eax, edx
587
        xor     edx, edx
588
        div     [days100year]
589
        cmp     al, 4
590
        jnz     @f
591
        dec     eax
592
        add     edx, [days100year]
593
@@:
594
        imul    eax, 100
595
        add     [edi+6], ax
596
        mov     eax, edx
597
        xor     edx, edx
598
        div     [days4year]
599
        shl     eax, 2
600
        add     [edi+6], ax
601
        mov     eax, edx
602
        xor     edx, edx
603
        div     [days1year]
604
        cmp     al, 4
605
        jnz     @f
606
        dec     eax
607
        add     edx, [days1year]
608
@@:
609
        add     [edi+6], ax
610
        push    esi edx
611
        mov     esi, months
612
        movzx   eax, word [edi+6]
613
        test    al, 3
614
        jnz     .noleap
615
        xor     edx, edx
616
        push    eax
617
        div     [_400]
618
        pop     eax
619
        test    edx, edx
620
        jz      .leap
621
        xor     edx, edx
622
        div     [_100]
623
        test    edx, edx
624
        jz      .noleap
625
.leap:
626
        mov     esi, months2
627
.noleap:
628
        pop     edx
629
        xor     eax, eax
630
        inc     eax
631
@@:
632
        sub     edx, [esi]
633
        jb      @f
634
        add     esi, 4
635
        inc     eax
636
        jmp     @b
637
@@:
638
        add     edx, [esi]
639
        pop     esi
640
        inc     edx
641
        mov     [edi+4], dl
642
        mov     [edi+5], al
643
        add     edi, 8
644
        ret
645
 
646
; By given array of files information, initialize links between them
647
; ("[folder] contains [item]" relations).
648
; Information structure must be compatible with 'file_common'.
649
; Size of information structure is in [esp+4].
650
init_file_links:
651
; in: edx->file infos, ebx = number of files, [esp+4] = size,
652
;     edi->{dd root.subfolders, dd root.subfolders.end,
653
;           dd root.subfiles, dd root.subfiles.end, dd root.NumItems}
654
        xor     eax, eax
655
        mov     [.free], eax
656
        push    edi
657
        stosd
658
        stosd
659
        stosd
660
        stosd
661
        stosd
662
        pop     edi
663
; Loop through all files
664
.mainloop:
665
        dec     ebx
666
        js      .mainloopdone
667
; Parse file name
668
; esi->current character in name
669
; dword [esp] = start of current component in file name
670
; ecx->{dd curdir.subfolders, dd curdir.subfolders.end,
671
;       dd curdir.subfiles, dd curdir.subfiles.end}
672
        mov     esi, [edx+file_common.fullname]
673
        mov     ecx, edi
674
.parseloop:
675
        push    esi
676
.parsename:
677
        lodsb
678
        test    al, al
679
        jz      @f
680
        cmp     al, '/'
681
        jnz     .parsename
682
@@:
683
; we have found next component of current name; look for it in current directory
684
        sub     esi, [esp]
685
        dec     esi     ; esi = strlen(component)
686
        cmp     esi, 259
687
        jbe     @f
688
        push    ContinueBtn
689
        push    1
690
        push    aNameTooLong_ptr
691
        push    1
692
        call    [SayErr]
693
        jmp     return.clear
694
@@:
695
        push    ecx
696
        mov     eax, [ecx]      ; eax->subfolders list
697
        mov     ecx, esi
698
.scansubfolders:
699
        test    eax, eax
700
        jz      .nofolder
701
        add     eax, [hOut]
702
        cmp     [eax+file_common.namelen], ecx
703
        jnz     .scancont
704
        mov     esi, [esp+4]
705
        push    ecx edi
706
        mov     edi, [eax+file_common.name]
707
        repz    cmpsb
708
        pop     edi ecx
709
        jz      .subfound
710
.scancont:
711
        mov     eax, [eax+file_common.next]
712
        jmp     .scansubfolders
713
.subfound:
714
; found subfolder, set it as current and continue parsing name
715
        add     [esp+4], ecx
716
        pop     ecx
717
        lea     ecx, [eax+file_common.subfolders]
718
        pop     esi
719
        lodsb
720
        test    al, al
721
        jnz     .parseloop
722
; that was the last component of the name, and we have found subfolder
723
; so found subfolder is a virtual subfolder and must be replaced with current
724
; name
725
        mov     eax, [ecx-file_common.subfolders+file_common.namelen]
726
        mov     [edx+file_common.namelen], eax
727
        sub     esi, eax
728
        dec     esi
729
        mov     [edx+file_common.name], esi
730
        sub     edx, [hOut]     ; convert pointer to relative
731
; replace item in L2-list
732
        mov     eax, [ecx-file_common.subfolders+file_common.prev]
733
        test    eax, eax
734
        jnz     .1
735
        mov     eax, [ecx-file_common.subfolders+file_common.parent]
736
        sub     eax, file_common.next - file_common.subfolders
737
        jnc     .1
738
        lea     eax, [edi-file_common.next]
739
        jmp     .2
740
.1:
741
        add     eax, [hOut]
742
.2:
743
        mov     [eax+file_common.next], edx
744
        mov     eax, [ecx-file_common.subfolders+file_common.next]
745
        test    eax, eax
746
        jnz     .3
747
        mov     eax, [ecx-file_common.subfolders+file_common.parent]
748
        sub     eax, file_common.prev - file_common.subfolders.end
749
        jnc     .3
750
        lea     eax, [edi-file_common.prev+4]
751
        jmp     .4
752
.3:
753
        add     eax, [hOut]
754
.4:
755
        mov     [eax+file_common.prev], edx
756
; correct parent links in childrens
757
        mov     eax, [ecx]
758
@@:
759
        test    eax, eax
760
        jz      @f
761
        add     eax, [hOut]
762
        mov     [eax+file_common.parent], edx
763
        mov     eax, [eax+file_common.next]
764
        jmp     @b
765
@@:
766
        mov     eax, [ecx+8]
767
@@:
768
        test    eax, eax
769
        jz      @f
770
        add     eax, [hOut]
771
        mov     [eax+file_common.parent], edx
772
        mov     eax, [eax+file_common.next]
773
        jmp     @b
774
@@:
775
        add     edx, [hOut]
776
; set children links
777
        mov     eax, [ecx]
778
        mov     [edx+file_common.subfolders], eax
779
        mov     eax, [ecx+4]
780
        mov     [edx+file_common.subfolders.end], eax
781
        mov     eax, [ecx+8]
782
        mov     [edx+file_common.subfiles], eax
783
        mov     eax, [ecx+12]
784
        mov     [edx+file_common.subfiles.end], eax
785
        mov     eax, [ecx+16]
786
        mov     [edx+file_common.NumSubItems], eax
787
; set prev/next links
788
        mov     eax, [ecx-file_common.subfolders+file_common.next]
789
        mov     [edx+file_common.next], eax
790
        mov     eax, [ecx-file_common.subfolders+file_common.prev]
791
        mov     [edx+file_common.prev], eax
792
; add old item to list of free items
793
uglobal
794
align 4
795
init_file_links.free    dd      ?
796
endg
797
        sub     ecx, file_common.subfolders
798
        mov     eax, [.free]
799
        mov     [ecx], eax
800
        sub     ecx, [hOut]
801
        mov     [.free], ecx
802
        jmp     .mainloopcont
803
.nofolder:
804
        mov     eax, edx
805
        mov     esi, [esp+4]
806
        cmp     byte [esi+ecx], 0
807
        jz      .newitem
808
; the current item is as 'dir1/item1' and 'dir1' has not been found
809
; allocate virtual subfolder 'dir1'
810
        mov     eax, [init_file_links.free]
811
        test    eax, eax
812
        jz      .realloc
813
        add     eax, [hOut]
814
        push    dword [eax]
815
        pop     [init_file_links.free]
816
        jmp     .allocated
817
.realloc:
818
; there is no free space, so reallocate [hOut] block
819
        mov     eax, [hOut]
820
        sub     [esp], eax      ; make pointers relative
821
        sub     edx, eax
822
        sub     edi, eax
823
        push    ecx
824
        mov     ecx, [hOut.allocated]
825
        add     ecx, [esp+12+4]
826
        mov     [hOut.allocated], ecx
827
        push    ecx
828
        and     ecx, 0xFFF
829
        cmp     ecx, [esp+16+4]
830
        pop     ecx
831
        ja      @f
832
        push    edx
833
        mov     edx, eax
834
        call    [pgrealloc]
835
        pop     edx
836
        test    eax, eax
837
        jnz     @f
838
        mov     ecx, [hOut]
839
        call    [pgfree]
840
        mov     esp, [_esp]
841
        or      eax, -1
842
        ret
843
@@:
844
        pop     ecx
845
        mov     [hOut], eax
846
        add     [esp], eax      ; make pointers absolute
847
        add     edx, eax
848
        add     edi, eax
849
        add     eax, [hOut.allocated]
850
        sub     eax, [esp+8+4]
851
.allocated:
852
; eax -> new item
853
        mov     [eax+file_common.bIsDirectory], 1
854
        mov     [eax+file_common.bPseudoFolder], 1
855
.newitem:
856
        mov     [eax+file_common.namelen], ecx
857
        pop     ecx
858
        pop     esi
859
; ecx = parent item, eax = current item
860
        mov     [eax+file_common.name], esi
861
        inc     dword [ecx+16]  ; new item in parent folder
862
        push    ecx
863
; add new item to end of L2-list
864
        and     [eax+file_common.next], 0
865
        cmp     [eax+file_common.bIsDirectory], 0
866
        jnz     @f
867
        add     ecx, 8
868
@@:
869
        push    eax
870
        sub     eax, [hOut]
871
        cmp     dword [ecx], 0
872
        jnz     @f
873
        mov     [ecx], eax
874
@@:
875
        xchg    eax, [ecx+4]
876
        xchg    eax, ecx
877
        pop     eax
878
        mov     [eax+file_common.prev], ecx
879
        jecxz   @f
880
        add     ecx, [hOut]
881
        sub     eax, [hOut]
882
        mov     [ecx+file_common.next], eax
883
        add     eax, [hOut]
884
@@:
885
        pop     ecx
886
; set parent link
887
        and     [eax+file_common.parent], 0
888
        cmp     ecx, edi
889
        jz      @f
890
        sub     ecx, file_common.subfolders
891
        sub     ecx, [hOut]
892
        mov     [eax+file_common.parent], ecx
893
@@:
894
; set current directory to current item
895
        lea     ecx, [eax+file_common.subfolders]
896
; if that was not last component, continue parse name
897
        add     esi, [eax+file_common.namelen]
898
        lodsb
899
        test    al, al
900
        jnz     .parseloop
901
.mainloopcont:
902
; continue main loop
903
        add     edx, [esp+4]
904
        jmp     .mainloop
905
.mainloopdone:
906
; Loop done.
907
        ret     4
908
 
909
; This subroutine is called by getattr and open.
910
; This subroutine looks for file name and returns NULL or pointer to file info record.
911
lookup_file_name:
912
        mov     ebp, [esp+8]    ; hPlugin
913
        mov     esi, [esp+12]   ; filename
914
        lea     edi, [ebp+handle_common.root.subfolders]
915
        xor     eax, eax
916
; KFar operates with absolute names, skip first '/'
917
        cmp     byte [esi], '/'
918
        jnz     .notfound
919
        inc     esi
920
.mainloop:
921
; get next component of name
922
        push    -1
923
        pop     ecx
924
@@:
925
        inc     ecx
926
        cmp     byte [esi+ecx], '/'
927
        jz      @f
928
        cmp     byte [esi+ecx], 0
929
        jnz     @b
930
@@:
931
; esi->component, ecx=length
932
; scan for required item in subfolders list
933
        push    -1
934
        mov     eax, [edi]      ; .subfolders
935
.scan1:
936
        test    eax, eax
937
        jz      .notfound1
938
        add     eax, ebp
939
        cmp     [eax+file_common.namelen], ecx
940
        jnz     .cont1
941
        push    ecx esi edi
942
        mov     edi, [eax+file_common.name]
943
        repz    cmpsb
944
        pop     edi esi ecx
945
        jz      .found1
946
.cont1:
947
        mov     eax, [eax+file_common.next]
948
        jmp     .scan1
949
.notfound1:
950
        pop     edx
951
; if this is last component in file name, scan in subfiles list
952
        cmp     byte [esi+ecx], al
953
        jnz     .notfound
954
        inc     edx
955
        jnz     .notfound
956
        mov     eax, [edi+8]    ; .subfiles
957
        push    edx
958
        jmp     .scan1
959
.found1:
960
        pop     edi
961
; item is found, go to next component
962
        lea     edi, [eax+file_common.subfolders]
963
        lea     esi, [esi+ecx+1]
964
        cmp     byte [esi-1], 0
965
        jnz     .mainloop
966
; this was the last component
967
.notfound:
968
        ret
969
 
970
; Memory streams handling.
971
; Archive handlers create memory stream for small files:
972
; size of which is not greater than (free RAM size)/4 and
973
; not greater than following constant...
974
;LIMIT_FOR_MEM_STREAM = 2*1024*1024
975
; ...if it is defined. Now the definition is commented:
976
; if user has many physical memory, why not to use it?
977
 
978
virtual at 0
979
mem_stream:
980
.type   dd      ?       ; type_mem_stream
981
.size   dd      ?
982
.pos    dd      ?
983
.buf:
984
end virtual
985
 
986
; unsigned __stdcall read(ebx = HANDLE hFile, void* buf, unsigned size);
987
read_mem_stream:
988
        mov     eax, [esp+12]
989
        mov     ecx, [ebx+mem_stream.size]
990
        sub     ecx, [ebx+mem_stream.pos]
991
        jnc     @f
992
        xor     ecx, ecx
993
@@:
994
        cmp     eax, ecx
995
        jb      @f
996
        mov     eax, ecx
997
@@:
998
        mov     ecx, eax
999
        lea     esi, [ebx+mem_stream.buf]
1000
        add     esi, [ebx+mem_stream.pos]
1001
        add     [ebx+mem_stream.pos], eax
1002
        mov     edi, [esp+8]
1003
        mov     edx, ecx
1004
        shr     ecx, 2
1005
        rep     movsd
1006
        mov     ecx, edx
1007
        and     ecx, 3
1008
        rep     movsb
1009
        ret     12
1010
 
1011
; void __stdcall setpos(ebx = HANDLE hFile, __int64 pos);
1012
setpos_mem_stream:
1013
        mov     eax, [esp+8]
1014
        mov     [ebx+mem_stream.pos], eax
1015
        ret     12
1016
 
1017
; void __stdcall close(ebx = HANDLE hFile);
1018
close_mem_stream:
1019
        mov     ecx, ebx
1020
        call    [pgfree]
1021
        ret     4
1022
 
1023
; Allocate handle for file
1024
; esi -> handle table, ecx = size of handle
1025
alloc_handle:
1026
; Handle table is L2-list of allocated pages.
1027
; Scan for free entry
1028
        mov     edx, esi
1029
@@:
1030
        mov     edx, [edx]
1031
        cmp     edx, esi
1032
        jz      .alloc_new
1033
        mov     eax, [edx+8]            ; head of L1-list of free entries
1034
        test    eax, eax                ; has free entry?
1035
        jz      @b
1036
; we have found allocated page with free entry; allocate entry and return
1037
        inc     dword [edx+12]          ; number of busy entries
1038
        push    dword [eax]
1039
        pop     dword [edx+8]
1040
.ret:
1041
        ret
1042
.alloc_new:
1043
; no free pages; get new page and initialize
1044
        push    ecx
1045
        mov     ecx, 0x1000
1046
        call    [pgalloc]
1047
        pop     ecx
1048
        test    eax, eax
1049
        jz      .ret
1050
; insert new page to start of L2-list
1051
        mov     edx, [esi]
1052
        mov     [eax], edx
1053
        mov     [esi], eax
1054
        mov     [eax+4], esi
1055
        mov     [edx+4], eax
1056
        mov     dword [eax+12], 1       ; 1 allocated entry
1057
; initialize list of free entries
1058
        lea     edx, [eax+16]
1059
        push    edx     ; save return value
1060
        add     edx, ecx
1061
        mov     [eax+8], edx
1062
        add     eax, 0x1000
1063
@@:
1064
        mov     esi, edx
1065
        add     edx, ecx
1066
        mov     [esi], edx
1067
        cmp     edx, eax
1068
        jb      @b
1069
        and     dword [esi], 0
1070
        pop     eax
1071
        ret
1072
 
1073
; Free handle allocated in previous procedure
1074
; esi = handle
1075
free_handle:
1076
        mov     ecx, esi
1077
        and     ecx, not 0xFFF  ; get page
1078
; add entry to head of L1-list of free entries
1079
        mov     eax, [ecx+8]
1080
        mov     [esi], eax
1081
        mov     [ecx+8], esi
1082
        dec     dword [ecx+12]  ; decrement number of allocated entries
1083
        jnz     .ret
1084
; delete page from common L2-list
1085
        mov     eax, [ecx]
1086
        mov     edx, [ecx+4]
1087
        mov     [eax+4], edx
1088
        mov     [edx], eax
1089
; free page
1090
        call    [pgfree]
1091
.ret:
1092
        ret
1093
 
1094
; Ask user to enter password.
1095
; Out: ZF set <=> user pressed Esc
1096
;      'password_ansi', 'password_unicode', 'password_size' filled
1097
query_password:
1098
        cmp     [bPasswordDefined], 0
1099
        jnz     .ret
1100
        mov     edi, password_data
1101
        mov     eax, password_maxlen
1102
        stosd           ; maximum length
1103
        xor     eax, eax
1104
        stosd           ; start of visible part
1105
        stosd           ; position of cursor
1106
        stosb           ; initial state: empty string
1107
        mov     eax, [cur_console_size]
1108
        mov     eax, [eax]      ; get current console width
1109
        sub     eax, 12
1110
        mov     edi, password_dlg
1111
        mov     [edi+password_dlg.width-password_dlg], eax
1112
        dec     eax
1113
        dec     eax
1114
        mov     [edi+password_dlg.width1-password_dlg], eax
1115
        mov     [edi+password_dlg.width2-password_dlg], eax
1116
        push    edi
1117
        call    [DialogBox]
1118
        inc     eax
1119
        jz      .ret
1120
; convert ANSI-cp866 to UNICODE string; also calculate 'password_size'
1121
        mov     esi, password_ansi
1122
        mov     edi, password_unicode
1123
        or      [password_size], -1
1124
.cvt:
1125
        inc     [password_size]
1126
        lodsb
1127
        mov     ah, 0
1128
; 0x00-0x7F - trivial map
1129
        cmp     al, 0x80
1130
        jb      .symb
1131
; 0x80-0xAF -> 0x410-0x43F
1132
        cmp     al, 0xB0
1133
        jae     @f
1134
        add     ax, 0x410-0x80
1135
        jmp     .symb
1136
@@:
1137
; 0xE0-0xEF -> 0x440-0x44F
1138
        cmp     al, 0xE0
1139
        jb      .unk
1140
        cmp     al, 0xF0
1141
        jae     @f
1142
        add     ax, 0x440-0xE0
1143
        jmp     .symb
1144
@@:
1145
; 0xF0 -> 0x401
1146
; 0xF1 -> 0x451
1147
        cmp     al, 'Ё'
1148
        jz      .yo1
1149
        cmp     al, 'ё'
1150
        jz      .yo2
1151
.unk:
1152
        mov     al, '_'
1153
        jmp     .symb
1154
.yo1:
1155
        mov     ax, 0x401
1156
        jmp     .symb
1157
.yo2:
1158
        mov     ax, 0x451
1159
.symb:
1160
        stosw
1161
        test    al, al
1162
        jnz     .cvt
1163
        inc     [bPasswordDefined]      ; clears ZF flag
1164
.ret:
1165
        ret
1166
 
1167
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1168
;;;;;;;;;;;;;;;; Initialized data ;;;;;;;;;;;;;;;
1169
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1170
 
1171
; export table
1172
align 4
1173
EXPORTS:
631 diamond 1174
        dd      aVersion,       2
589 diamond 1175
        dd      aPluginLoad,    plugin_load
1176
        dd      aOpenFilePlugin,OpenFilePlugin
1177
        dd      aClosePlugin,   ClosePlugin
1178
        dd      aReadFolder,    ReadFolder
1179
        dd      aSetFolder,     SetFolder
1180
        dd      aGetFiles,      GetFiles
1181
        dd      aGetOpenPluginInfo, GetOpenPluginInfo
1182
        dd      aGetattr,       mygetattr
1183
        dd      aOpen,          myopen
1184
        dd      aRead,          myread
1185
        dd      aSetpos,        mysetpos
1186
        dd      aClose,         myclose
1187
        dd      0
1188
 
1189
; exported names
1190
aVersion        db      'version',0
1191
aPluginLoad     db      'plugin_load',0
1192
aOpenFilePlugin db      'OpenFilePlugin',0
1193
aClosePlugin    db      'ClosePlugin',0
1194
aReadFolder     db      'ReadFolder',0
1195
aSetFolder      db      'SetFolder',0
1196
aGetFiles       db      'GetFiles',0
1197
aGetOpenPluginInfo db   'GetOpenPluginInfo',0
1198
aGetattr        db      'getattr',0
1199
aOpen           db      'open',0
1200
aRead           db      'read',0
1201
aSetpos         db      'setpos',0
1202
aClose          db      'close',0
1203
 
1204
; common strings
1205
if lang eq ru
1206
aContinue       db      'Продолжить',0
1207
aCancel         db      'Отмена',0
1208
aHeaderError    db      'Ошибка в заголовке архива',0
1209
aReadError      db      'Ошибка чтения',0
1210
aNoFreeRam      db      'Недостаточно свободной оперативной памяти',0
1211
aEncodingProblem db     'Проблема с кодировкой',0
1212
aEncodingProblem_str db 'Имена некоторых файлов в архиве содержат символы,',0
1213
.2              db      'не представимые в кодировке cp866.',0
1214
.3              db      'Эти символы будут заменены на подчёркивания.',0
1215
aEnterPassword  db      'Введите пароль:',0
1216
aEnterPasswordLen = $ - aEnterPassword - 1
1217
aEnterPasswordTitle db  'Ввод пароля',0
1218
aArchiveDataError db    'Ошибка в данных архива',0
1219
aArchiveDataErrorPass db 'Ошибка в данных архива или неверный пароль',0
1220
aChangePass     db      'Ввести пароль',0
1221
aNameTooLong    db      'Слишком длинное имя',0
631 diamond 1222
aCannotOpenFile db      'Не могу открыть файл',0
589 diamond 1223
else
1224
aContinue       db      'Continue',0
1225
aCancel         db      'Cancel',0
1226
aHeaderError    db      'Invalid archive header',0
1227
aReadError      db      'Read error',0
1228
aNoFreeRam      db      'There is not enough of free RAM',0
1229
aEncodingProblem db     'Encoding problem',0
1230
aEncodingProblem_str db 'The names of some files in the archive contain',0
1231
.2              db      'characters which can not be represented in cp866.',0
1232
.3              db      'Such characters will be replaced to underscores.',0
1233
aEnterPassword  db      'Enter password:',0
1234
aEnterPasswordLen = $ - aEnterPassword - 1
1235
aEnterPasswordTitle db  'Get password',0
1236
aArchiveDataError db    'Error in archive data',0
1237
aArchiveDataErrorPass db 'Error in archive data or incorrect password',0
1238
aChangePass     db      'Enter password',0
1239
aNameTooLong    db      'Name is too long',0
631 diamond 1240
aCannotOpenFile db      'Cannot open file',0
589 diamond 1241
end if
1242
 
631 diamond 1243
; kfar_arc supports many archive types.
589 diamond 1244
; OpenFilePlugin looks for supported archive signature and gives control
1245
;   to concrete handler if found.
631 diamond 1246
; Other functions just determine type of opened archive and jump to corresponding handler.
589 diamond 1247
type_mem_stream = 0     ; memory stream - for file handles (returned from 'open')
1248
type_7z = 1
631 diamond 1249
type_zip = 2
589 diamond 1250
 
1251
; archive functions (types start from type_7z)
1252
align 4
1253
ClosePluginTable:
1254
        dd      close_7z
631 diamond 1255
        dd      close_zip
589 diamond 1256
getattrTable:
1257
        dd      getattr_7z
631 diamond 1258
        dd      getattr_zip
589 diamond 1259
openTable:
1260
        dd      open_file_7z
631 diamond 1261
        dd      open_file_zip
1262
basesizes:
1263
        dd      handle_7z.basesize, file_in_7z.size
1264
        dd      handle_zip.basesize, file_in_zip.size
589 diamond 1265
 
1266
; file functions (types start from type_mem_stream)
1267
readTable:
1268
        dd      read_mem_stream
1269
        dd      read_7z
631 diamond 1270
        dd      read_zip
589 diamond 1271
setposTable:
1272
        dd      setpos_mem_stream
1273
        dd      setpos_7z
631 diamond 1274
        dd      setpos_zip
589 diamond 1275
closeTable:
1276
        dd      close_mem_stream
1277
        dd      close_file_7z
631 diamond 1278
        dd      close_file_zip
589 diamond 1279
 
1280
; pointers for SayErr and Message
1281
ContinueBtn     dd      aContinue
1282
HeaderError_ptr dd      aHeaderError
1283
aReadError_ptr  dd      aReadError
1284
aNoFreeRam_ptr  dd      aNoFreeRam
1285
aEncodingProblem_str_ptr:
1286
                dd      aEncodingProblem_str
1287
                dd      aEncodingProblem_str.2
1288
                dd      aEncodingProblem_str.3
1289
aNameTooLong_ptr dd     aNameTooLong
1290
aArchiveDataError_ptr dd aArchiveDataError
1291
aArchiveDataErrorPass_ptr dd aArchiveDataErrorPass
1292
CancelPassBtn   dd      aCancel
1293
                dd      aChangePass
1294
 
1295
; "enter password" dialog for KFar
1296
password_dlg:
1297
        dd      1       ; use standard dialog colors
1298
        dd      -1      ; center window by x
1299
        dd      -1      ; center window by y
1300
.width  dd      ?       ; width (will be filled according to current console width)
1301
        dd      2       ; height
1302
        dd      4, 2    ; border size
1303
        dd      aEnterPasswordTitle     ; title
1304
        dd      ?       ; colors (will be set by KFar)
1305
        dd      0, 0    ; reserved for DlgProc
1306
        dd      2       ; 2 controls
1307
; the string "enter password"
1308
        dd      1       ; type: static
1309
        dd      1,0     ; upper-left position
1310
.width1 dd      ?,0     ; bottom-right position
1311
        dd      aEnterPassword  ; data
1312
        dd      0       ; flags
1313
; editbox for password
1314
        dd      3       ; type: edit
1315
        dd      1,1     ; upper-left position
1316
.width2 dd      ?,0     ; bottom-right position
1317
        dd      password_data   ; data
1318
        dd      2Ch     ; flags
1319
 
1320
IncludeIGlobals
1321
 
1322
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1323
;;;;;;;;;;;;;;; Uninitialized data ;;;;;;;;;;;;;;
1324
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1325
 
1326
section '.udata' data readable writable align 16
1327
kfar_info       dd      ?
1328
crc_table       rd      256
1329
_esp            dd      ?
1330
_ebp            dd      ?
1331
bufsize         dd      ?
1332
bufptr          dd      ?
1333
bufend          dd      ?
1334
buffer          rb      1024
1335
inStream        dd      ?
1336
hOut            dd      ?
1337
.allocated      dd      ?
1338
 
1339
error_proc      dd      ?
1340
clear_proc      dd      ?
1341
 
1342
; import from kfar
631 diamond 1343
open2           dd      ?
1344
filesize        dd      ?
589 diamond 1345
read            dd      ?
1346
seek            dd      ?
1347
close           dd      ?
1348
pgalloc         dd      ?
1349
pgrealloc       dd      ?
1350
pgfree          dd      ?
1351
getfreemem      dd      ?
1352
DialogBox       dd      ?
1353
SayErr          dd      ?
1354
Message         dd      ?
1355
cur_console_size dd     ?
1356
 
1357
; data for editbox in kfar dialog
1358
password_maxlen = 512
1359
password_data:
1360
.maxlen         dd      ?
1361
.pos            dd      ?
1362
.start          dd      ?
1363
password_ansi   rb      password_maxlen+1
1364
bPasswordDefined db     ?
1365
 
1366
; converted password
1367
password_unicode rw     password_maxlen+1
1368
password_size   dd      ?
1369
 
1370
IncludeUGlobals
1371
 
1372
bWasWarning     db      ?