Subversion Repositories Kolibri OS

Rev

Rev 3500 | Rev 3725 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 3500 Rev 3626
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
3
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
4
;; Distributed under terms of the GNU General Public License    ;;
4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
5
;;                                                              ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7
 
7
 
8
$Revision: 3500 $
8
$Revision: 3626 $
9
 
9
 
10
ERROR_SUCCESS        = 0
10
ERROR_SUCCESS        = 0
11
ERROR_DISK_BASE      = 1
11
ERROR_DISK_BASE      = 1
12
ERROR_UNSUPPORTED_FS = 2
12
ERROR_UNSUPPORTED_FS = 2
13
ERROR_UNKNOWN_FS     = 3
13
ERROR_UNKNOWN_FS     = 3
14
ERROR_PARTITION      = 4
14
ERROR_PARTITION      = 4
15
ERROR_FILE_NOT_FOUND = 5
15
ERROR_FILE_NOT_FOUND = 5
16
ERROR_END_OF_FILE    = 6
16
ERROR_END_OF_FILE    = 6
17
ERROR_MEMORY_POINTER = 7
17
ERROR_MEMORY_POINTER = 7
18
ERROR_DISK_FULL      = 8
18
ERROR_DISK_FULL      = 8
19
ERROR_FAT_TABLE      = 9 ;deprecated
19
ERROR_FAT_TABLE      = 9 ;deprecated
20
ERROR_FS_FAIL        = 9
20
ERROR_FS_FAIL        = 9
21
ERROR_ACCESS_DENIED  = 10
21
ERROR_ACCESS_DENIED  = 10
22
ERROR_DEVICE         = 11
22
ERROR_DEVICE         = 11
23
 
23
 
24
image_of_eax EQU esp+32
24
image_of_eax EQU esp+32
25
image_of_ebx EQU esp+20
25
image_of_ebx EQU esp+20
26
 
26
 
27
; System function 70 - files with long names (LFN)
27
; System function 70 - files with long names (LFN)
28
; diamond, 2006
28
; diamond, 2006
29
 
29
 
30
iglobal
30
iglobal
31
; in this table names must be in lowercase
31
; in this table names must be in lowercase
32
rootdirs:
32
rootdirs:
33
        db      2,'rd'
33
        db      2,'rd'
34
        dd      fs_OnRamdisk
34
        dd      fs_OnRamdisk
35
        dd      fs_NextRamdisk
35
        dd      fs_NextRamdisk
36
        db      7,'ramdisk'
36
        db      7,'ramdisk'
37
        dd      fs_OnRamdisk
37
        dd      fs_OnRamdisk
38
        dd      fs_NextRamdisk
38
        dd      fs_NextRamdisk
39
        db      2,'fd'
39
        db      2,'fd'
40
        dd      fs_OnFloppy
40
        dd      fs_OnFloppy
41
        dd      fs_NextFloppy
41
        dd      fs_NextFloppy
42
        db      10,'floppydisk'
42
        db      10,'floppydisk'
43
        dd      fs_OnFloppy
43
        dd      fs_OnFloppy
44
        dd      fs_NextFloppy
44
        dd      fs_NextFloppy
45
        db      3,'hd0'
45
        db      3,'hd0'
46
        dd      fs_OnHd0
46
        dd      fs_OnHd0
47
        dd      fs_NextHd0
47
        dd      fs_NextHd0
48
        db      3,'hd1'
48
        db      3,'hd1'
49
        dd      fs_OnHd1
49
        dd      fs_OnHd1
50
        dd      fs_NextHd1
50
        dd      fs_NextHd1
51
        db      3,'hd2'
51
        db      3,'hd2'
52
        dd      fs_OnHd2
52
        dd      fs_OnHd2
53
        dd      fs_NextHd2
53
        dd      fs_NextHd2
54
        db      3,'hd3'
54
        db      3,'hd3'
55
        dd      fs_OnHd3
55
        dd      fs_OnHd3
56
        dd      fs_NextHd3
56
        dd      fs_NextHd3
57
;**********************************************
57
;**********************************************
58
        db      3,'cd0'
58
        db      3,'cd0'
59
        dd      fs_OnCd0
59
        dd      fs_OnCd0
60
        dd      fs_NextCd
60
        dd      fs_NextCd
61
        db      3,'cd1'
61
        db      3,'cd1'
62
        dd      fs_OnCd1
62
        dd      fs_OnCd1
63
        dd      fs_NextCd
63
        dd      fs_NextCd
64
        db      3,'cd2'
64
        db      3,'cd2'
65
        dd      fs_OnCd2
65
        dd      fs_OnCd2
66
        dd      fs_NextCd
66
        dd      fs_NextCd
67
        db      3,'cd3'
67
        db      3,'cd3'
68
        dd      fs_OnCd3
68
        dd      fs_OnCd3
69
        dd      fs_NextCd
69
        dd      fs_NextCd
70
;***********************************************
70
;***********************************************
71
        db      0
71
        db      0
72
 
72
 
73
 
73
 
74
virtual_root_query:
74
virtual_root_query:
75
        dd      fs_HasRamdisk
75
        dd      fs_HasRamdisk
76
        db      'rd',0
76
        db      'rd',0
77
        dd      fs_HasFloppy
77
        dd      fs_HasFloppy
78
        db      'fd',0
78
        db      'fd',0
79
        dd      fs_HasHd0
79
        dd      fs_HasHd0
80
        db      'hd0',0
80
        db      'hd0',0
81
        dd      fs_HasHd1
81
        dd      fs_HasHd1
82
        db      'hd1',0
82
        db      'hd1',0
83
        dd      fs_HasHd2
83
        dd      fs_HasHd2
84
        db      'hd2',0
84
        db      'hd2',0
85
        dd      fs_HasHd3
85
        dd      fs_HasHd3
86
        db      'hd3',0
86
        db      'hd3',0
87
;**********************************************
87
;**********************************************
88
        dd      fs_HasCd0
88
        dd      fs_HasCd0
89
        db      'cd0',0
89
        db      'cd0',0
90
        dd      fs_HasCd1
90
        dd      fs_HasCd1
91
        db      'cd1',0
91
        db      'cd1',0
92
        dd      fs_HasCd2
92
        dd      fs_HasCd2
93
        db      'cd2',0
93
        db      'cd2',0
94
        dd      fs_HasCd3
94
        dd      fs_HasCd3
95
        db      'cd3',0
95
        db      'cd3',0
96
;**********************************************
96
;**********************************************
97
        dd      0
97
        dd      0
98
 
98
 
99
fs_additional_handlers:
99
fs_additional_handlers:
100
        dd      biosdisk_handler, biosdisk_enum_root
100
        dd      biosdisk_handler, biosdisk_enum_root
101
        dd      dyndisk_handler, dyndisk_enum_root
101
        dd      dyndisk_handler, dyndisk_enum_root
102
; add new handlers here
102
; add new handlers here
103
        dd      0
103
        dd      0
104
 
104
 
105
endg
105
endg
106
 
106
 
107
file_system_lfn_protected:
107
file_system_lfn_protected:
108
        pushad
108
        pushad
109
        call    protect_from_terminate
109
        call    protect_from_terminate
110
        call    file_system_lfn
110
        call    file_system_lfn
111
        call    unprotect_from_terminate
111
        call    unprotect_from_terminate
112
        popad
112
        popad
113
        mov     [image_of_eax], eax
113
        mov     [image_of_eax], eax
114
        mov     [image_of_ebx], ebx
114
        mov     [image_of_ebx], ebx
115
        ret
115
        ret
116
 
116
 
117
file_system_lfn:
117
file_system_lfn:
118
; in: ebx->fileinfo block
118
; in: ebx->fileinfo block
119
; operation codes:
119
; operation codes:
120
; 0 : read file
120
; 0 : read file
121
; 1 : read folder
121
; 1 : read folder
122
; 2 : create/rewrite file
122
; 2 : create/rewrite file
123
; 3 : write/append to file
123
; 3 : write/append to file
124
; 4 : set end of file
124
; 4 : set end of file
125
; 5 : get file/directory attributes structure
125
; 5 : get file/directory attributes structure
126
; 6 : set file/directory attributes structure
126
; 6 : set file/directory attributes structure
127
; 7 : start application
127
; 7 : start application
128
; 8 : delete file
128
; 8 : delete file
129
; 9 : create directory
129
; 9 : create directory
130
 
130
 
131
; parse file name
131
; parse file name
132
        lea     esi, [ebx+20]
132
        lea     esi, [ebx+20]
133
        lodsb
133
        lodsb
134
        test    al, al
134
        test    al, al
135
        jnz     @f
135
        jnz     @f
136
        mov     esi, [esi]
136
        mov     esi, [esi]
137
        lodsb
137
        lodsb
138
@@:
138
@@:
139
        cmp     al, '/'
139
        cmp     al, '/'
140
        jz      .notcurdir
140
        jz      .notcurdir
141
        dec     esi
141
        dec     esi
142
        mov     ebp, esi
142
        mov     ebp, esi
143
        test    al, al
143
        test    al, al
144
        jnz     @f
144
        jnz     @f
145
        xor     ebp, ebp
145
        xor     ebp, ebp
146
@@:
146
@@:
147
        mov     esi, [current_slot]
147
        mov     esi, [current_slot]
148
        mov     esi, [esi+APPDATA.cur_dir]
148
        mov     esi, [esi+APPDATA.cur_dir]
