Subversion Repositories Kolibri OS

Rev

Rev 4273 | Rev 4700 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2288 clevermous 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
2455 mario79 3
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
2288 clevermous 4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7
 
8
$Revision: 4277 $
9
 
2889 turbanoff 10
ERROR_SUCCESS        = 0
11
ERROR_DISK_BASE      = 1
12
ERROR_UNSUPPORTED_FS = 2
13
ERROR_UNKNOWN_FS     = 3
14
ERROR_PARTITION      = 4
15
ERROR_FILE_NOT_FOUND = 5
16
ERROR_END_OF_FILE    = 6
17
ERROR_MEMORY_POINTER = 7
18
ERROR_DISK_FULL      = 8
19
ERROR_FAT_TABLE      = 9 ;deprecated
20
ERROR_FS_FAIL        = 9
21
ERROR_ACCESS_DENIED  = 10
22
ERROR_DEVICE         = 11
2288 clevermous 23
 
24
image_of_eax EQU esp+32
25
image_of_ebx EQU esp+20
26
 
27
; System function 70 - files with long names (LFN)
28
; diamond, 2006
29
 
30
iglobal
31
; in this table names must be in lowercase
32
rootdirs:
33
;**********************************************
34
        db      3,'cd0'
35
        dd      fs_OnCd0
36
        dd      fs_NextCd
37
        db      3,'cd1'
38
        dd      fs_OnCd1
39
        dd      fs_NextCd
40
        db      3,'cd2'
41
        dd      fs_OnCd2
42
        dd      fs_NextCd
43
        db      3,'cd3'
44
        dd      fs_OnCd3
45
        dd      fs_NextCd
46
;***********************************************
47
        db      0
48
 
49
 
50
virtual_root_query:
51
;**********************************************
52
        dd      fs_HasCd0
53
        db      'cd0',0
54
        dd      fs_HasCd1
55
        db      'cd1',0
56
        dd      fs_HasCd2
57
        db      'cd2',0
58
        dd      fs_HasCd3
59
        db      'cd3',0
60
;**********************************************
61
        dd      0
62
endg
3296 clevermous 63
 
64
file_system_lfn_protected:
65
        pushad
66
        call    protect_from_terminate
67
        call    file_system_lfn
68
        call    unprotect_from_terminate
69
        popad
70
        mov     [image_of_eax], eax
71
        mov     [image_of_ebx], ebx
72
        ret
73
 
2288 clevermous 74
file_system_lfn:
75
; in: ebx->fileinfo block
76
; operation codes:
77
; 0 : read file
78
; 1 : read folder
79
; 2 : create/rewrite file
80
; 3 : write/append to file
81
; 4 : set end of file
82
; 5 : get file/directory attributes structure
83
; 6 : set file/directory attributes structure
84
; 7 : start application
85
; 8 : delete file
86
; 9 : create directory
87
 
88
; parse file name
89
        lea     esi, [ebx+20]
90
        lodsb
91
        test    al, al
92
        jnz     @f
93
        mov     esi, [esi]
94
        lodsb
95
@@:
96
        cmp     al, '/'
97
        jz      .notcurdir
98
        dec     esi
99
        mov     ebp, esi
100
        test    al, al
101
        jnz     @f
102
        xor     ebp, ebp
103
@@:
104
        mov     esi, [current_slot]
105
        mov     esi, [esi+APPDATA.cur_dir]
106
        jmp     .parse_normal
107
.notcurdir:
108
        cmp     byte [esi], 0
109
        jz      .rootdir
110
        call    process_replace_file_name
111
.parse_normal:
112
        cmp     dword [ebx], 7
113
        jne     @F
114
        mov     edx, [ebx+4]
115
        mov     ebx, [ebx+8]
116
        call    fs_execute; esi+ebp, ebx, edx
117
        mov     [image_of_eax], eax
118
        ret
119
@@:
120
        mov     edi, rootdirs-8
121
        xor     ecx, ecx
122
        push    esi
123
.scan1:
124
        pop     esi
125
        add     edi, ecx
126
        scasd
127
        scasd
128
        mov     cl, byte [edi]
129
        test    cl, cl
130
        jz      .notfound_try
131
        inc     edi
132
        push    esi
133
@@:
134
        lodsb
135
        or      al, 20h
136
        scasb
137
        loopz   @b
138
        jnz     .scan1
139
        lodsb
140
        cmp     al, '/'