149
        jmp     .parse_normal
149
        jmp     .parse_normal
150
.notcurdir:
150
.notcurdir:
151
        cmp     byte [esi], 0
151
        cmp     byte [esi], 0
152
        jz      .rootdir
152
        jz      .rootdir
153
        call    process_replace_file_name
153
        call    process_replace_file_name
154
.parse_normal:
154
.parse_normal:
155
        cmp     dword [ebx], 7
155
        cmp     dword [ebx], 7
156
        jne     @F
156
        jne     @F
157
        mov     edx, [ebx+4]
157
        mov     edx, [ebx+4]
158
        mov     ebx, [ebx+8]
158
        mov     ebx, [ebx+8]
159
        call    fs_execute; esi+ebp, ebx, edx
159
        call    fs_execute; esi+ebp, ebx, edx
160
        mov     [image_of_eax], eax
160
        mov     [image_of_eax], eax
161
        ret
161
        ret
162
@@:
162
@@:
163
        mov     edi, rootdirs-8
163
        mov     edi, rootdirs-8
164
        xor     ecx, ecx
164
        xor     ecx, ecx
165
        push    esi
165
        push    esi
166
.scan1:
166
.scan1:
167
        pop     esi
167
        pop     esi
168
        add     edi, ecx
168
        add     edi, ecx
169
        scasd
169
        scasd
170
        scasd
170
        scasd
171
        mov     cl, byte [edi]
171
        mov     cl, byte [edi]
172
        test    cl, cl
172
        test    cl, cl
173
        jz      .notfound_try
173
        jz      .notfound_try
174
        inc     edi
174
        inc     edi
175
        push    esi
175
        push    esi
176
@@:
176
@@:
177
        lodsb
177
        lodsb
178
        or      al, 20h
178
        or      al, 20h
179
        scasb
179
        scasb
180
        loopz   @b
180
        loopz   @b
181
        jnz     .scan1
181
        jnz     .scan1
182
        lodsb
182
        lodsb
183
        cmp     al, '/'
183
        cmp     al, '/'
184
        jz      .found1
184
        jz      .found1
185
        test    al, al
185
        test    al, al
186
        jnz     .scan1
186
        jnz     .scan1
187
        pop     eax
187
        pop     eax
188
; directory /xxx
188
; directory /xxx
189
.maindir:
189
.maindir:
190
        mov     esi, [edi+4]
190
        mov     esi, [edi+4]
191
.maindir_noesi:
191
.maindir_noesi:
192
        cmp     dword [ebx], 1
192
        cmp     dword [ebx], 1
193
        jnz     .access_denied
193
        jnz     .access_denied
194
        xor     eax, eax
194
        xor     eax, eax
195
        mov     ebp, [ebx+12]                   ;количество блоков для считывания
195
        mov     ebp, [ebx+12]                   ;количество блоков для считывания
196
        mov     edx, [ebx+16]                   ;куда записывать рузельтат
196
        mov     edx, [ebx+16]                   ;куда записывать рузельтат
197
    ;    add     edx, std_application_base_address
197
    ;    add     edx, std_application_base_address
198
        push    dword [ebx+4]   ; first block
198
        push    dword [ebx+4]   ; first block
199
        mov     ebx, [ebx+8]    ; flags
199
        mov     ebx, [ebx+8]    ; flags
200
; ebx=flags, [esp]=first block, ebp=number of blocks, edx=return area, esi='Next' handler
200
; ebx=flags, [esp]=first block, ebp=number of blocks, edx=return area, esi='Next' handler
201
        mov     edi, edx
201
        mov     edi, edx
202
        push    ecx
202
        push    ecx
203
        mov     ecx, 32/4
203
        mov     ecx, 32/4
204
        rep stosd
204
        rep stosd
205
        pop     ecx
205
        pop     ecx
206
        mov     byte [edx], 1   ; version
206
        mov     byte [edx], 1   ; version
207
.maindir_loop:
207
.maindir_loop:
208
        call    esi
208
        call    esi
209
        jc      .maindir_done
209
        jc      .maindir_done
210
        inc     dword [edx+8]
210
        inc     dword [edx+8]
211
        dec     dword [esp]
211
        dec     dword [esp]
212
        jns     .maindir_loop
212
        jns     .maindir_loop
213
        dec     ebp
213
        dec     ebp
214
        js      .maindir_loop
214
        js      .maindir_loop
215
        inc     dword [edx+4]
215
        inc     dword [edx+4]
216
        mov     dword [edi], 0x10       ; attributes: folder
216
        mov     dword [edi], 0x10       ; attributes: folder
217
        mov     dword [edi+4], 1        ; name type: UNICODE
217
        mov     dword [edi+4], 1        ; name type: UNICODE
218
        push    eax
218
        push    eax
219
        xor     eax, eax
219
        xor     eax, eax
220
        add     edi, 8
220
        add     edi, 8
221
        push    ecx
221
        push    ecx
222
        mov     ecx, 40/4-2
222
        mov     ecx, 40/4-2
223
        rep stosd
223
        rep stosd
224
        pop     ecx
224
        pop     ecx
225
        pop     eax
225
        pop     eax
226
        push    eax edx
226
        push    eax edx
227
; convert number in eax to decimal UNICODE string
227
; convert number in eax to decimal UNICODE string
228
        push    edi
228
        push    edi
229
        push    ecx
229
        push    ecx
230
        push    -'0'
230
        push    -'0'
231
        mov     ecx, 10
231
        mov     ecx, 10
232
@@:
232
@@:
233
        xor     edx, edx
233
        xor     edx, edx
234
        div     ecx
234
        div     ecx
235
        push    edx
235
        push    edx
236
        test    eax, eax
236
        test    eax, eax
237
        jnz     @b
237
        jnz     @b
238
@@:
238
@@:
239
        pop     eax
239
        pop     eax
240
        add     al, '0'
240
        add     al, '0'
241
        stosb
241
        stosb
242
        test    bl, 1           ; UNICODE name?
242
        test    bl, 1           ; UNICODE name?
243
        jz      .ansi2
243
        jz      .ansi2
244
        mov     byte [edi], 0
244
        mov     byte [edi], 0
245
        inc     edi
245
        inc     edi
246
.ansi2:
246
.ansi2:
247
        test    al, al
247
        test    al, al
248
        jnz     @b
248
        jnz     @b
249
        mov     byte [edi-1], 0
249
        mov     byte [edi-1], 0
250
        pop     ecx
250
        pop     ecx
251
        pop     edi
251
        pop     edi
252
; UNICODE name length is 520 bytes, ANSI - 264
252
; UNICODE name length is 520 bytes, ANSI - 264
253
        add     edi, 520
253
        add     edi, 520
254
        test    bl, 1
254
        test    bl, 1
255
        jnz     @f
255
        jnz     @f
256
        sub     edi, 520-264
256
        sub     edi, 520-264
257
@@:
257
@@:
258
        pop     edx eax
258
        pop     edx eax
259
        jmp     .maindir_loop
259
        jmp     .maindir_loop
260
.maindir_done:
260
.maindir_done:
261
        pop     eax
261
        pop     eax
262
        mov     ebx, [edx+4]
262
        mov     ebx, [edx+4]
263
        xor     eax, eax
263
        xor     eax, eax
264
        dec     ebp
264
        dec     ebp
265
        js      @f
265
        js      @f
266
        mov     al, ERROR_END_OF_FILE
266
        mov     al, ERROR_END_OF_FILE
267
@@:
267
@@:
268
        mov     [image_of_eax], eax
268
        mov     [image_of_eax], eax
269
        mov     [image_of_ebx], ebx
269
        mov     [image_of_ebx], ebx
270
        ret
270
        ret
271
; directory /
271
; directory /
272
.rootdir:
272
.rootdir:
273
        cmp     dword [ebx], 1  ; read folder?
273
        cmp     dword [ebx], 1  ; read folder?
274
        jz      .readroot
274
        jz      .readroot
275
.access_denied:
275
.access_denied:
276
        mov     dword [image_of_eax], 10      ; access denied
276
        mov     dword [image_of_eax], 10      ; access denied
277
        ret
277
        ret
278
 
278
 
279
.readroot:
279
.readroot:
280
; virtual root folder - special handler
280
; virtual root folder - special handler
281
        mov     esi, virtual_root_query
281
        mov     esi, virtual_root_query
282
        mov     ebp, [ebx+12]
282
        mov     ebp, [ebx+12]
283
        mov     edx, [ebx+16]
283
        mov     edx, [ebx+16]
284
    ;    add     edx, std_application_base_address
284
    ;    add     edx, std_application_base_address
285
        push    dword [ebx+4]   ; first block
285
        push    dword [ebx+4]   ; first block
286
        mov     ebx, [ebx+8]    ; flags
286
        mov     ebx, [ebx+8]    ; flags
287
        xor     eax, eax
287
        xor     eax, eax
288
; eax=0, [esp]=first block, ebx=flags, ebp=number of blocks, edx=return area
288
; eax=0, [esp]=first block, ebx=flags, ebp=number of blocks, edx=return area
289
        mov     edi, edx
289
        mov     edi, edx
290
        mov     ecx, 32/4
290
        mov     ecx, 32/4
291
        rep stosd
291
        rep stosd
292
        mov     byte [edx], 1   ; version
292
        mov     byte [edx], 1   ; version
293
.readroot_loop:
293
.readroot_loop:
294
        cmp     dword [esi], eax