141
        jz      .found1
142
        test    al, al
143
        jnz     .scan1
144
        pop     eax
145
; directory /xxx
146
.maindir:
147
        mov     esi, [edi+4]
148
.maindir_noesi:
149
        cmp     dword [ebx], 1
150
        jnz     .access_denied
151
        xor     eax, eax
152
        mov     ebp, [ebx+12]                   ;количество блоков для считывания
153
        mov     edx, [ebx+16]                   ;куда записывать рузельтат
154
    ;    add     edx, std_application_base_address
155
        push    dword [ebx+4]   ; first block
156
        mov     ebx, [ebx+8]    ; flags
157
; ebx=flags, [esp]=first block, ebp=number of blocks, edx=return area, esi='Next' handler
158
        mov     edi, edx
159
        push    ecx
160
        mov     ecx, 32/4
161
        rep stosd
162
        pop     ecx
163
        mov     byte [edx], 1   ; version
164
.maindir_loop:
165
        call    esi
166
        jc      .maindir_done
167
        inc     dword [edx+8]
168
        dec     dword [esp]
169
        jns     .maindir_loop
170
        dec     ebp
171
        js      .maindir_loop
172
        inc     dword [edx+4]
173
        mov     dword [edi], 0x10       ; attributes: folder
174
        mov     dword [edi+4], 1        ; name type: UNICODE
175
        push    eax
176
        xor     eax, eax
177
        add     edi, 8
178
        push    ecx
179
        mov     ecx, 40/4-2
180
        rep stosd
181
        pop     ecx
182
        pop     eax
183
        push    eax edx
184
; convert number in eax to decimal UNICODE string
185
        push    edi
186
        push    ecx
187
        push    -'0'
188
        mov     ecx, 10
189
@@:
190
        xor     edx, edx
191
        div     ecx
192
        push    edx
193
        test    eax, eax
194
        jnz     @b
195
@@:
196
        pop     eax
197
        add     al, '0'
198
        stosb
199
        test    bl, 1           ; UNICODE name?
200
        jz      .ansi2
201
        mov     byte [edi], 0
202
        inc     edi
203
.ansi2:
204
        test    al, al
205
        jnz     @b
206
        mov     byte [edi-1], 0
207
        pop     ecx
208
        pop     edi
209
; UNICODE name length is 520 bytes, ANSI - 264
210
        add     edi, 520
211
        test    bl, 1
212
        jnz     @f
213
        sub     edi, 520-264
214
@@:
215
        pop     edx eax
216
        jmp     .maindir_loop
217
.maindir_done:
218
        pop     eax
219
        mov     ebx, [edx+4]
220
        xor     eax, eax
221
        dec     ebp
222
        js      @f
223
        mov     al, ERROR_END_OF_FILE
224
@@:
225
        mov     [image_of_eax], eax
226
        mov     [image_of_ebx], ebx
227
        ret
228
; directory /
229
.rootdir:
230
        cmp     dword [ebx], 1  ; read folder?
231
        jz      .readroot
232
.access_denied:
233
        mov     dword [image_of_eax], 10      ; access denied
234
        ret
235
 
236
.readroot:
237
; virtual root folder - special handler
238
        mov     ebp, [ebx+12]
239
        mov     edx, [ebx+16]
240
    ;    add     edx, std_application_base_address
241
        push    dword [ebx+4]   ; first block
242
        mov     ebx, [ebx+8]    ; flags
243
        xor     eax, eax
244
; eax=0, [esp]=first block, ebx=flags, ebp=number of blocks, edx=return area
245
        mov     edi, edx
246
        mov     ecx, 32/4
247
        rep stosd
248
        mov     byte [edx], 1   ; version
4277 clevermous 249
        sub     esp, 16
250
.readroot_ah_loop2:
251
        push    edi
252
        lea     edi, [esp+4]
253
        call    dyndisk_enum_root
254
        pop     edi
255
        test    eax, eax
256
        jz      .readroot_done_dynamic
257
        inc     dword [edx+8]
258
        dec     dword [esp+16]
259
        jns     .readroot_ah_loop2
260
        dec     ebp
261
        js      .readroot_ah_loop2
262
        push    eax
263
        xor     eax, eax
264
        inc     dword [edx+4]
265
        mov     dword [edi], 0x10       ; attributes: folder
266
        mov     dword [edi+4], ebx
267
        add     edi, 8