294
        cmp     dword [esi], eax
295
        jz      .readroot_done_static
295
        jz      .readroot_done_static
296
        call    dword [esi]
296
        call    dword [esi]
297
        add     esi, 4
297
        add     esi, 4
298
        test    eax, eax
298
        test    eax, eax
299
        jnz     @f
299
        jnz     @f
300
.readroot_next:
300
.readroot_next:
301
        or      ecx, -1
301
        or      ecx, -1
302
        xchg    esi, edi
302
        xchg    esi, edi
303
        repnz scasb
303
        repnz scasb
304
        xchg    esi, edi
304
        xchg    esi, edi
305
        jmp     .readroot_loop
305
        jmp     .readroot_loop
306
@@:
306
@@:
307
        xor     eax, eax
307
        xor     eax, eax
308
        inc     dword [edx+8]
308
        inc     dword [edx+8]
309
        dec     dword [esp]
309
        dec     dword [esp]
310
        jns     .readroot_next
310
        jns     .readroot_next
311
        dec     ebp
311
        dec     ebp
312
        js      .readroot_next
312
        js      .readroot_next
313
        inc     dword [edx+4]
313
        inc     dword [edx+4]
314
        mov     dword [edi], 0x10       ; attributes: folder
314
        mov     dword [edi], 0x10       ; attributes: folder
315
        mov     dword [edi+4], ebx      ; name type: UNICODE
315
        mov     dword [edi+4], ebx      ; name type: UNICODE
316
        add     edi, 8
316
        add     edi, 8
317
        mov     ecx, 40/4-2
317
        mov     ecx, 40/4-2
318
        rep stosd
318
        rep stosd
319
        push    edi
319
        push    edi
320
@@:
320
@@:
321
        lodsb
321
        lodsb
322
        stosb
322
        stosb
323
        test    bl, 1
323
        test    bl, 1
324
        jz      .ansi
324
        jz      .ansi
325
        mov     byte [edi], 0
325
        mov     byte [edi], 0
326
        inc     edi
326
        inc     edi
327
.ansi:
327
.ansi:
328
        test    eax, eax
328
        test    eax, eax
329
        jnz     @b
329
        jnz     @b
330
        pop     edi
330
        pop     edi
331
        add     edi, 520
331
        add     edi, 520
332
        test    bl, 1
332
        test    bl, 1
333
        jnz     .readroot_loop
333
        jnz     .readroot_loop
334
        sub     edi, 520-264
334
        sub     edi, 520-264
335
        jmp     .readroot_loop
335
        jmp     .readroot_loop
336
.readroot_done_static:
336
.readroot_done_static:
337
        mov     esi, fs_additional_handlers-8
337
        mov     esi, fs_additional_handlers-8
338
        sub     esp, 16
338
        sub     esp, 16
339
.readroot_ah_loop:
339
.readroot_ah_loop:
340
        add     esi, 8
340
        add     esi, 8
341
        cmp     dword [esi], 0
341
        cmp     dword [esi], 0
342
        jz      .readroot_done
342
        jz      .readroot_done
343
        xor     eax, eax
343
        xor     eax, eax
344
.readroot_ah_loop2:
344
.readroot_ah_loop2:
345
        push    edi
345
        push    edi
346
        lea     edi, [esp+4]
346
        lea     edi, [esp+4]
347
        call    dword [esi+4]
347
        call    dword [esi+4]
348
        pop     edi
348
        pop     edi
349
        test    eax, eax
349
        test    eax, eax
350
        jz      .readroot_ah_loop
350
        jz      .readroot_ah_loop
351
        inc     dword [edx+8]
351
        inc     dword [edx+8]
352
        dec     dword [esp+16]
352
        dec     dword [esp+16]
353
        jns     .readroot_ah_loop2
353
        jns     .readroot_ah_loop2
354
        dec     ebp
354
        dec     ebp
355
        js      .readroot_ah_loop2
355
        js      .readroot_ah_loop2
356
        push    eax
356
        push    eax
357
        xor     eax, eax
357
        xor     eax, eax
358
        inc     dword [edx+4]
358
        inc     dword [edx+4]
359
        mov     dword [edi], 0x10       ; attributes: folder
359
        mov     dword [edi], 0x10       ; attributes: folder
360
        mov     dword [edi+4], ebx
360
        mov     dword [edi+4], ebx
361
        add     edi, 8
361
        add     edi, 8
362
        mov     ecx, 40/4-2
362
        mov     ecx, 40/4-2
363
        rep stosd
363
        rep stosd
364
        push    esi edi
364
        push    esi edi
365
        lea     esi, [esp+12]
365
        lea     esi, [esp+12]
366
@@:
366
@@:
367
        lodsb
367
        lodsb
368
        stosb
368
        stosb
369
        test    bl, 1
369
        test    bl, 1
370
        jz      .ansi3
370
        jz      .ansi3
371
        mov     byte [edi], 0
371
        mov     byte [edi], 0
372
        inc     edi
372
        inc     edi
373
.ansi3:
373
.ansi3:
374
        test    al, al
374
        test    al, al
375
        jnz     @b
375
        jnz     @b
376
        pop     edi esi eax
376
        pop     edi esi eax
377
        add     edi, 520
377
        add     edi, 520
378
        test    bl, 1
378
        test    bl, 1
379
        jnz     .readroot_ah_loop2
379
        jnz     .readroot_ah_loop2
380
        sub     edi, 520-264
380
        sub     edi, 520-264
381
        jmp     .readroot_ah_loop2
381
        jmp     .readroot_ah_loop2
382
.readroot_done:
382
.readroot_done:
383
        add     esp, 16
383
        add     esp, 16
384
        pop     eax
384
        pop     eax
385
        mov     ebx, [edx+4]
385
        mov     ebx, [edx+4]
386
        xor     eax, eax
386
        xor     eax, eax
387
        dec     ebp
387
        dec     ebp
388
        js      @f
388
        js      @f
389
        mov     al, ERROR_END_OF_FILE
389
        mov     al, ERROR_END_OF_FILE
390
@@:
390
@@:
391
        mov     [image_of_eax], eax
391
        mov     [image_of_eax], eax
392
        mov     [image_of_ebx], ebx
392
        mov     [image_of_ebx], ebx
393
        ret
393
        ret
394
.notfound_try:
394
.notfound_try:
395
        mov     edi, fs_additional_handlers
395
        mov     edi, fs_additional_handlers
396
@@:
396
@@:
397
        cmp     dword [edi], 0
397
        cmp     dword [edi], 0
398
        jz      .notfound
398
        jz      .notfound
399
        call    dword [edi]
399
        call    dword [edi]
400
        scasd
400
        scasd
401
        scasd
401
        scasd
402
        jmp     @b
402
        jmp     @b
403
.notfound:
403
.notfound:
404
        mov     dword [image_of_eax], ERROR_FILE_NOT_FOUND
404
        mov     dword [image_of_eax], ERROR_FILE_NOT_FOUND
405
        and     dword [image_of_ebx], 0
405
        and     dword [image_of_ebx], 0
406
        ret
406
        ret
407
 
407
 
408
.notfounda:
408
.notfounda:
409
        cmp     edi, esp
409
        cmp     edi, esp
410
        jnz     .notfound
410
        jnz     .notfound
411
        call    dword [edi+4]
411
        call    dword [edi+4]
412
        add     esp, 16
412
        add     esp, 16
413
        jmp     .notfound
413
        jmp     .notfound
414
 
414
 
415
.found1:
415
.found1:
416
        pop     eax
416
        pop     eax
417
        cmp     byte [esi], 0
417
        cmp     byte [esi], 0
418
        jz      .maindir
418
        jz      .maindir
419
.found2:
419
.found2:
420
; read partition number
420
; read partition number
421
        xor     ecx, ecx
421
        xor     ecx, ecx
422
        xor     eax, eax
422
        xor     eax, eax
423
@@:
423
@@:
424
        lodsb
424
        lodsb
425
        cmp     al, '/'
425
        cmp     al, '/'
426
        jz      .done1
426
        jz      .done1
427
        test    al, al
427
        test    al, al
428
        jz      .done1
428
        jz      .done1
429
        sub     al, '0'
429
        sub     al, '0'
430
        cmp     al, 9
430
        cmp     al, 9
431
        ja      .notfounda
431
        ja      .notfounda
432
        lea     ecx, [ecx*5]
432
        lea     ecx, [ecx*5]
433
        lea     ecx, [ecx*2+eax]
433
        lea     ecx, [ecx*2+eax]
434
        jmp     @b
434
        jmp     @b
435
.done1:
435
.done1:
436
        jecxz   .notfounda
436
        jecxz   .notfounda
437
        test    al, al
437
        test    al, al
438
        jnz     @f
438
        jnz     @f
439
        dec     esi
439
        dec     esi
440
@@:
440
@@:
441
        cmp     byte [esi], 0
441
        cmp     byte [esi], 0
442
        jnz     @f
442
        jnz     @f
443
        test    ebp, ebp
443
        test    ebp, ebp
444
        jz      @f
444
        jz      @f
445
        mov     esi, ebp
445
        mov     esi, ebp
446
        xor     ebp, ebp
446
        xor     ebp, ebp
447
@@:
447
@@:
448
; now [edi] contains handler address, ecx - partition number,
448
; now [edi] contains handler address, ecx - partition number,
449
; esi points to ASCIIZ string - rest of name
449
; esi points to ASCIIZ string - rest of name
450
        jmp     dword [edi]