268
        mov     ecx, 40/4-2
269
        rep stosd
270
        push    esi edi
271
        lea     esi, [esp+12]
272
@@:
273
        lodsb
274
        stosb
275
        test    bl, 1
276
        jz      .ansi3
277
        mov     byte [edi], 0
278
        inc     edi
279
.ansi3:
280
        test    al, al
281
        jnz     @b
282
        pop     edi esi eax
283
        add     edi, 520
284
        test    bl, 1
285
        jnz     .readroot_ah_loop2
286
        sub     edi, 520-264
287
        jmp     .readroot_ah_loop2
288
.readroot_done_dynamic:
289
        add     esp, 16
290
        mov     esi, virtual_root_query
2288 clevermous 291
.readroot_loop:
292
        cmp     dword [esi], eax
4277 clevermous 293
        jz      .readroot_done
2288 clevermous 294
        call    dword [esi]
295
        add     esi, 4
296
        test    eax, eax
297
        jnz     @f
298
.readroot_next:
299
        or      ecx, -1
300
        xchg    esi, edi
301
        repnz scasb
302
        xchg    esi, edi
303
        jmp     .readroot_loop
304
@@:
305
        xor     eax, eax
306
        inc     dword [edx+8]
307
        dec     dword [esp]
308
        jns     .readroot_next
309
        dec     ebp
310
        js      .readroot_next
311
        inc     dword [edx+4]
312
        mov     dword [edi], 0x10       ; attributes: folder
313
        mov     dword [edi+4], ebx      ; name type: UNICODE
314
        add     edi, 8
315
        mov     ecx, 40/4-2
316
        rep stosd
317
        push    edi
318
@@:
319
        lodsb
320
        stosb
321
        test    bl, 1
322
        jz      .ansi
323
        mov     byte [edi], 0
324
        inc     edi
325
.ansi:
326
        test    eax, eax
327
        jnz     @b
328
        pop     edi
329
        add     edi, 520
330
        test    bl, 1
331
        jnz     .readroot_loop
332
        sub     edi, 520-264
333
        jmp     .readroot_loop
334
.readroot_done:
335
        pop     eax
336
        mov     ebx, [edx+4]
337
        xor     eax, eax
338
        dec     ebp
339
        js      @f
340
        mov     al, ERROR_END_OF_FILE
341
@@:
342
        mov     [image_of_eax], eax
343
        mov     [image_of_ebx], ebx
344
        ret
345
.notfound_try:
4277 clevermous 346
        call    dyndisk_handler
2288 clevermous 347
.notfound:
348
        mov     dword [image_of_eax], ERROR_FILE_NOT_FOUND
349
        and     dword [image_of_ebx], 0
350
        ret
351
 
352
.notfounda:
353
        cmp     edi, esp
354
        jnz     .notfound
355
        call    dword [edi+4]
356
        add     esp, 16
357
        jmp     .notfound
358
 
359
.found1:
360
        pop     eax
361
        cmp     byte [esi], 0
362
        jz      .maindir
363
.found2:
364
; read partition number
365
        xor     ecx, ecx
366
        xor     eax, eax
367
@@:
368
        lodsb
369
        cmp     al, '/'
370
        jz      .done1
371
        test    al, al
372
        jz      .done1
373
        sub     al, '0'
374
        cmp     al, 9
375
        ja      .notfounda
376
        lea     ecx, [ecx*5]
377
        lea     ecx, [ecx*2+eax]
378
        jmp     @b
379
.done1:
380
        jecxz   .notfounda
381
        test    al, al
382
        jnz     @f
383
        dec     esi
384
@@:
385
        cmp     byte [esi], 0
386
        jnz     @f
387
        test    ebp, ebp
388
        jz      @f
389
        mov     esi, ebp
390
        xor     ebp, ebp
391
@@:
392
; now [edi] contains handler address, ecx - partition number,
393
; esi points to ASCIIZ string - rest of name
394
        jmp     dword [edi]
395
 
396
; handlers for devices
397
; in: ecx = 0 => query virtual directory /xxx
398
; in: ecx = partition number
399
;     esi -> relative (for device) name
400
;     ebx -> fileinfo
401
;     ebp = 0 or pointer to rest of name from folder addressed by esi
402
; out: [image_of_eax]=image of eax, [image_of_ebx]=image of ebx
403
 
404
fs_NotImplemented:
405
        mov     eax, 2
406
        ret
407
 
408
;*******************************************************
409
fs_OnCd0:
410
        call    reserve_cd
411
        mov     [ChannelNumber], 1
412
        mov     [DiskNumber], 0
413
        push    6
414
        push    1
415
        jmp     fs_OnCd
416
fs_OnCd1:
417
        call    reserve_cd
418
        mov     [ChannelNumber], 1
419
        mov     [DiskNumber], 1
420
        push    4
421
        push    2
422
        jmp     fs_OnCd
423
fs_OnCd2:
424
        call    reserve_cd
425
        mov     [ChannelNumber], 2
426
        mov     [DiskNumber], 0
427
        push    2
428
        push    3
429
        jmp     fs_OnCd
430
fs_OnCd3:
431
        call    reserve_cd
432
        mov     [ChannelNumber], 2
433
        mov     [DiskNumber], 1
434
        push    0
435
        push    4
436
fs_OnCd:
437
        call    reserve_cd_channel
438
        pop     eax
439
        mov     [cdpos], eax
440
        pop     eax
441
        cmp     ecx, 0x100
442
        jae     .nf
443
        push    ecx ebx
444
        mov     cl, al
445
        mov     bl, [DRIVE_DATA+1]
446
        shr     bl, cl
447
        test    bl, 2
448
        pop     ebx ecx
449
 
450
        jnz     @f
451
.nf:
452
        call    free_cd_channel
453
        and     [cd_status], 0
454
        mov     dword [image_of_eax], 5       ; not found
455
        ret
456
@@:
457
        mov     ecx, [ebx+12]
458
        mov     edx, [ebx+16]
459
    ;    add     edx, std_application_base_address
460
        mov     eax, [ebx]
461
        cmp     eax, fs_NumCdServices
462
        jae     .not_impl
463
        add     ebx, 4
464
        call    dword [fs_CdServices + eax*4]
465
        call    free_cd_channel
466
        and     [cd_status], 0
467
        mov     [image_of_eax], eax
468
        mov     [image_of_ebx], ebx
469
        ret
470
.not_impl:
471
        call    free_cd_channel
472
        and     [cd_status], 0
473
        mov     dword [image_of_eax], 2       ; not implemented
474
        ret
475
 
476
fs_CdServices:
477
        dd      fs_CdRead
478
        dd      fs_CdReadFolder
479
        dd      fs_NotImplemented
480
        dd      fs_NotImplemented
481
        dd      fs_NotImplemented
482
        dd      fs_CdGetFileInfo
483
        dd      fs_NotImplemented
484
        dd      0
485
        dd      fs_NotImplemented
486
        dd      fs_NotImplemented
487
fs_NumCdServices = ($ - fs_CdServices)/4
488
 
489
;*******************************************************
490
fs_HasCd0:
3627 Serge 491
        test    byte [DRIVE_DATA+1], 10000000b
492
        setnz   al
2288 clevermous 493
        ret
494
fs_HasCd1:
3627 Serge 495
        test    byte [DRIVE_DATA+1], 00100000b
496
        setnz   al
2288 clevermous 497
        ret
498
fs_HasCd2:
3627 Serge 499
        test    byte [DRIVE_DATA+1], 00001000b
500
        setnz   al
2288 clevermous 501
        ret
502
fs_HasCd3:
3627 Serge 503
        test    byte [DRIVE_DATA+1], 00000010b
504
        setnz   al
2288 clevermous 505
        ret
506
;*******************************************************
507
 
508
; fs_NextXXX functions:
509
; in: eax = partition number, from which start to scan
510
; out: CF=1 => no more partitions
511
;      CF=0 => eax=next partition number
512
 
513
;*******************************************************
514
fs_NextCd:
515
; we always have /cdX/1
516
        test    eax, eax
517
        stc
518
        jnz     @f
519
        mov     al, 1
520
        clc
521
@@:
522
        ret
523
;*******************************************************
524
 
3689 mario79 525
;-----------------------------------------------------------------------------
2288 clevermous 526
process_replace_file_name:
3663 mario79 527
; in
528
; esi - path with filename(f.70)
529
;
530
; out
531
; ebp - full filename
3689 mario79 532
        pushfd
533
        cli
2288 clevermous 534
        mov     ebp, [full_file_name_table]
3689 mario79 535
        xor     edi, edi
2288 clevermous 536
.loop:
3711 clevermous 537
        cmp     edi, [full_file_name_table.size]