450
        jmp     dword [edi]
451
 
451
 
452
; handlers for devices
452
; handlers for devices
453
; in: ecx = 0 => query virtual directory /xxx
453
; in: ecx = 0 => query virtual directory /xxx
454
; in: ecx = partition number
454
; in: ecx = partition number
455
;     esi -> relative (for device) name
455
;     esi -> relative (for device) name
456
;     ebx -> fileinfo
456
;     ebx -> fileinfo
457
;     ebp = 0 or pointer to rest of name from folder addressed by esi
457
;     ebp = 0 or pointer to rest of name from folder addressed by esi
458
; out: [image_of_eax]=image of eax, [image_of_ebx]=image of ebx
458
; out: [image_of_eax]=image of eax, [image_of_ebx]=image of ebx
459
 
459
 
460
fs_OnRamdisk:
460
fs_OnRamdisk:
461
        cmp     ecx, 1
461
        cmp     ecx, 1
462
        jnz     file_system_lfn.notfound
462
        jnz     file_system_lfn.notfound
463
        mov     eax, [ebx]
463
        mov     eax, [ebx]
464
        cmp     eax, fs_NumRamdiskServices
464
        cmp     eax, fs_NumRamdiskServices
465
        jae     .not_impl
465
        jae     .not_impl
466
        mov     ecx, [ebx+12]
466
        mov     ecx, [ebx+12]
467
        mov     edx, [ebx+16]
467
        mov     edx, [ebx+16]
468
   ;     add     edx, std_application_base_address
468
   ;     add     edx, std_application_base_address
469
        add     ebx, 4
469
        add     ebx, 4
470
        call    dword [fs_RamdiskServices + eax*4]
470
        call    dword [fs_RamdiskServices + eax*4]
471
        mov     [image_of_eax], eax
471
        mov     [image_of_eax], eax
472
        mov     [image_of_ebx], ebx
472
        mov     [image_of_ebx], ebx
473
        ret
473
        ret
474
.not_impl:
474
.not_impl:
475
        mov     dword [image_of_eax], 2       ; not implemented
475
        mov     dword [image_of_eax], 2       ; not implemented
476
        ret
476
        ret
477
 
477
 
478
fs_NotImplemented:
478
fs_NotImplemented:
479
        mov     eax, 2
479
        mov     eax, 2
480
        ret
480
        ret
481
 
481
 
482
fs_RamdiskServices:
482
fs_RamdiskServices:
483
        dd      fs_RamdiskRead
483
        dd      fs_RamdiskRead
484
        dd      fs_RamdiskReadFolder
484
        dd      fs_RamdiskReadFolder
485
        dd      fs_RamdiskRewrite
485
        dd      fs_RamdiskRewrite
486
        dd      fs_RamdiskWrite
486
        dd      fs_RamdiskWrite
487
        dd      fs_RamdiskSetFileEnd
487
        dd      fs_RamdiskSetFileEnd
488
        dd      fs_RamdiskGetFileInfo
488
        dd      fs_RamdiskGetFileInfo
489
        dd      fs_RamdiskSetFileInfo
489
        dd      fs_RamdiskSetFileInfo
490
        dd      0
490
        dd      0
491
        dd      fs_RamdiskDelete
491
        dd      fs_RamdiskDelete
492
        dd      fs_RamdiskCreateFolder
492
        dd      fs_RamdiskCreateFolder
493
fs_NumRamdiskServices = ($ - fs_RamdiskServices)/4
493
fs_NumRamdiskServices = ($ - fs_RamdiskServices)/4
494
 
494
 
495
fs_OnFloppy:
495
fs_OnFloppy:
496
        cmp     ecx, 2
496
        cmp     ecx, 2
497
        ja      file_system_lfn.notfound
497
        ja      file_system_lfn.notfound
498
        mov     eax, [ebx]
498
        mov     eax, [ebx]
499
        cmp     eax, fs_NumFloppyServices
499
        cmp     eax, fs_NumFloppyServices
500
        jae     fs_OnRamdisk.not_impl
500
        jae     fs_OnRamdisk.not_impl
501
        call    reserve_flp
501
        call    reserve_flp
502
        mov     [flp_number], cl
502
        mov     [flp_number], cl
503
        mov     ecx, [ebx+12]
503
        mov     ecx, [ebx+12]
504
        mov     edx, [ebx+16]
504
        mov     edx, [ebx+16]
505
   ;     add     edx, std_application_base_address
505
   ;     add     edx, std_application_base_address
506
        add     ebx, 4
506
        add     ebx, 4
507
        call    dword [fs_FloppyServices + eax*4]
507
        call    dword [fs_FloppyServices + eax*4]
508
        and     [flp_status], 0
508
        and     [flp_status], 0
509
        mov     [image_of_eax], eax
509
        mov     [image_of_eax], eax
510
        mov     [image_of_ebx], ebx
510
        mov     [image_of_ebx], ebx
511
        ret
511
        ret
512
 
512
 
513
fs_FloppyServices:
513
fs_FloppyServices:
514
        dd      fs_FloppyRead
514
        dd      fs_FloppyRead
515
        dd      fs_FloppyReadFolder
515
        dd      fs_FloppyReadFolder
516
        dd      fs_FloppyRewrite
516
        dd      fs_FloppyRewrite
517
        dd      fs_FloppyWrite
517
        dd      fs_FloppyWrite
518
        dd      fs_FloppySetFileEnd
518
        dd      fs_FloppySetFileEnd
519
        dd      fs_FloppyGetFileInfo
519
        dd      fs_FloppyGetFileInfo
520
        dd      fs_FloppySetFileInfo
520
        dd      fs_FloppySetFileInfo
521
        dd      0
521
        dd      0
522
        dd      fs_FloppyDelete
522
        dd      fs_FloppyDelete
523
        dd      fs_FloppyCreateFolder
523
        dd      fs_FloppyCreateFolder
524
fs_NumFloppyServices = ($ - fs_FloppyServices)/4
524
fs_NumFloppyServices = ($ - fs_FloppyServices)/4
525
 
525
 
526
fs_OnHd0:
526
fs_OnHd0:
527
        call    reserve_hd1
527
        call    reserve_hd1
528
        mov     [hdbase], 0x1F0
528
        mov     [hdbase], 0x1F0
529
        mov     [hdid], 0
529
        mov     [hdid], 0
530
        push    1
530
        push    1
531
        jmp     fs_OnHd
531
        jmp     fs_OnHd
532
fs_OnHd1:
532
fs_OnHd1:
533
        call    reserve_hd1
533
        call    reserve_hd1
534
        mov     [hdbase], 0x1F0
534
        mov     [hdbase], 0x1F0
535
        mov     [hdid], 0x10
535
        mov     [hdid], 0x10
536
        push    2
536
        push    2
537
        jmp     fs_OnHd
537
        jmp     fs_OnHd
538
fs_OnHd2:
538
fs_OnHd2:
539
        call    reserve_hd1
539
        call    reserve_hd1
540
        mov     [hdbase], 0x170
540
        mov     [hdbase], 0x170
541
        mov     [hdid], 0
541
        mov     [hdid], 0
542
        push    3
542
        push    3
543
        jmp     fs_OnHd
543
        jmp     fs_OnHd
544
fs_OnHd3:
544
fs_OnHd3:
545
        call    reserve_hd1
545
        call    reserve_hd1
546
        mov     [hdbase], 0x170
546
        mov     [hdbase], 0x170
547
        mov     [hdid], 0x10
547
        mov     [hdid], 0x10
548
        push    4
548
        push    4
549
fs_OnHd:
549
fs_OnHd:
550
        call    reserve_hd_channel
550
        call    reserve_hd_channel
551
        pop     eax
551
        pop     eax
552
        mov     [hdpos], eax
552
        mov     [hdpos], eax
553
        cmp     ecx, 0x100
553
        cmp     ecx, 0x100
554
        jae     fs_OnHdAndBd.nf
554
        jae     fs_OnHdAndBd.nf
555
        cmp     cl, [DRIVE_DATA+1+eax]
555
        cmp     cl, [DRIVE_DATA+1+eax]
556
fs_OnHdAndBd:
556
fs_OnHdAndBd:
557
        jbe     @f
557
        jbe     @f
558
.nf:
558
.nf:
559
        call    free_hd_channel
559
        call    free_hd_channel
560
        and     [hd1_status], 0
560
        and     [hd1_status], 0
561
        mov     dword [image_of_eax], 5       ; not found
561
        mov     dword [image_of_eax], 5       ; not found
562
        ret
562
        ret
563
@@:
563
@@:
564
        mov     [known_part], ecx ;     mov     [fat32part], ecx
564
        mov     [known_part], ecx ;     mov     [fat32part], ecx
565
        push    ebx esi
565
        push    ebx esi
566
        call    choice_necessity_partition_1
566
        call    choice_necessity_partition_1
567
        pop     esi ebx
567
        pop     esi ebx
568
        mov     ecx, [ebx+12]
568
        mov     ecx, [ebx+12]
569
        mov     edx, [ebx+16]
569
        mov     edx, [ebx+16]
570
    ;    add     edx, std_application_base_address
570
    ;    add     edx, std_application_base_address
571
        mov     eax, [ebx]
571
        mov     eax, [ebx]
572
        cmp     eax, fs_NumHdServices
572
        cmp     eax, fs_NumHdServices
573
        jae     .not_impl
573
        jae     .not_impl
574
        add     ebx, 4
574
        add     ebx, 4
575
        call    dword [fs_HdServices + eax*4]
575
        call    dword [fs_HdServices + eax*4]
576
        call    free_hd_channel
576
        call    free_hd_channel
577
        and     [hd1_status], 0
577
        and     [hd1_status], 0
578
        mov     [image_of_eax], eax
578
        mov     [image_of_eax], eax
579
        mov     [image_of_ebx], ebx
579
        mov     [image_of_ebx], ebx
580
        ret
580
        ret
581
.not_impl:
581
.not_impl:
582
        call    free_hd_channel
582
        call    free_hd_channel
583
        and     [hd1_status], 0
583
        and     [hd1_status], 0
584
        mov     dword [image_of_eax], 2       ; not implemented
584
        mov     dword [image_of_eax], 2       ; not implemented
585
        ret
585
        ret
586
 
586
 
587
fs_HdServices:
587
fs_HdServices:
588
        dd      fs_HdRead
588
        dd      fs_HdRead
589
        dd      fs_HdReadFolder
589
        dd      fs_HdReadFolder
590
        dd      fs_HdRewrite
590
        dd      fs_HdRewrite
591
        dd      fs_HdWrite
591
        dd      fs_HdWrite
592
        dd      fs_HdSetFileEnd
592
        dd      fs_HdSetFileEnd
593
        dd      fs_HdGetFileInfo
593
        dd      fs_HdGetFileInfo
594
        dd      fs_HdSetFileInfo
594
        dd      fs_HdSetFileInfo
595
        dd      0
595
        dd      0
596
        dd      fs_HdDelete
596
        dd      fs_HdDelete
597
        dd      fs_HdCreateFolder
597
        dd      fs_HdCreateFolder
598
fs_NumHdServices = ($ - fs_HdServices)/4
598
fs_NumHdServices = ($ - fs_HdServices)/4
599
 
599
 
600
;*******************************************************
600
;*******************************************************
601
fs_OnCd0:
601
fs_OnCd0:
602
        call    reserve_cd
602
        call    reserve_cd
603
        mov     [ChannelNumber], 1
603
        mov     [ChannelNumber], 1
604
        mov     [DiskNumber], 0
604
        mov     [DiskNumber], 0
605
        push    6
605
        push    6
606
        push    1
606
        push    1
607
        jmp     fs_OnCd
607
        jmp     fs_OnCd
608
fs_OnCd1:
608
fs_OnCd1:
609
        call    reserve_cd
609
        call    reserve_cd
610
        mov     [ChannelNumber], 1
610
        mov     [ChannelNumber], 1
611
        mov     [DiskNumber], 1
611
        mov     [DiskNumber], 1
612
        push    4
612
        push    4
613
        push    2
613
        push    2
614
        jmp     fs_OnCd
614
        jmp     fs_OnCd
615
fs_OnCd2:
615
fs_OnCd2:
616
        call    reserve_cd
616
        call    reserve_cd
617
        mov     [ChannelNumber], 2
617
        mov     [ChannelNumber], 2
618
        mov     [DiskNumber], 0
618
        mov     [DiskNumber], 0
619
        push    2
619
        push    2
620
        push    3
620
        push    3
621
        jmp     fs_OnCd
621
        jmp     fs_OnCd
622
fs_OnCd3:
622
fs_OnCd3:
623
        call    reserve_cd
623
        call    reserve_cd
624
        mov     [ChannelNumber], 2
624
        mov     [ChannelNumber], 2
625
        mov     [DiskNumber], 1
625
        mov     [DiskNumber], 1
626
        push    0
626
        push    0
627
        push    4
627
        push    4
628
fs_OnCd:
628
fs_OnCd:
629
        call    reserve_cd_channel
629
        call    reserve_cd_channel
630
        pop     eax
630
        pop     eax
631
        mov     [cdpos], eax
631
        mov     [cdpos], eax
632
        pop     eax
632
        pop     eax
633
        cmp     ecx, 0x100
633
        cmp     ecx, 0x100
634
        jae     .nf
634
        jae     .nf
635
        push    ecx ebx
635
        push    ecx ebx
636
        mov     cl, al
636
        mov     cl, al
637
        mov     bl, [DRIVE_DATA+1]
637
        mov     bl, [DRIVE_DATA+1]
638
        shr     bl, cl
638
        shr     bl, cl
639
        test    bl, 2
639
        test    bl, 2
640
        pop     ebx ecx
640
        pop     ebx ecx
641
 
641
 
642
        jnz     @f
642
        jnz     @f
643
.nf:
643
.nf:
644
        call    free_cd_channel
644
        call    free_cd_channel
645
        and     [cd_status], 0
645
        and     [cd_status], 0
646
        mov     dword [image_of_eax], 5       ; not found
646
        mov     dword [image_of_eax], 5       ; not found
647
        ret
647
        ret
648
@@:
648
@@:
649
        mov     ecx, [ebx+12]
649
        mov     ecx, [ebx+12]
650
        mov     edx, [ebx+16]
650
        mov     edx, [ebx+16]
651
    ;    add     edx, std_application_base_address
651
    ;    add     edx, std_application_base_address
652
        mov     eax, [ebx]
652
        mov     eax, [ebx]
653
        cmp     eax, fs_NumCdServices
653
        cmp     eax, fs_NumCdServices
654
        jae     .not_impl
654
        jae     .not_impl
655
        add     ebx, 4
655
        add     ebx, 4
656
        call    dword [fs_CdServices + eax*4]
656
        call    dword [fs_CdServices + eax*4]
657
        call    free_cd_channel
657
        call    free_cd_channel
658
        and     [cd_status], 0
658
        and     [cd_status], 0
659
        mov     [image_of_eax], eax
659
        mov     [image_of_eax], eax
660
        mov     [image_of_ebx], ebx
660
        mov     [image_of_ebx], ebx
661
        ret
661
        ret
662
.not_impl:
662
.not_impl:
663
        call    free_cd_channel
663
        call    free_cd_channel
664
        and     [cd_status], 0
664
        and     [cd_status], 0
665
        mov     dword [image_of_eax], 2       ; not implemented
665
        mov     dword [image_of_eax], 2       ; not implemented
666
        ret
666
        ret
667
 
667
 
668
fs_CdServices:
668
fs_CdServices:
669
        dd      fs_CdRead
669
        dd      fs_CdRead
670
        dd      fs_CdReadFolder
670
        dd      fs_CdReadFolder
671
        dd      fs_NotImplemented
671
        dd      fs_NotImplemented
672
        dd      fs_NotImplemented
672
        dd      fs_NotImplemented
673
        dd      fs_NotImplemented
673
        dd      fs_NotImplemented
674
        dd      fs_CdGetFileInfo
674
        dd      fs_CdGetFileInfo
675
        dd      fs_NotImplemented
675
        dd      fs_NotImplemented
676
        dd      0
676
        dd      0
677
        dd      fs_NotImplemented
677
        dd      fs_NotImplemented
678
        dd      fs_NotImplemented
678
        dd      fs_NotImplemented
679
fs_NumCdServices = ($ - fs_CdServices)/4
679
fs_NumCdServices = ($ - fs_CdServices)/4
680
 
680
 
681
;*******************************************************
681
;*******************************************************
682
 
682
 
683
fs_HasRamdisk:
683
fs_HasRamdisk:
684
        mov     al, 1   ; we always have ramdisk
684
        mov     al, 1   ; we always have ramdisk
685
        ret
685
        ret
686
 
-
 
687
fs_HasFloppy:
686
fs_HasFloppy:
688
        cmp     byte [DRIVE_DATA], 0
687
        cmp     byte [DRIVE_DATA], 0
689
        setnz   al
688
        setnz   al
690
        ret
689
        ret
691
 
-
 
692
fs_HasHd0:
690
fs_HasHd0:
693
        mov     al, [DRIVE_DATA+1]
691
        test    byte [DRIVE_DATA+1], 01000000b
694
        and     al, 11000000b
-
 
695
        cmp     al, 01000000b
-
 
696
        setz    al
692
        setnz   al
697
        ret
693
        ret
698
fs_HasHd1:
694
fs_HasHd1:
699
        mov     al, [DRIVE_DATA+1]
695
        test    byte [DRIVE_DATA+1], 00010000b
700
        and     al, 00110000b
-
 
701
        cmp     al, 00010000b
-
 
702
        setz    al
696
        setnz   al
703
        ret
697
        ret
704
fs_HasHd2:
698
fs_HasHd2:
705
        mov     al, [DRIVE_DATA+1]
699
        test    byte [DRIVE_DATA+1], 00000100b
706
        and     al, 00001100b
-
 
707
        cmp     al, 00000100b
-
 
708
        setz    al
700
        setnz   al
709
        ret
701
        ret
710
fs_HasHd3:
702
fs_HasHd3:
711
        mov     al, [DRIVE_DATA+1]
703
        test    byte [DRIVE_DATA+1], 00000001b
712
        and     al, 00000011b
-
 
713
        cmp     al, 00000001b
-
 
714
        setz    al
704
        setnz   al
715
        ret
705
        ret
716
 
706
 
717
;*******************************************************
707
;*******************************************************
718
fs_HasCd0:
708
fs_HasCd0:
719
        mov     al, [DRIVE_DATA+1]
709
        test    byte [DRIVE_DATA+1], 10000000b