3689 mario79 538
        jae     .notfound
2288 clevermous 539
        push    esi edi
3689 mario79 540
        shl     edi, 7 ; edi*128
541
        add     edi, ebp
2288 clevermous 542
@@:
3689 mario79 543
        cmp     byte [edi], 0 ; end of dir_name
2288 clevermous 544
        jz      .dest_done
545
        lodsb
546
        test    al, al
547
        jz      .cont
3689 mario79 548
        or      al, 20h ; 32 - space char
2288 clevermous 549
        scasb
550
        jz      @b
551
        jmp     .cont
552
.dest_done:
553
        cmp     byte [esi], 0
554
        jz      .found
555
        cmp     byte [esi], '/'
556
        jnz     .cont
557
        inc     esi
558
        jmp     .found
559
.cont:
560
        pop     edi esi
3689 mario79 561
        inc     edi
2288 clevermous 562
        jmp     .loop
563
.found:
564
        pop     edi eax
3689 mario79 565
        shl     edi, 7 ; edi*128
566
        add     edi, ebp
2288 clevermous 567
        mov     ebp, esi
568
        cmp     byte [esi], 0
569
        lea     esi, [edi+64]
570
        jnz     .ret
571
.notfound:
572
        xor     ebp, ebp
573
.ret:
3689 mario79 574
        popfd
2288 clevermous 575
        ret
3689 mario79 576
;-----------------------------------------------------------------------------
3663 mario79 577
uglobal
578
lock_flag_for_f30_3 rb 1
579
endg
580
 
2288 clevermous 581
sys_current_directory:
582
;       mov     esi, [current_slot]
583
;       mov     esi, [esi+APPDATA.cur_dir]
584
;       mov     edx, esi
585
 
586
;get length string of appdata.cur_dir
587
        mov     eax, [current_slot]
588
        mov     edi, [eax+APPDATA.cur_dir]
589
 
590
        dec     ebx
591
        jz      .set
592
        dec     ebx
593
        jz      .get
3663 mario79 594
        dec     ebx
595
        jz      .mount_additional_directory
2288 clevermous 596
        ret
3663 mario79 597
 
598
.mount_additional_directory:
599
; sysfunction 30.2: [for app] eax=30,ebx=3,ecx->dir name+dir path (128)
600
; for our code: nothing
601
 
602
; check lock of the function
603
        cmp     [lock_flag_for_f30_3], 1
604
        je      @f
605
 
606
        mov     esi, ecx
607
        mov     edi, sysdir_name1
608
; copying fake directory name
609
        mov     ecx, 63
3711 clevermous 610
        pushfd
611
        cli
3663 mario79 612
        cld
3711 clevermous 613
        rep movsb
3663 mario79 614
; terminator of name, in case if we get the inlet trash
615
        inc     esi
616
        xor     eax, eax
617
        stosb
618
; copying real directory path for mounting
619
        mov     ecx, 63
3711 clevermous 620
        rep movsb
3663 mario79 621
; terminator of name, in case if we get the inlet trash
622
        xor     eax, eax
623
        stosb
624
; increase the pointer of inputs for procedure "process_replace_file_name"
625
        mov     [full_file_name_table.size], 2
626
; block the ability to call f.30.3 because for one session is necessary
627
; for us only once
628
        mov     [lock_flag_for_f30_3], 1
3711 clevermous 629
        popfd
3663 mario79 630
@@:
631
        ret
632
 
2288 clevermous 633
.get:
634
; sysfunction 30.2: [for app] eax=30,ebx=2,ecx->buffer,edx=len
635
; for our code: ebx->buffer,ecx=len
636
max_cur_dir     equ     0x1000
637
 
638
        mov     ebx, edi
639
 
640
        push    ecx
641
        push    edi
642
 
643
        xor     eax, eax
644
        mov     ecx, max_cur_dir
645
 
646
        repne scasb             ;find zerro at and string
647
        jnz     .error          ; no zero in cur_dir: internal error, should not happen
648
 
649
        sub     edi, ebx        ;lenght for copy
650
        inc     edi
651
        mov     [esp+32+8], edi ;return in eax
652
 
653
        cmp     edx, edi
654
        jbe     @f
655
        mov     edx, edi
656
@@:
657
;source string
658
        pop     esi
659
;destination string
660
        pop     edi
661
        cmp     edx, 1
662
        jbe     .ret
663
 