720
        and     al, 11000000b
-
 
721
        cmp     al, 10000000b
-
 
722
        setz    al
710
        setnz   al
723
        ret
711
        ret
724
fs_HasCd1:
712
fs_HasCd1:
725
        mov     al, [DRIVE_DATA+1]
713
        test    byte [DRIVE_DATA+1], 00100000b
726
        and     al, 00110000b
-
 
727
        cmp     al, 00100000b
-
 
728
        setz    al
714
        setnz   al
729
        ret
715
        ret
730
fs_HasCd2:
716
fs_HasCd2:
731
        mov     al, [DRIVE_DATA+1]
717
        test    byte [DRIVE_DATA+1], 00001000b
732
        and     al, 00001100b
-
 
733
        cmp     al, 00001000b
-
 
734
        setz    al
718
        setnz   al
735
        ret
719
        ret
736
fs_HasCd3:
720
fs_HasCd3:
737
        mov     al, [DRIVE_DATA+1]
721
        test    byte [DRIVE_DATA+1], 00000010b
738
        and     al, 00000011b
-
 
739
        cmp     al, 00000010b
-
 
740
        setz    al
722
        setnz   al
741
        ret
723
        ret
742
;*******************************************************
724
;*******************************************************
743
 
725
 
744
; fs_NextXXX functions:
726
; fs_NextXXX functions:
745
; in: eax = partition number, from which start to scan
727
; in: eax = partition number, from which start to scan
746
; out: CF=1 => no more partitions
728
; out: CF=1 => no more partitions
747
;      CF=0 => eax=next partition number
729
;      CF=0 => eax=next partition number
748
 
730
 
749
fs_NextRamdisk:
731
fs_NextRamdisk:
750
; we always have /rd/1
732
; we always have /rd/1
751
        test    eax, eax
733
        test    eax, eax
752
        stc
734
        stc
753
        jnz     @f
735
        jnz     @f
754
        mov     al, 1
736
        mov     al, 1
755
        clc
737
        clc
756
@@:
738
@@:
757
        ret
739
        ret
758
 
740
 
759
fs_NextFloppy:
741
fs_NextFloppy:
760
; we have /fd/1 iff (([DRIVE_DATA] and 0xF0) != 0) and /fd/2 iff (([DRIVE_DATA] and 0x0F) != 0)
742
; we have /fd/1 iff (([DRIVE_DATA] and 0xF0) != 0) and /fd/2 iff (([DRIVE_DATA] and 0x0F) != 0)
761
        test    byte [DRIVE_DATA], 0xF0
743
        test    byte [DRIVE_DATA], 0xF0
762
        jz      .no1
744
        jz      .no1
763
        test    eax, eax
745
        test    eax, eax
764
        jnz     .no1
746
        jnz     .no1
765
        inc     eax
747
        inc     eax
766
        ret     ; CF cleared
748
        ret     ; CF cleared
767
.no1:
749
.no1:
768
        test    byte [DRIVE_DATA], 0x0F
750
        test    byte [DRIVE_DATA], 0x0F
769
        jz      .no2
751
        jz      .no2
770
        cmp     al, 2
752
        cmp     al, 2
771
        jae     .no2
753
        jae     .no2
772
        mov     al, 2
754
        mov     al, 2
773
        clc
755
        clc
774
        ret
756
        ret
775
.no2:
757
.no2:
776
        stc
758
        stc
777
        ret
759
        ret
778
 
760
 
779
; on hdx, we have partitions from 1 to [0x40002+x]
761
; on hdx, we have partitions from 1 to [0x40002+x]
780
fs_NextHd0:
762
fs_NextHd0:
781
        push    0
763
        push    0
782
        jmp     fs_NextHd
764
        jmp     fs_NextHd
783
fs_NextHd1:
765
fs_NextHd1:
784
        push    1
766
        push    1
785
        jmp     fs_NextHd
767
        jmp     fs_NextHd
786
fs_NextHd2:
768
fs_NextHd2:
787
        push    2
769
        push    2
788
        jmp     fs_NextHd
770
        jmp     fs_NextHd
789
fs_NextHd3:
771
fs_NextHd3:
790
        push    3
772
        push    3
791
fs_NextHd:
773
fs_NextHd:
792
        pop     ecx
774
        pop     ecx
793
        movzx   ecx, byte [DRIVE_DATA+2+ecx]
775
        movzx   ecx, byte [DRIVE_DATA+2+ecx]
794
        cmp     eax, ecx
776
        cmp     eax, ecx
795
        jae     fs_NextFloppy.no2
777
        jae     fs_NextFloppy.no2
796
        inc     eax
778
        inc     eax
797
        clc
779
        clc
798
        ret
780
        ret
799
 
781
 
800
;*******************************************************
782
;*******************************************************
801
fs_NextCd:
783
fs_NextCd:
802
; we always have /cdX/1
784
; we always have /cdX/1
803
        test    eax, eax
785
        test    eax, eax
804
        stc
786
        stc
805
        jnz     @f
787
        jnz     @f
806
        mov     al, 1
788
        mov     al, 1
807
        clc
789
        clc
808
@@:
790
@@:
809
        ret
791
        ret
810
;*******************************************************
792
;*******************************************************
811
 
793
 
812
; Additional FS handlers.
794
; Additional FS handlers.
813
; This handler gets the control each time when fn 70 is called
795
; This handler gets the control each time when fn 70 is called
814
; with unknown item of root subdirectory.
796
; with unknown item of root subdirectory.
815
; in: esi -> name
797
; in: esi -> name
816
;     ebp = 0 or rest of name relative to esi
798
;     ebp = 0 or rest of name relative to esi
817
; out: if the handler processes path, he must not return in file_system_lfn,
799
; out: if the handler processes path, he must not return in file_system_lfn,
818
;      but instead pop return address and return directly to the caller
800
;      but instead pop return address and return directly to the caller
819
;      otherwise simply return
801
;      otherwise simply return
820
 
802
 
821
; here we test for /bd/... - BIOS disks
803
; here we test for /bd/... - BIOS disks
822
biosdisk_handler:
804
biosdisk_handler:
823
        cmp     [NumBiosDisks], 0
805
        cmp     [NumBiosDisks], 0
824
        jz      .ret
806
        jz      .ret
825
        mov     al, [esi]
807
        mov     al, [esi]
826
        or      al, 20h
808
        or      al, 20h
827
        cmp     al, 'b'
809
        cmp     al, 'b'
828
        jnz     .ret
810
        jnz     .ret
829
        mov     al, [esi+1]
811
        mov     al, [esi+1]
830
        or      al, 20h
812
        or      al, 20h
831
        cmp     al, 'd'
813
        cmp     al, 'd'
832
        jnz     .ret
814
        jnz     .ret
833
        push    esi
815
        push    esi
834
        inc     esi
816
        inc     esi
835
        inc     esi
817
        inc     esi
836
        cmp     byte [esi], '0'
818
        cmp     byte [esi], '0'
837
        jb      .ret2
819
        jb      .ret2
838
        cmp     byte [esi], '9'
820
        cmp     byte [esi], '9'
839
        ja      .ret2
821
        ja      .ret2
840
        xor     edx, edx
822
        xor     edx, edx
841
@@:
823
@@:
842
        lodsb
824
        lodsb
843
        test    al, al
825
        test    al, al
844
        jz      .ok
826
        jz      .ok
845
        cmp     al, '/'
827
        cmp     al, '/'
846
        jz      .ok
828
        jz      .ok
847
        sub     al, '0'
829
        sub     al, '0'
848
        cmp     al, 9
830
        cmp     al, 9
849
        ja      .ret2
831
        ja      .ret2
850
        lea     edx, [edx*5]
832
        lea     edx, [edx*5]
851
        lea     edx, [edx*2+eax]
833
        lea     edx, [edx*2+eax]
852
        jmp     @b
834
        jmp     @b
853
.ret2:
835
.ret2:
854
        pop     esi
836
        pop     esi
855
.ret:
837
.ret:
856
        ret
838
        ret
857
.ok:
839
.ok:
858
        cmp     al, '/'
840
        cmp     al, '/'
859
        jz      @f
841
        jz      @f
860
        dec     esi
842
        dec     esi
861
@@:
843
@@:
862
        add     dl, 80h
844
        add     dl, 80h
863
        xor     ecx, ecx
845
        xor     ecx, ecx
864
@@:
846
@@:
865
        cmp     dl, [BiosDisksData+ecx*4]
847
        cmp     dl, [BiosDisksData+ecx*4]
866
        jz      .ok2
848
        jz      .ok2
867
        inc     ecx
849
        inc     ecx
868
        cmp     ecx, [NumBiosDisks]
850
        cmp     ecx, [NumBiosDisks]
869
        jb      @b
851
        jb      @b
870
        jmp     .ret2
852
        jmp     .ret2
871
.ok2:
853
.ok2:
872
        add     esp, 8
854
        add     esp, 8
873
        test    al, al
855
        test    al, al
874
        jnz     @f
856
        jnz     @f
875
        mov     esi, fs_BdNext
857
        mov     esi, fs_BdNext
876
        jmp     file_system_lfn.maindir_noesi
858
        jmp     file_system_lfn.maindir_noesi
877
@@:
859
@@:
878
        push    ecx
860
        push    ecx
879
        push    ecx
861
        push    ecx
880
        push    biosdisk_cleanup
862
        push    biosdisk_cleanup
881
        push    fs_OnBd
863
        push    fs_OnBd
882
        mov     edi, esp
864
        mov     edi, esp
883
        jmp     file_system_lfn.found2
865
        jmp     file_system_lfn.found2
884
 
866
 
885
fs_BdNext:
867
fs_BdNext:
886
        cmp     eax, [BiosDiskPartitions+ecx*4]
868
        cmp     eax, [BiosDiskPartitions+ecx*4]
887
        inc     eax
869
        inc     eax
888
        cmc
870
        cmc
889
biosdisk_cleanup:
871
biosdisk_cleanup:
890
        ret
872
        ret
891
 
873
 
892
fs_OnBd:
874
fs_OnBd:
893
        pop     edx edx edx edx
875
        pop     edx edx edx edx
894
; edx = disk number, ecx = partition number
876
; edx = disk number, ecx = partition number
895
; esi+ebp = name
877
; esi+ebp = name
896
        call    reserve_hd1
878
        call    reserve_hd1
897
        add     edx, 0x80
879
        add     edx, 0x80
898
        mov     [hdpos], edx
880
        mov     [hdpos], edx
899
        cmp     ecx, [BiosDiskPartitions+(edx-0x80)*4]
881
        cmp     ecx, [BiosDiskPartitions+(edx-0x80)*4]
900
        jmp     fs_OnHdAndBd
882
        jmp     fs_OnHdAndBd
901
 
883
 
902
; This handler is called when virtual root is enumerated
884
; This handler is called when virtual root is enumerated
903
; and must return all items which can be handled by this.
885
; and must return all items which can be handled by this.
904
; It is called several times, first time with eax=0
886
; It is called several times, first time with eax=0
905
; in: eax = 0 for first call, previously returned value for subsequent calls
887
; in: eax = 0 for first call, previously returned value for subsequent calls
906
; out: eax = 0 => no more items
888
; out: eax = 0 => no more items
907
;      eax != 0 => buffer pointed to by edi contains name of item
889
;      eax != 0 => buffer pointed to by edi contains name of item
908
 
890
 
909
; here we enumerate existing BIOS disks /bd
891
; here we enumerate existing BIOS disks /bd
910
biosdisk_enum_root:
892
biosdisk_enum_root:
911
        cmp     eax, [NumBiosDisks]
893
        cmp     eax, [NumBiosDisks]
912
        jae     .end
894
        jae     .end
913
        push    eax
895
        push    eax
914
        movzx   eax, byte [BiosDisksData+eax*4]
896
        movzx   eax, byte [BiosDisksData+eax*4]
915
        sub     al, 80h
897
        sub     al, 80h
916
        push    eax
898
        push    eax
917
        mov     al, 'b'
899
        mov     al, 'b'
918
        stosb
900
        stosb
919
        mov     al, 'd'
901
        mov     al, 'd'
920
        stosb
902
        stosb
921
        pop     eax
903
        pop     eax
922
        cmp     al, 10
904
        cmp     al, 10
923
        jae     .big
905
        jae     .big
924
        add     al, '0'
906
        add     al, '0'
925
        stosb
907
        stosb
926
        mov     byte [edi], 0
908
        mov     byte [edi], 0
927
        pop     eax
909
        pop     eax
928
        inc     eax
910
        inc     eax
929
        ret
911
        ret
930
.end:
912
.end:
931
        xor     eax, eax
913
        xor     eax, eax
932
        ret
914
        ret
933
.big:
915
.big:
934
        push    ecx edx
916
        push    ecx edx
935
        push    -'0'
917
        push    -'0'
936
        mov     ecx, 10
918
        mov     ecx, 10
937
@@:
919
@@:
938
        xor     edx, edx
920
        xor     edx, edx
939
        div     ecx
921
        div     ecx
940
        push    edx
922
        push    edx
941
        test    eax, eax
923
        test    eax, eax
942
        jnz     @b
924
        jnz     @b
943
        xchg    eax, edx
925
        xchg    eax, edx
944
@@:
926
@@:
945
        pop     eax
927
        pop     eax
946
        add     al, '0'
928
        add     al, '0'
947
        stosb
929
        stosb
948
        jnz     @b
930
        jnz     @b
949
        pop     edx ecx
931
        pop     edx ecx
950
        pop     eax
932
        pop     eax
951
        inc     eax
933
        inc     eax
952
        ret
934
        ret
953
 
935
 
954
process_replace_file_name:
936
process_replace_file_name:
955
        mov     ebp, [full_file_name_table]
937
        mov     ebp, [full_file_name_table]
956
        mov     edi, [full_file_name_table.size]
938
        mov     edi, [full_file_name_table.size]
957
        dec     edi
939
        dec     edi
958
        shl     edi, 7
940
        shl     edi, 7
959
        add     edi, ebp
941
        add     edi, ebp
960
.loop:
942
.loop:
961
        cmp     edi, ebp
943
        cmp     edi, ebp
962
        jb      .notfound
944
        jb      .notfound
963
        push    esi edi
945
        push    esi edi
964
@@:
946
@@:
965
        cmp     byte [edi], 0
947
        cmp     byte [edi], 0
966
        jz      .dest_done
948
        jz      .dest_done
967
        lodsb
949
        lodsb
968
        test    al, al
950
        test    al, al
969
        jz      .cont
951
        jz      .cont
970
        or      al, 20h
952
        or      al, 20h
971
        scasb
953
        scasb
972
        jz      @b
954
        jz      @b
973
        jmp     .cont
955
        jmp     .cont
974
.dest_done:
956
.dest_done:
975
        cmp     byte [esi], 0
957
        cmp     byte [esi], 0
976
        jz      .found
958
        jz      .found
977
        cmp     byte [esi], '/'
959
        cmp     byte [esi], '/'
978
        jnz     .cont
960
        jnz     .cont
979
        inc     esi
961
        inc     esi
980
        jmp     .found
962
        jmp     .found
981
.cont:
963
.cont:
982
        pop     edi esi
964
        pop     edi esi
983
        sub     edi, 128
965
        sub     edi, 128
984
        jmp     .loop
966
        jmp     .loop
985
.found:
967
.found:
986
        pop     edi eax
968
        pop     edi eax
987
        mov     ebp, esi
969
        mov     ebp, esi
988
        cmp     byte [esi], 0
970
        cmp     byte [esi], 0
989
        lea     esi, [edi+64]
971
        lea     esi, [edi+64]
990
        jnz     .ret
972
        jnz     .ret
991
.notfound:
973
.notfound:
992
        xor     ebp, ebp
974
        xor     ebp, ebp
993
.ret:
975
.ret:
994
        ret
976
        ret
995
 
977
 
996
sys_current_directory:
978
sys_current_directory:
997
;       mov     esi, [current_slot]
979
;       mov     esi, [current_slot]
998
;       mov     esi, [esi+APPDATA.cur_dir]
980
;       mov     esi, [esi+APPDATA.cur_dir]
999
;       mov     edx, esi
981
;       mov     edx, esi
1000
 
982
 
1001
;get length string of appdata.cur_dir
983
;get length string of appdata.cur_dir
1002
        mov     eax, [current_slot]
984
        mov     eax, [current_slot]
1003
        mov     edi, [eax+APPDATA.cur_dir]
985
        mov     edi, [eax+APPDATA.cur_dir]
1004
 
986
 
1005
        dec     ebx
987
        dec     ebx
1006
        jz      .set
988
        jz      .set
1007
        dec     ebx
989
        dec     ebx
1008
        jz      .get
990
        jz      .get
1009
        ret
991
        ret
1010
.get:
992
.get:
1011
; sysfunction 30.2: [for app] eax=30,ebx=2,ecx->buffer,edx=len
993
; sysfunction 30.2: [for app] eax=30,ebx=2,ecx->buffer,edx=len
1012
; for our code: ebx->buffer,ecx=len
994
; for our code: ebx->buffer,ecx=len
1013
max_cur_dir     equ     0x1000
995
max_cur_dir     equ     0x1000
1014
 
996
 
1015
        mov     ebx, edi
997
        mov     ebx, edi
1016
 
998
 
1017
        push    ecx
999
        push    ecx
1018
        push    edi
1000
        push    edi
1019
 
1001
 
1020
        xor     eax, eax
1002
        xor     eax, eax
1021
        mov     ecx, max_cur_dir
1003
        mov     ecx, max_cur_dir
1022
 
1004
 
1023
        repne scasb             ;find zerro at and string
1005
        repne scasb             ;find zerro at and string
1024
        jnz     .error          ; no zero in cur_dir: internal error, should not happen
1006
        jnz     .error          ; no zero in cur_dir: internal error, should not happen
1025
 
1007
 
1026
        sub     edi, ebx        ;lenght for copy
1008
        sub     edi, ebx        ;lenght for copy
1027
        inc     edi
1009
        inc     edi
1028
        mov     [esp+32+8], edi ;return in eax
1010
        mov     [esp+32+8], edi ;return in eax
1029
 
1011
 
1030
        cmp     edx, edi
1012
        cmp     edx, edi
1031
        jbe     @f
1013
        jbe     @f
1032
        mov     edx, edi
1014
        mov     edx, edi
1033
@@:
1015
@@:
1034
;source string
1016
;source string
1035
        pop     esi
1017
        pop     esi
1036
;destination string
1018
;destination string
1037
        pop     edi
1019
        pop     edi
1038
        cmp     edx, 1
1020
        cmp     edx, 1