664
        mov     al, '/'         ;start string with '/'
665
        stosb
666
        mov     ecx, edx
667
        rep movsb               ;copy string
668
.ret:
669
        ret
670
 
671
.error:
672
        add     esp, 8
673
        or      dword [esp+32], -1      ;error not found zerro at string ->[eax+APPDATA.cur_dir]
674
        ret
675
.set:
676
; sysfunction 30.1: [for app] eax=30,ebx=1,ecx->string
677
; for our code: ebx->string to set
678
; use generic resolver with APPDATA.cur_dir as destination
679
        push    max_cur_dir     ;0x1000
680
        push    edi     ;destination
681
        mov     ebx, ecx
682
        call    get_full_file_name
683
        ret
684
 
685
; in: ebx = file name, [esp+4] = destination, [esp+8] = sizeof destination
686
; destroys all registers except ebp,esp
687
get_full_file_name:
688
        push    ebp
689
        mov     esi, [current_slot]
690
        mov     esi, [esi+APPDATA.cur_dir]
691
        mov     edx, esi
692
@@:
693
        inc     esi
694
        cmp     byte [esi-1], 0
695
        jnz     @b
696
        dec     esi
697
        cmp     byte [ebx], '/'
698
        jz      .set_absolute
699
; string gives relative path
700
        mov     edi, [esp+8]    ; destination
701
.relative:
702
        cmp     byte [ebx], 0
703
        jz      .set_ok
704
        cmp     word [ebx], '.'
705
        jz      .set_ok
706
        cmp     word [ebx], './'
707
        jnz     @f
708
        add     ebx, 2
709
        jmp     .relative
710
@@:
711
        cmp     word [ebx], '..'
712
        jnz     .doset_relative
713
        cmp     byte [ebx+2], 0
714
        jz      @f
715
        cmp     byte [ebx+2], '/'
716
        jnz     .doset_relative
717
@@:
718
        dec     esi
719
        cmp     byte [esi], '/'
720
        jnz     @b
721
        add     ebx, 3
722
        jmp     .relative
723
.set_ok:
724
        cmp     edx, edi        ; is destination equal to APPDATA.cur_dir?
725
        jz      .set_ok.cur_dir
726
        sub     esi, edx
727
        cmp     esi, [esp+12]
728
        jb      .set_ok.copy
729
.fail:
730
        mov     byte [edi], 0
731
        xor     eax, eax        ; fail
732
        pop     ebp
733
        ret     8
734
.set_ok.copy:
735
        mov     ecx, esi
736
        mov     esi, edx
737
        rep movsb
738
        mov     byte [edi], 0
739
.ret.ok:
740
        mov     al, 1   ; ok
741
        pop     ebp
742
        ret     8
743
.set_ok.cur_dir:
744
        mov     byte [esi], 0
745
        jmp     .ret.ok
746
.doset_relative:
747
        cmp     edx, edi
748
        jz      .doset_relative.cur_dir
749
        sub     esi, edx
750
        cmp     esi, [esp+12]
751
        jae     .fail
752
        mov     ecx, esi
753
        mov     esi, edx
754
        mov     edx, edi
755
        rep movsb
756
        jmp     .doset_relative.copy
757
.doset_relative.cur_dir:
758
        mov     edi, esi
759
.doset_relative.copy:
760
        add     edx, [esp+12]
761
        mov     byte [edi], '/'
762
        inc     edi
763
        cmp     edi, edx
764
        jae     .overflow
765
@@:
766
        mov     al, [ebx]
767
        inc     ebx
768
        stosb
769
        test    al, al
770
        jz      .ret.ok
771
        cmp     edi, edx
772
        jb      @b
773
.overflow:
774
        dec     edi
775
        jmp     .fail
776
.set_absolute:
777
        lea     esi, [ebx+1]
778
        call    process_replace_file_name
779
        mov     edi, [esp+8]
780
        mov     edx, [esp+12]
781
        add     edx, edi
782
.set_copy:
783
        lodsb
784
        stosb
785
        test    al, al
786
        jz      .set_part2
787
.set_copy_cont:
788
        cmp     edi, edx
789
        jb      .set_copy
790
        jmp     .overflow
791
.set_part2:
792
        mov     esi, ebp
793
        xor     ebp, ebp
794
        test    esi, esi
795
        jz      .ret.ok
796
        mov     byte [edi-1], '/'
797
        jmp     .set_copy_cont