1039
        jbe     .ret
1021
        jbe     .ret
1040
 
1022
 
1041
        mov     al, '/'         ;start string with '/'
1023
        mov     al, '/'         ;start string with '/'
1042
        stosb
1024
        stosb
1043
        mov     ecx, edx
1025
        mov     ecx, edx
1044
        rep movsb               ;copy string
1026
        rep movsb               ;copy string
1045
.ret:
1027
.ret:
1046
        ret
1028
        ret
1047
 
1029
 
1048
.error:
1030
.error:
1049
        add     esp, 8
1031
        add     esp, 8
1050
        or      dword [esp+32], -1      ;error not found zerro at string ->[eax+APPDATA.cur_dir]
1032
        or      dword [esp+32], -1      ;error not found zerro at string ->[eax+APPDATA.cur_dir]
1051
        ret
1033
        ret
1052
.set:
1034
.set:
1053
; sysfunction 30.1: [for app] eax=30,ebx=1,ecx->string
1035
; sysfunction 30.1: [for app] eax=30,ebx=1,ecx->string
1054
; for our code: ebx->string to set
1036
; for our code: ebx->string to set
1055
; use generic resolver with APPDATA.cur_dir as destination
1037
; use generic resolver with APPDATA.cur_dir as destination
1056
        push    max_cur_dir     ;0x1000
1038
        push    max_cur_dir     ;0x1000
1057
        push    edi     ;destination
1039
        push    edi     ;destination
1058
        mov     ebx, ecx
1040
        mov     ebx, ecx
1059
        call    get_full_file_name
1041
        call    get_full_file_name
1060
        ret
1042
        ret
1061
 
1043
 
1062
; in: ebx = file name, [esp+4] = destination, [esp+8] = sizeof destination
1044
; in: ebx = file name, [esp+4] = destination, [esp+8] = sizeof destination
1063
; destroys all registers except ebp,esp
1045
; destroys all registers except ebp,esp
1064
get_full_file_name:
1046
get_full_file_name:
1065
        push    ebp
1047
        push    ebp
1066
        mov     esi, [current_slot]
1048
        mov     esi, [current_slot]
1067
        mov     esi, [esi+APPDATA.cur_dir]
1049
        mov     esi, [esi+APPDATA.cur_dir]
1068
        mov     edx, esi
1050
        mov     edx, esi
1069
@@:
1051
@@:
1070
        inc     esi
1052
        inc     esi
1071
        cmp     byte [esi-1], 0
1053
        cmp     byte [esi-1], 0
1072
        jnz     @b
1054
        jnz     @b
1073
        dec     esi
1055
        dec     esi
1074
        cmp     byte [ebx], '/'
1056
        cmp     byte [ebx], '/'
1075
        jz      .set_absolute
1057
        jz      .set_absolute
1076
; string gives relative path
1058
; string gives relative path
1077
        mov     edi, [esp+8]    ; destination
1059
        mov     edi, [esp+8]    ; destination
1078
.relative:
1060
.relative:
1079
        cmp     byte [ebx], 0
1061
        cmp     byte [ebx], 0
1080
        jz      .set_ok
1062
        jz      .set_ok
1081
        cmp     word [ebx], '.'
1063
        cmp     word [ebx], '.'
1082
        jz      .set_ok
1064
        jz      .set_ok
1083
        cmp     word [ebx], './'
1065
        cmp     word [ebx], './'
1084
        jnz     @f
1066
        jnz     @f
1085
        add     ebx, 2
1067
        add     ebx, 2
1086
        jmp     .relative
1068
        jmp     .relative
1087
@@:
1069
@@:
1088
        cmp     word [ebx], '..'
1070
        cmp     word [ebx], '..'
1089
        jnz     .doset_relative
1071
        jnz     .doset_relative
1090
        cmp     byte [ebx+2], 0
1072
        cmp     byte [ebx+2], 0
1091
        jz      @f
1073
        jz      @f
1092
        cmp     byte [ebx+2], '/'
1074
        cmp     byte [ebx+2], '/'
1093
        jnz     .doset_relative
1075
        jnz     .doset_relative
1094
@@:
1076
@@:
1095
        dec     esi
1077
        dec     esi
1096
        cmp     byte [esi], '/'
1078
        cmp     byte [esi], '/'
1097
        jnz     @b
1079
        jnz     @b
1098
        add     ebx, 3
1080
        add     ebx, 3
1099
        jmp     .relative
1081
        jmp     .relative
1100
.set_ok:
1082
.set_ok:
1101
        cmp     edx, edi        ; is destination equal to APPDATA.cur_dir?
1083
        cmp     edx, edi        ; is destination equal to APPDATA.cur_dir?
1102
        jz      .set_ok.cur_dir
1084
        jz      .set_ok.cur_dir
1103
        sub     esi, edx
1085
        sub     esi, edx
1104
        cmp     esi, [esp+12]
1086
        cmp     esi, [esp+12]
1105
        jb      .set_ok.copy
1087
        jb      .set_ok.copy
1106
.fail:
1088
.fail:
1107
        mov     byte [edi], 0
1089
        mov     byte [edi], 0
1108
        xor     eax, eax        ; fail
1090
        xor     eax, eax        ; fail
1109
        pop     ebp
1091
        pop     ebp
1110
        ret     8
1092
        ret     8
1111
.set_ok.copy:
1093
.set_ok.copy:
1112
        mov     ecx, esi
1094
        mov     ecx, esi
1113
        mov     esi, edx
1095
        mov     esi, edx
1114
        rep movsb
1096
        rep movsb
1115
        mov     byte [edi], 0
1097
        mov     byte [edi], 0
1116
.ret.ok:
1098
.ret.ok:
1117
        mov     al, 1   ; ok
1099
        mov     al, 1   ; ok
1118
        pop     ebp
1100
        pop     ebp
1119
        ret     8
1101
        ret     8
1120
.set_ok.cur_dir:
1102
.set_ok.cur_dir:
1121
        mov     byte [esi], 0
1103
        mov     byte [esi], 0
1122
        jmp     .ret.ok
1104
        jmp     .ret.ok
1123
.doset_relative:
1105
.doset_relative:
1124
        cmp     edx, edi
1106
        cmp     edx, edi
1125
        jz      .doset_relative.cur_dir
1107
        jz      .doset_relative.cur_dir
1126
        sub     esi, edx
1108
        sub     esi, edx
1127
        cmp     esi, [esp+12]
1109
        cmp     esi, [esp+12]
1128
        jae     .fail
1110
        jae     .fail
1129
        mov     ecx, esi
1111
        mov     ecx, esi
1130
        mov     esi, edx
1112
        mov     esi, edx
1131
        mov     edx, edi
1113
        mov     edx, edi
1132
        rep movsb
1114
        rep movsb
1133
        jmp     .doset_relative.copy
1115
        jmp     .doset_relative.copy
1134
.doset_relative.cur_dir:
1116
.doset_relative.cur_dir:
1135
        mov     edi, esi
1117
        mov     edi, esi
1136
.doset_relative.copy:
1118
.doset_relative.copy:
1137
        add     edx, [esp+12]
1119
        add     edx, [esp+12]
1138
        mov     byte [edi], '/'
1120
        mov     byte [edi], '/'
1139
        inc     edi
1121
        inc     edi
1140
        cmp     edi, edx
1122
        cmp     edi, edx
1141
        jae     .overflow
1123
        jae     .overflow
1142
@@:
1124
@@:
1143
        mov     al, [ebx]
1125
        mov     al, [ebx]
1144
        inc     ebx
1126
        inc     ebx
1145
        stosb
1127
        stosb
1146
        test    al, al
1128
        test    al, al
1147
        jz      .ret.ok
1129
        jz      .ret.ok
1148
        cmp     edi, edx
1130
        cmp     edi, edx
1149
        jb      @b
1131
        jb      @b
1150
.overflow:
1132
.overflow:
1151
        dec     edi
1133
        dec     edi
1152
        jmp     .fail
1134
        jmp     .fail
1153
.set_absolute:
1135
.set_absolute:
1154
        lea     esi, [ebx+1]
1136
        lea     esi, [ebx+1]
1155
        call    process_replace_file_name
1137
        call    process_replace_file_name
1156
        mov     edi, [esp+8]
1138
        mov     edi, [esp+8]
1157
        mov     edx, [esp+12]
1139
        mov     edx, [esp+12]
1158
        add     edx, edi
1140
        add     edx, edi
1159
.set_copy:
1141
.set_copy:
1160
        lodsb
1142
        lodsb
1161
        stosb
1143
        stosb
1162
        test    al, al
1144
        test    al, al
1163
        jz      .set_part2
1145
        jz      .set_part2
1164
.set_copy_cont:
1146
.set_copy_cont:
1165
        cmp     edi, edx
1147
        cmp     edi, edx
1166
        jb      .set_copy
1148
        jb      .set_copy
1167
        jmp     .overflow
1149
        jmp     .overflow
1168
.set_part2:
1150
.set_part2:
1169
        mov     esi, ebp
1151
        mov     esi, ebp
1170
        xor     ebp, ebp
1152
        xor     ebp, ebp
1171
        test    esi, esi
1153
        test    esi, esi
1172
        jz      .ret.ok
1154
        jz      .ret.ok
1173
        mov     byte [edi-1], '/'
1155
        mov     byte [edi-1], '/'
1174
        jmp     .set_copy_cont
1156
        jmp     .set_copy_cont