Subversion Repositories Kolibri OS

Rev

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

Rev 8985 Rev 8986
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2004-2016. All rights reserved. ;;
3
;; Copyright (C) KolibriOS team 2004-2016. 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: 8914 $
8
$Revision: 8986 $
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_FS_FAIL        = 9
19
ERROR_FS_FAIL        = 9
20
ERROR_ACCESS_DENIED  = 10
20
ERROR_ACCESS_DENIED  = 10
21
ERROR_DEVICE         = 11
21
ERROR_DEVICE         = 11
22
ERROR_OUT_OF_MEMORY  = 12
22
ERROR_OUT_OF_MEMORY  = 12
23
 
23
 
24
maxPathLength = 1000h
24
maxPathLength = 1000h
25
 
25
 
26
image_of_eax EQU esp+32
26
image_of_eax EQU esp+32
27
image_of_ebx EQU esp+20
27
image_of_ebx EQU esp+20
28
 
28
 
29
; ; System function 70 security check
29
; ; System function 70 security check
30
; align 4
30
; align 4
31
; proc file_system_is_operation_safe stdcall, inf_struct_ptr: dword
31
; proc file_system_is_operation_safe stdcall, inf_struct_ptr: dword
32
; ; in:
32
; ; in:
33
; ;      inf_struct_ptr = pointer to information structure was given to sysfn70
33
; ;      inf_struct_ptr = pointer to information structure was given to sysfn70
34
; ; out: ZF = 1 if operation is safe
34
; ; out: ZF = 1 if operation is safe
35
; ;      ZF = 0 if operation can cause kernel crash
35
; ;      ZF = 0 if operation can cause kernel crash
36
;         push    ebx ecx edx
36
;         push    ebx ecx edx
37
;         xor     ecx, ecx ; ecx - length of target buffer
37
;         xor     ecx, ecx ; ecx - length of target buffer
38
 
38
 
39
;         mov     ebx, [inf_struct_ptr]
39
;         mov     ebx, [inf_struct_ptr]
40
;         mov     edx, [ebx + 16] ; base of target buffer
40
;         mov     edx, [ebx + 16] ; base of target buffer
41
 
41
 
42
;         cmp     dword [ebx], 0 ; if 70.0
42
;         cmp     dword [ebx], 0 ; if 70.0
43
;         jnz     .case1
43
;         jnz     .case1
44
;         mov     ecx, dword [ebx + 12]
44
;         mov     ecx, dword [ebx + 12]
45
;         jmp     .end_switch
45
;         jmp     .end_switch
46
 
46
 
47
; .case1:
47
; .case1:
48
;         cmp     dword [ebx], 1 ; if 70.1
48
;         cmp     dword [ebx], 1 ; if 70.1
49
;         jnz     .case2_3
49
;         jnz     .case2_3
50
;         ;mov     ecx, 32
50
;         ;mov     ecx, 32
51
;         cmp     dword [ebx + 8], 1 ; check encoding
51
;         cmp     dword [ebx + 8], 1 ; check encoding
52
;         jbe     .case1_304 ; if encdoing <= 1 i.e cpp866 
52
;         jbe     .case1_304 ; if encdoing <= 1 i.e cpp866 
53
;         mov     ecx, 560 ; if unicode then bdvk block len is 560 bytes
53
;         mov     ecx, 560 ; if unicode then bdvk block len is 560 bytes
54
;         jmp     .case1_end
54
;         jmp     .case1_end
55
; .case1_304:
55
; .case1_304:
56
;         mov     ecx, 304 ; if cp866 then bdvk block len is 304 bytes
56
;         mov     ecx, 304 ; if cp866 then bdvk block len is 304 bytes
57
; .case1_end:
57
; .case1_end:
58
;         imul    ecx, dword [ebx + 12] ; multiply bdvk length by their count
58
;         imul    ecx, dword [ebx + 12] ; multiply bdvk length by their count
59
;         add     ecx, 32 ; add result header len
59
;         add     ecx, 32 ; add result header len
60
;         jmp     .end_switch
60
;         jmp     .end_switch
61
 
61
 
62
; .case2_3:
62
; .case2_3:
63
;         cmp     dword [ebx], 3
63
;         cmp     dword [ebx], 3
64
;         ja      .case5 ; if subfn > 3
64
;         ja      .case5 ; if subfn > 3
65
;         mov     ecx, dword [ebx + 12]
65
;         mov     ecx, dword [ebx + 12]
66
;         jmp     .end_switch
66
;         jmp     .end_switch
67
 
67
 
68
; .case5:
68
; .case5:
69
;         cmp     dword [ebx], 5
69
;         cmp     dword [ebx], 5
70
;         jnz     .case6
70
;         jnz     .case6
71
;         mov     ecx, 40
71
;         mov     ecx, 40
72
;         jmp     .end_switch
72
;         jmp     .end_switch
73
 
73
 
74
; .case6:
74
; .case6:
75
;         cmp     dword [ebx], 6
75
;         cmp     dword [ebx], 6
76
;         jnz     .switch_none
76
;         jnz     .switch_none
77
;         mov     ecx, 32
77
;         mov     ecx, 32
78
;         jmp     .end_switch
78
;         jmp     .end_switch
79
 
79
 
80
; .switch_none:
80
; .switch_none:
81
;         mov     ecx, 1
81
;         mov     ecx, 1
82
;         test    ecx, ecx
82
;         test    ecx, ecx
83
;         jmp     .ret
83
;         jmp     .ret
84
        
84
        
85
; .end_switch:
85
; .end_switch:
86
;         ;;
86
;         ;;
87
;         stdcall is_region_userspace, edx, ecx
87
;         stdcall is_region_userspace, edx, ecx
88
; .ret:
88
; .ret:
89
;         pop     edx ecx ebx
89
;         pop     edx ecx ebx
90
;         ret
90
;         ret
91
; endp
91
; endp
92
 
92
 
93
; syscall_fileSystemUnicode: ; with user pointer correctness checking
93
; syscall_syscall_fs_diff_encodings: ; with user pointer correctness checking
94
; ; in: ebx -> f.80 parameter structure
94
; ; in: ebx -> f.80 parameter structure
95
;         stdcall file_system_is_operation_safe, ebx
95
;         stdcall file_system_is_operation_safe, ebx
96
;         jnz     @f
96
;         jnz     @f
97
 
97
 
98
;         DEBUGF  1, "sysfn80 addr error\n"
98
;         DEBUGF  1, "sysfn80 addr error\n"
99
;         mov     dword [image_of_eax], ERROR_MEMORY_POINTER
99
;         mov     dword [image_of_eax], ERROR_MEMORY_POINTER
100
;         ret
100
;         ret
101
; @@:
101
; @@:
102
;         jmp     fileSystemUnicode
102
;         jmp     syscall_fs_diff_encodings
103
 
103
 
104
; temporarily commented out cause acpi driver (drivers/devman) uses sysfn70 via 0x40
104
; temporarily commented out cause acpi driver (drivers/devman) uses sysfn70 via 0x40
105
; so because drivers it kernel space, pointer checking fails
105
; so because drivers it kernel space, pointer checking fails
106
; TODO solution: add filesystem functions without pointer checking to kernel exports
106
; TODO solution: add filesystem functions without pointer checking to kernel exports
107
; and make the driver use them, not int 0x40
107
; and make the driver use them, not int 0x40
108
; syscall_fileSystemUnicode commented out for the same reason
108
; syscall_syscall_fs_diff_encodings commented out for the same reason
109
; syscall_file_system_lfn: ; with user pointer correctness checking
109
; syscall_file_system_lfn: ; with user pointer correctness checking
110
; ; in: ebx -> f.70 parameter structure
110
; ; in: ebx -> f.70 parameter structure
111
;         stdcall file_system_is_operation_safe, ebx
111
;         stdcall file_system_is_operation_safe, ebx
112
;         jnz     @f
112
;         jnz     @f
113
 
113
 
114
;         DEBUGF  1, "sysfn70 addr error\n"
114
;         DEBUGF  1, "sysfn70 addr error\n"
115
;         mov     dword [image_of_eax], ERROR_MEMORY_POINTER
115
;         mov     dword [image_of_eax], ERROR_MEMORY_POINTER
116
;         ret
116
;         ret
117
; @@:
117
; @@:
118
;         jmp     file_system_lfn
118
;         jmp     syscall_file_system_lfn
119
 
119
 
120
 
120
 
121
; System function 70
121
; System function 70
122
 
122
 
123
file_system_lfn_protected:
123
syscall_file_system_lfn_protected:
124
        pushad
124
        pushad
125
        call    protect_from_terminate
125
        call    protect_from_terminate
126
        call    file_system_lfn
126
        call    syscall_file_system_lfn
127
        call    unprotect_from_terminate
127
        call    unprotect_from_terminate
128
        popad
128
        popad
129
        mov     [image_of_eax], eax
129
        mov     [image_of_eax], eax
130
        mov     [image_of_ebx], ebx
130
        mov     [image_of_ebx], ebx
131
        ret
131
        ret
132
 
132
 
133
fileSystemUnicode:
133
syscall_fs_diff_encodings:
134
; in: ebx -> f.80 parameter structure
134
; in: ebx -> f.80 parameter structure
135
        mov     edi, [ebx+20]
135
        mov     edi, [ebx+20]
136
        mov     esi, [ebx+24]
136
        mov     esi, [ebx+24]
137
        jmp     @f
137
        jmp     @f
138
 
138
 
139
file_system_lfn:
139
syscall_file_system_lfn:
140
; in: ebx -> f.70 parameter structure
140
; in: ebx -> f.70 parameter structure
141
        xor     edi, edi
141
        xor     edi, edi
142
        lea     esi, [ebx+20]
142
        lea     esi, [ebx+20]
143
        cmp     byte [esi], 0
143
        cmp     byte [esi], 0
144
        jnz     @f
144
        jnz     @f
145
        mov     esi, [ebx+21]
145
        mov     esi, [ebx+21]
146
@@:
146
@@:
147
        cmp     word [esi], '/'
147
        cmp     word [esi], '/'
148
        jnz     @f
148
        jnz     @f
149
        cmp     edi, 2
149
        cmp     edi, 2
150
        jnz     .rootdir
150
        jnz     .rootdir
151
        cmp     dword[esi], '/'
151
        cmp     dword[esi], '/'
152
        jz      .rootdir
152
        jz      .rootdir
153
@@:
153
@@:
154
        stdcall kernel_alloc, maxPathLength
154
        stdcall kernel_alloc, maxPathLength
155
        push    eax ebx
155
        push    eax ebx
156
        xchg    eax, edi
156
        xchg    eax, edi
157
        call    getFullPath
157
        call    getFullPath
158
        pop     ebx ebp
158
        pop     ebx ebp
159
        test    eax, eax
159
        test    eax, eax
160
        jz      .notfound
160
        jz      .notfound
161
        cmp     dword[ebx], 7   ; start application
161
        cmp     dword[ebx], 7   ; start application
162
        jnz     @f
162
        jnz     @f
163
        mov     edx, [ebx+4]
163
        mov     edx, [ebx+4]
164
        mov     ecx, [ebx+8]
164
        mov     ecx, [ebx+8]
165
        mov     ebx, ebp
165
        mov     ebx, ebp
166
        call    fs_execute
166
        call    fs_execute
167
        mov     [image_of_eax], eax
167
        mov     [image_of_eax], eax
168
        ret
168
        ret
169
 
169
 
170
@@:
170
@@:
171
        lea     esi, [ebp+2]
171
        lea     esi, [ebp+2]
172
        mov     ax, [esi]
172
        mov     ax, [esi]
173
        or      ax, 2020h
173
        or      ax, 2020h
174
        cmp     ax, 'cd'
174
        cmp     ax, 'cd'
175
        jz      .CD
175
        jz      .CD
176
        call    dyndisk_handler ; not returns if success
176
        call    dyndisk_handler ; not returns if success
177
.notfound:
177
.notfound:
178
        stdcall kernel_free, ebp
178
        stdcall kernel_free, ebp
179
        mov     dword[image_of_eax], ERROR_FILE_NOT_FOUND
179
        mov     dword[image_of_eax], ERROR_FILE_NOT_FOUND
180
        ret
180
        ret
181
 
181
 
182
.CD:
182
.CD:
183
        add     esi, 2
183
        add     esi, 2
184
        xor     eax, eax
184
        xor     eax, eax
185
        lodsb       ; disk number
185
        lodsb       ; disk number
186
        sub     eax, '0'
186
        sub     eax, '0'
187
        cmp     eax, 10
187
        cmp     eax, 10
188
        jnc     .notfound
188
        jnc     .notfound
189
        mov     edi, eax
189
        mov     edi, eax
190
        lodsb
190
        lodsb
191
        test    eax, eax
191
        test    eax, eax
192
        jz      .maindir
192
        jz      .maindir
193
        cmp     al, '/'
193
        cmp     al, '/'
194
        jnz     .notfound
194
        jnz     .notfound
195
        lodsb       ; partition number
195
        lodsb       ; partition number
196
        test    eax, eax
196
        test    eax, eax
197
        jz      .maindir
197
        jz      .maindir
198
        cmp     al, '1'
198
        cmp     al, '1'
199
        jnz     .notfound
199
        jnz     .notfound
200
        cmp     byte [esi], '/'
200
        cmp     byte [esi], '/'
201
        jnz     @f
201
        jnz     @f
202
        inc     esi
202
        inc     esi
203
@@:
203
@@:
204
        call    reserve_cd
204
        call    reserve_cd
205
        mov     eax, edi
205
        mov     eax, edi
206
        bt      eax, 0
206
        bt      eax, 0
207
        setc    [DiskNumber]
207
        setc    [DiskNumber]
208
        bt      eax, 1
208
        bt      eax, 1
209
        setc    [ChannelNumber]
209
        setc    [ChannelNumber]
210
        inc     [ChannelNumber]
210
        inc     [ChannelNumber]
211
        inc     eax
211
        inc     eax
212
        mov     [cdpos], eax
212
        mov     [cdpos], eax
213
        call    reserve_cd_channel
213
        call    reserve_cd_channel
214
        mov     eax, edi
214
        mov     eax, edi
215
        not     eax
215
        not     eax
216
        and     eax, 3
216
        and     eax, 3
217
        shl     eax, 1
217
        shl     eax, 1
218
        inc     eax
218
        inc     eax
219
        shr     edi, 2
219
        shr     edi, 2
220
        mov     dword[image_of_eax], ERROR_FILE_NOT_FOUND
220
        mov     dword[image_of_eax], ERROR_FILE_NOT_FOUND
221
        bt      [edi*5+DRIVE_DATA+1], ax
221
        bt      [edi*5+DRIVE_DATA+1], ax
222
        jnc     @f
222
        jnc     @f
223
        mov     ecx, [ebx+12]
223
        mov     ecx, [ebx+12]
224
        mov     edx, [ebx+16]
224
        mov     edx, [ebx+16]
225
        mov     eax, [ebx]
225
        mov     eax, [ebx]
226
        mov     dword[image_of_eax], ERROR_UNSUPPORTED_FS
226
        mov     dword[image_of_eax], ERROR_UNSUPPORTED_FS
227
        cmp     eax, fs_NumCdServices
227
        cmp     eax, fs_NumCdServices
228
        jae     @f
228
        jae     @f
229
        add     ebx, 4
229
        add     ebx, 4
230
        push    ebp
230
        push    ebp
231
        call    dword[fs_CdServices + eax*4]
231
        call    dword[fs_CdServices + eax*4]
232
        pop     ebp
232
        pop     ebp
233
        mov     [image_of_eax], eax
233
        mov     [image_of_eax], eax
234
        mov     [image_of_ebx], ebx
234
        mov     [image_of_ebx], ebx
235
@@:
235
@@:
236
        call    free_cd_channel
236
        call    free_cd_channel
237
        and     [cd_status], 0
237
        and     [cd_status], 0
238
        stdcall kernel_free, ebp
238
        stdcall kernel_free, ebp
239
        ret
239
        ret
240
 
240
 
241
.nextCD:
241
.nextCD:
242
        test    eax, eax    ; partition number
242
        test    eax, eax    ; partition number
243
        jnz     @f
243
        jnz     @f
244
        inc     eax     ; /cdX/1
244
        inc     eax     ; /cdX/1
245
        ret
245
        ret
246
 
246
 
247
@@:
247
@@:
248
        stc
248
        stc
249
        ret
249
        ret
250
 
250
 
251
.maindir:   ; list partitions
251
.maindir:   ; list partitions
252
        mov     esi, .nextCD
252
        mov     esi, .nextCD
253
        xor     ecx, ecx
253
        xor     ecx, ecx
254
.maindir_noesi:     ; backjump from dyndisk_handler
254
.maindir_noesi:     ; backjump from dyndisk_handler
255
        push    ebp
255
        push    ebp
256
        mov     ebp, ecx
256
        mov     ebp, ecx
257
        call    kernel_free
257
        call    kernel_free
258
        mov     edi, [ebx+16]   ; buffer
258
        mov     edi, [ebx+16]   ; buffer
259
        cmp     byte [ebx], 5
259
        cmp     byte [ebx], 5
260
        jz      .deviceInfo
260
        jz      .deviceInfo
261
        cmp     byte [ebx], 1   ; read folder?
261
        cmp     byte [ebx], 1   ; read folder?
262
        jnz     .access_denied
262
        jnz     .access_denied
263
        push    ebp
263
        push    ebp
264
        pushd   [ebx+4]         ; first block
264
        pushd   [ebx+4]         ; first block
265
        mov     ebp, [ebx+12]   ; the number of blocks to read
265
        mov     ebp, [ebx+12]   ; the number of blocks to read
266
        mov     ebx, [ebx+8]    ; flags
266
        mov     ebx, [ebx+8]    ; flags
267
        mov     ecx, 32/4
267
        mov     ecx, 32/4
268
        mov     edx, edi
268
        mov     edx, edi
269
        xor     eax, eax
269
        xor     eax, eax
270
        rep stosd
270
        rep stosd
271
        mov     byte [edx], 1   ; version
271
        mov     byte [edx], 1   ; version
272
.maindir_loop:
272
.maindir_loop:
273
        call    esi
273
        call    esi
274
        jc      .maindir_done
274
        jc      .maindir_done
275
        inc     dword[edx+8]
275
        inc     dword[edx+8]
276
        dec     dword[esp]
276
        dec     dword[esp]
277
        jns     .maindir_loop
277
        jns     .maindir_loop
278
        dec     ebp
278
        dec     ebp
279
        js      .maindir_loop
279
        js      .maindir_loop
280
        inc     dword[edx+4]
280
        inc     dword[edx+4]
281
        mov     dword[edi], 16      ; attributes: folder
281
        mov     dword[edi], 16      ; attributes: folder
282
        mov     dword[edi+4], ebx   ; name encoding
282
        mov     dword[edi+4], ebx   ; name encoding
283
        push    eax
283
        push    eax
284
        mov     ecx, 32/4
284
        mov     ecx, 32/4
285
        add     edi, 8
285
        add     edi, 8
286
        xor     eax, eax
286
        xor     eax, eax
287
        rep stosd
287
        rep stosd
288
        pop     eax
288
        pop     eax
289
        push    eax edx edi
289
        push    eax edx edi
290
; convert number in eax to decimal string
290
; convert number in eax to decimal string
291
        push    -'0'
291
        push    -'0'
292
        mov     ecx, 10
292
        mov     ecx, 10
293
@@:
293
@@:
294
        xor     edx, edx
294
        xor     edx, edx
295
        div     ecx
295
        div     ecx
296
        push    edx
296
        push    edx
297
        test    eax, eax
297
        test    eax, eax
298
        jnz     @b
298
        jnz     @b
299
        cmp     ebx, 2
299
        cmp     ebx, 2
300
        jz      .uni
300
        jz      .uni
301
@@:
301
@@:
302
        pop     eax
302
        pop     eax
303
        add     eax, '0'
303
        add     eax, '0'
304
        stosb
304
        stosb
305
        test    eax, eax
305
        test    eax, eax
306
        jnz     @b
306
        jnz     @b
307
        pop     edi edx eax
307
        pop     edi edx eax
308
        cmp     ebx, 3
308
        cmp     ebx, 3
309
        jz      @f
309
        jz      @f
310
        add     edi, 264
310
        add     edi, 264
311
        jmp     .maindir_loop
311
        jmp     .maindir_loop
312
 
312
 
313
.uni:
313
.uni:
314
        pop     eax
314
        pop     eax
315
        add     eax, '0'
315
        add     eax, '0'
316
        stosw
316
        stosw
317
        test    eax, eax
317
        test    eax, eax
318
        jnz     .uni
318
        jnz     .uni
319
        pop     edi edx eax
319
        pop     edi edx eax
320
@@:
320
@@:
321
        add     edi, 520
321
        add     edi, 520
322
        jmp     .maindir_loop
322
        jmp     .maindir_loop
323
 
323
 
324
.maindir_done:
324
.maindir_done:
325
        pop     eax eax
325
        pop     eax eax
326
        mov     ebx, [edx+4]
326
        mov     ebx, [edx+4]
327
        xor     eax, eax
327
        xor     eax, eax
328
        dec     ebp
328
        dec     ebp
329
        js      @f
329
        js      @f
330
        mov     al, ERROR_END_OF_FILE
330
        mov     al, ERROR_END_OF_FILE
331
@@:
331
@@:
332
        mov     [image_of_eax], eax
332
        mov     [image_of_eax], eax
333
        mov     [image_of_ebx], ebx
333
        mov     [image_of_ebx], ebx
334
        ret
334
        ret
335
 
335
 
336
.access_denied:
336
.access_denied:
337
        mov     dword[image_of_eax], ERROR_ACCESS_DENIED
337
        mov     dword[image_of_eax], ERROR_ACCESS_DENIED
338
        ret
338
        ret
339
 
339
 
340
.deviceInfo:
340
.deviceInfo:
341
        test    ebp, ebp
341
        test    ebp, ebp
342
        jz      @f
342
        jz      @f
343
        mov     eax, dword[ebp+DISK.MediaInfo.Capacity]
343
        mov     eax, dword[ebp+DISK.MediaInfo.Capacity]
344
        mov     edx, dword[ebp+DISK.MediaInfo.Capacity+4]
344
        mov     edx, dword[ebp+DISK.MediaInfo.Capacity+4]
345
        shld    edx, eax, 9
345
        shld    edx, eax, 9
346
        shl     eax, 9
346
        shl     eax, 9
347
        mov     [edi+36], edx
347
        mov     [edi+36], edx
348
        mov     [edi+32], eax
348
        mov     [edi+32], eax
349
@@:
349
@@:
350
        and     dword[image_of_eax], 0
350
        and     dword[image_of_eax], 0
351
        ret
351
        ret
352
 
352
 
353
.rootdir:   ; / - virtual root folder
353
.rootdir:   ; / - virtual root folder
354
        cmp     byte [ebx], 5
354
        cmp     byte [ebx], 5
355
        jz      @b
355
        jz      @b
356
        cmp     byte [ebx], 1   ; read folder?
356
        cmp     byte [ebx], 1   ; read folder?
357
        jnz     .access_denied
357
        jnz     .access_denied
358
        mov     ebp, [ebx+12]   ; number of blocks
358
        mov     ebp, [ebx+12]   ; number of blocks
359
        mov     edx, [ebx+16]   ; return area
359
        mov     edx, [ebx+16]   ; return area
360
        push    dword[ebx+4]    ; first block
360
        push    dword[ebx+4]    ; first block
361
        mov     ebx, [ebx+8]    ; flags
361
        mov     ebx, [ebx+8]    ; flags
362
        mov     ecx, 32/4
362
        mov     ecx, 32/4
363
        mov     edi, edx
363
        mov     edi, edx
364
        xor     eax, eax
364
        xor     eax, eax
365
        rep stosd
365
        rep stosd
366
        mov     byte [edx], 1   ; version
366
        mov     byte [edx], 1   ; version
367
        sub     esp, 16
367
        sub     esp, 16
368
.rootdir_loop:
368
.rootdir_loop:
369
        push    edi
369
        push    edi
370
        lea     edi, [esp+4]
370
        lea     edi, [esp+4]
371
        call    dyndisk_enum_root
371
        call    dyndisk_enum_root
372
        pop     edi
372
        pop     edi
373
        test    eax, eax
373
        test    eax, eax
374
        jz      .rootdirCD
374
        jz      .rootdirCD
375
        inc     dword[edx+8]
375
        inc     dword[edx+8]
376
        dec     dword[esp+16]
376
        dec     dword[esp+16]
377
        jns     .rootdir_loop
377
        jns     .rootdir_loop
378
        dec     ebp
378
        dec     ebp
379
        js      .rootdir_loop
379
        js      .rootdir_loop
380
        inc     dword[edx+4]
380
        inc     dword[edx+4]
381
        mov     dword[edi], 16      ; attributes: folder
381
        mov     dword[edi], 16      ; attributes: folder
382
        mov     dword[edi+4], ebx   ; name encoding
382
        mov     dword[edi+4], ebx   ; name encoding
383
        push    eax
383
        push    eax
384
        mov     ecx, 32/4
384
        mov     ecx, 32/4
385
        add     edi, 8
385
        add     edi, 8
386
        xor     eax, eax
386
        xor     eax, eax
387
        rep stosd
387
        rep stosd
388
        push    edi
388
        push    edi
389
        lea     esi, [esp+8]
389
        lea     esi, [esp+8]
390
        cmp     ebx, 2
390
        cmp     ebx, 2
391
        jz      .uni2
391
        jz      .uni2
392
@@:
392
@@:
393
        lodsb
393
        lodsb
394
        stosb
394
        stosb
395
        test    eax, eax
395
        test    eax, eax
396
        jnz     @b
396
        jnz     @b
397
        pop     edi eax
397
        pop     edi eax
398
        cmp     ebx, 3
398
        cmp     ebx, 3
399
        jz      @f
399
        jz      @f
400
        add     edi, 264
400
        add     edi, 264
401
        jmp     .rootdir_loop
401
        jmp     .rootdir_loop
402
 
402
 
403
.uni2:
403
.uni2:
404
        lodsb
404
        lodsb
405
        stosw
405
        stosw
406
        test    eax, eax
406
        test    eax, eax
407
        jnz     .uni2
407
        jnz     .uni2
408
        pop     edi eax
408
        pop     edi eax
409
@@:
409
@@:
410
        add     edi, 520
410
        add     edi, 520
411
        jmp     .rootdir_loop
411
        jmp     .rootdir_loop
412
 
412
 
413
.rootdirCD:
413
.rootdirCD:
414
        add     esp, 16
414
        add     esp, 16
415
        or      esi, -1
415
        or      esi, -1
416
.rootdirCD_loop:
416
.rootdirCD_loop:
417
        inc     esi
417
        inc     esi
418
        cmp     esi, 10
418
        cmp     esi, 10
419
        jnc     .rootdir_done
419
        jnc     .rootdir_done
420
        mov     eax, esi
420
        mov     eax, esi
421
        not     eax
421
        not     eax
422
        and     eax, 3
422
        and     eax, 3
423
        shl     eax, 1
423
        shl     eax, 1
424
        inc     eax
424
        inc     eax
425
        mov     ecx, esi
425
        mov     ecx, esi
426
        shr     ecx, 2
426
        shr     ecx, 2
427
        bt      [ecx*5+DRIVE_DATA+1], ax
427
        bt      [ecx*5+DRIVE_DATA+1], ax
428
        jnc     .rootdirCD_loop
428
        jnc     .rootdirCD_loop
429
        inc     dword[edx+8]
429
        inc     dword[edx+8]
430
        dec     dword[esp]
430
        dec     dword[esp]
431
        jns     .rootdirCD_loop
431
        jns     .rootdirCD_loop
432
        dec     ebp
432
        dec     ebp
433
        js      .rootdirCD_loop
433
        js      .rootdirCD_loop
434
        inc     dword[edx+4]
434
        inc     dword[edx+4]
435
        mov     dword[edi], 16      ; attributes: folder
435
        mov     dword[edi], 16      ; attributes: folder
436
        mov     dword[edi+4], ebx   ; name encoding
436
        mov     dword[edi+4], ebx   ; name encoding
437
        mov     ecx, 32/4
437
        mov     ecx, 32/4
438
        add     edi, 8
438
        add     edi, 8
439
        xor     eax, eax
439
        xor     eax, eax
440
        rep stosd
440
        rep stosd
441
        mov     eax, esi
441
        mov     eax, esi
442
        add     eax, '0'
442
        add     eax, '0'
443
        cmp     ebx, 1
443
        cmp     ebx, 1
444
        jz      @f
444
        jz      @f
445
        mov     word [edi], 'cd'
445
        mov     word [edi], 'cd'
446
        mov     [edi+2], ax
446
        mov     [edi+2], ax
447
        add     edi, 264
447
        add     edi, 264
448
        jmp     .rootdirCD_loop
448
        jmp     .rootdirCD_loop
449
 
449
 
450
@@:
450
@@:
451
        mov     dword[edi], 640063h
451
        mov     dword[edi], 640063h
452
        mov     [edi+4], eax
452
        mov     [edi+4], eax
453
        add     edi, 520
453
        add     edi, 520
454
        jmp     .rootdirCD_loop
454
        jmp     .rootdirCD_loop
455
 
455
 
456
.rootdir_done:
456
.rootdir_done:
457
        pop     eax
457
        pop     eax
458
        mov     ebx, [edx+4]
458
        mov     ebx, [edx+4]
459
        xor     eax, eax
459
        xor     eax, eax
460
        dec     ebp
460
        dec     ebp
461
        js      @f
461
        js      @f
462
        mov     al, ERROR_END_OF_FILE
462
        mov     al, ERROR_END_OF_FILE
463
@@:
463
@@:
464
        mov     [image_of_eax], eax
464
        mov     [image_of_eax], eax
465
        mov     [image_of_ebx], ebx
465
        mov     [image_of_ebx], ebx
466
        ret
466
        ret
467
 
467
 
468
;-----------------------------------------------------------------------------
468
;-----------------------------------------------------------------------------
469
process_replace_file_name:
469
process_replace_file_name:
470
; in: [esi] = virtual path
470
; in: [esi] = virtual path
471
; out: [esi]+[ebp] = physical path
471
; out: [esi]+[ebp] = physical path
472
        xor     edi, edi
472
        xor     edi, edi
473
        xor     ebp, ebp
473
        xor     ebp, ebp
474
.loop:
474
.loop:
475
        cmp     edi, [full_file_name_table.size]
475
        cmp     edi, [full_file_name_table.size]
476
        jae     .notfound
476
        jae     .notfound
477
        push    esi edi
477
        push    esi edi
478
        shl     edi, 7
478
        shl     edi, 7
479
        add     edi, [full_file_name_table]
479
        add     edi, [full_file_name_table]
480
@@:
480
@@:
481
        cmp     byte [edi], 0
481
        cmp     byte [edi], 0
482
        jz      .dest_done
482
        jz      .dest_done
483
        lodsb
483
        lodsb
484
        test    al, al
484
        test    al, al
485
        jz      .cont
485
        jz      .cont
486
        scasb
486
        scasb
487
        jz      @b
487
        jz      @b
488
        or      al, 20h
488
        or      al, 20h
489
        cmp     [edi-1], al
489
        cmp     [edi-1], al
490
        jz      @b
490
        jz      @b
491
.cont:
491
.cont:
492
        pop     edi esi
492
        pop     edi esi
493
        inc     edi
493
        inc     edi
494
        jmp     .loop
494
        jmp     .loop
495
 
495
 
496
.dest_done:
496
.dest_done:
497
        cmp     byte [esi], 0
497
        cmp     byte [esi], 0
498
        jz      .found
498
        jz      .found
499
        cmp     byte [esi], '/'
499
        cmp     byte [esi], '/'
500
        jnz     .cont
500
        jnz     .cont
501
.found:
501
.found:
502
        pop     edi eax
502
        pop     edi eax
503
        shl     edi, 7
503
        shl     edi, 7
504
        add     edi, [full_file_name_table]
504
        add     edi, [full_file_name_table]
505
        mov     ebp, esi
505
        mov     ebp, esi
506
        lea     esi, [edi+64]
506
        lea     esi, [edi+64]
507
.notfound:
507
.notfound:
508
        ret
508
        ret
509
 
509
 
510
;-----------------------------------------------------------------------------
510
;-----------------------------------------------------------------------------
511
uglobal
511
uglobal
512
addDirSeal db  ?
512
addDirSeal db  ?
513
endg
513
endg
514
 
514
 
515
sys_current_directory:  ; sysfunction 30
515
syscall_current_directory:  ; sysfunction 30
516
        mov     eax, [current_slot]
516
        mov     eax, [current_slot]
517
        mov     edi, [eax+APPDATA.cur_dir]
517
        mov     edi, [eax+APPDATA.cur_dir]
518
        xor     eax, eax
518
        xor     eax, eax
519
        dec     ebx
519
        dec     ebx
520
        jz      .set
520
        jz      .set
521
        dec     ebx
521
        dec     ebx
522
        jz      .get
522
        jz      .get
523
        dec     ebx
523
        dec     ebx
524
        jz      .mount_additional_directory
524
        jz      .mount_additional_directory
525
        mov     eax, edx
525
        mov     eax, edx
526
        dec     ebx
526
        dec     ebx
527
        jz      .set
527
        jz      .set
528
        mov     eax, esi
528
        mov     eax, esi
529
        dec     ebx
529
        dec     ebx
530
        jz      .get
530
        jz      .get
531
@@:
531
@@:
532
        ret
532
        ret
533
 
533
 
534
.mount_additional_directory:
534
.mount_additional_directory:
535
; in: ecx -> dir name+dir path (128)
535
; in: ecx -> dir name+dir path (128)
536
        mov     al, 1
536
        mov     al, 1
537
        xchg    [addDirSeal], al
537
        xchg    [addDirSeal], al
538
        test    al, al
538
        test    al, al
539
        jnz     @b
539
        jnz     @b
540
        mov     esi, ecx
540
        mov     esi, ecx
541
        mov     edi, sysdir_name1
541
        mov     edi, sysdir_name1
542
        mov     ecx, 64
542
        mov     ecx, 64
543
        rep movsb   ; copying fake directory name
543
        rep movsb   ; copying fake directory name
544
        mov     byte [edi-1], 0
544
        mov     byte [edi-1], 0
545
        mov     cl, 63
545
        mov     cl, 63
546
        call    cp866toUTF8_string
546
        call    cp866toUTF8_string
547
        mov     byte [edi], 0
547
        mov     byte [edi], 0
548
        mov     [full_file_name_table.size], 2
548
        mov     [full_file_name_table.size], 2
549
        ret
549
        ret
550
 
550
 
551
.get:
551
.get:
552
; in: ecx -> buffer, edx = length, eax = encoding
552
; in: ecx -> buffer, edx = length, eax = encoding
553
        stdcall is_region_userspace, ecx, edx
553
        stdcall is_region_userspace, ecx, edx
554
        jnz     @f
554
        jnz     @f
555
 
555
 
556
        ; if illegal buffer given
556
        ; if illegal buffer given
557
        xor     edx, edx
557
        xor     edx, edx
558
        jmp     .ret
558
        jmp     .ret
559
@@:
559
@@:
560
 
560
 
561
        mov     esi, edi
561
        mov     esi, edi
562
        inc     esi
562
        inc     esi
563
        mov     edi, ecx
563
        mov     edi, ecx
564
        cmp     edx, maxPathLength
564
        cmp     edx, maxPathLength
565
        jc      @f
565
        jc      @f
566
        mov     edx, maxPathLength
566
        mov     edx, maxPathLength
567
@@:
567
@@:
568
        mov     ecx, edx
568
        mov     ecx, edx
569
        jecxz   .ret
569
        jecxz   .ret
570
        cmp     eax, 2
570
        cmp     eax, 2
571
        jz      .get16
571
        jz      .get16
572
        cmp     eax, 3
572
        cmp     eax, 3
573
        jz      .get8
573
        jz      .get8
574
@@:
574
@@:
575
        dec     ecx
575
        dec     ecx
576
        js      @f
576
        js      @f
577
        call    utf8to16
577
        call    utf8to16
578
        call    uni2ansi_char
578
        call    uni2ansi_char
579
        stosb
579
        stosb
580
        test    al, al
580
        test    al, al
581
        jnz     @b
581
        jnz     @b
582
        sub     edx, ecx
582
        sub     edx, ecx
583
@@:
583
@@:
584
        mov     byte [edi-1], 0
584
        mov     byte [edi-1], 0
585
.ret:
585
.ret:
586
        mov     [esp+32], edx
586
        mov     [esp+32], edx
587
        ret
587
        ret
588
 
588
 
589
.get8:
589
.get8:
590
        push    edi
590
        push    edi
591
        mov     edi, esi
591
        mov     edi, esi
592
        xor     eax, eax
592
        xor     eax, eax
593
        repnz scasb
593
        repnz scasb
594
        sub     edx, ecx
594
        sub     edx, ecx
595
        mov     ecx, edx
595
        mov     ecx, edx
596
        pop     edi
596
        pop     edi
597
        rep movsb
597
        rep movsb
598
        jmp     @b
598
        jmp     @b
599
 
599
 
600
.get16:
600
.get16:
601
        shr     ecx, 1
601
        shr     ecx, 1
602
        shr     edx, 1
602
        shr     edx, 1
603
@@:
603
@@:
604
        dec     ecx
604
        dec     ecx
605
        js      @f
605
        js      @f
606
        call    utf8to16
606
        call    utf8to16
607
        stosw
607
        stosw
608
        test    ax, ax
608
        test    ax, ax
609
        jnz     @b
609
        jnz     @b
610
        sub     edx, ecx
610
        sub     edx, ecx
611
@@:
611
@@:
612
        shl     edx, 1
612
        shl     edx, 1
613
        mov     word [edi-2], 0
613
        mov     word [edi-2], 0
614
        jmp     .ret
614
        jmp     .ret
615
 
615
 
616
.set:
616
.set:
617
        mov     esi, ecx
617
        mov     esi, ecx
618
getFullPath:
618
getFullPath:
619
; in: esi -> file path, eax = string encoding, edi -> destination
619
; in: esi -> file path, eax = string encoding, edi -> destination
620
; out: UTF-8 string (with marker), eax = length, 0 -> error
620
; out: UTF-8 string (with marker), eax = length, 0 -> error
621
        test    eax, eax
621
        test    eax, eax
622
        jnz     @f
622
        jnz     @f
623
        cmp     byte [esi], 4
623
        cmp     byte [esi], 4
624
        jnc     @f
624
        jnc     @f
625
        cmp     byte [esi], 0
625
        cmp     byte [esi], 0
626
        jz      @f
626
        jz      @f
627
        lodsb
627
        lodsb
628
@@:
628
@@:
629
        cmp     byte [esi], '/'
629
        cmp     byte [esi], '/'
630
        jnz     .relative
630
        jnz     .relative
631
        cmp     eax, 2
631
        cmp     eax, 2
632
        jnz     @f
632
        jnz     @f
633
        cmp     word [esi], '/'
633
        cmp     word [esi], '/'
634
        jnz     .relative
634
        jnz     .relative
635
        inc     esi
635
        inc     esi
636
        inc     esi
636
        inc     esi
637
        jmp     .start
637
        jmp     .start
638
 
638
 
639
@@:
639
@@:
640
        inc     esi
640
        inc     esi
641
        cmp     byte [esi], 4
641
        cmp     byte [esi], 4
642
        jnc     .start
642
        jnc     .start
643
        lodsb
643
        lodsb
644
        cmp     byte [esi], '/'
644
        cmp     byte [esi], '/'
645
        jnz     .start
645
        jnz     .start
646
        inc     esi
646
        inc     esi
647
.start:
647
.start:
648
        push    eax edi
648
        push    eax edi
649
        call    process_replace_file_name
649
        call    process_replace_file_name
650
        mov     edi, [esp]
650
        mov     edi, [esp]
651
        mov     ecx, maxPathLength
651
        mov     ecx, maxPathLength
652
        mov     al, 3
652
        mov     al, 3
653
        mov     ah, '/'
653
        mov     ah, '/'
654
        stosw
654
        stosw
655
        sub     ecx, 2
655
        sub     ecx, 2
656
        test    ebp, ebp
656
        test    ebp, ebp
657
        jz      .absolute
657
        jz      .absolute
658
@@:
658
@@:
659
        lodsb
659
        lodsb
660
        stosb
660
        stosb
661
        dec     ecx
661
        dec     ecx
662
        test    al, al
662
        test    al, al
663
        jnz     @b
663
        jnz     @b
664
        mov     esi, ebp
664
        mov     esi, ebp
665
        dec     edi
665
        dec     edi
666
.absolute:
666
.absolute:
667
        cmp     byte [esp+4], 2
667
        cmp     byte [esp+4], 2
668
        jz      .utf16
668
        jz      .utf16
669
        cmp     byte [esp+4], 3
669
        cmp     byte [esp+4], 3
670
        jz      .utf8
670
        jz      .utf8
671
        call    cp866toUTF8_string
671
        call    cp866toUTF8_string
672
        jns     .end
672
        jns     .end
673
        jmp     .fail
673
        jmp     .fail
674
 
674
 
675
.utf8:
675
.utf8:
676
        dec     ecx
676
        dec     ecx
677
        js      .fail
677
        js      .fail
678
        lodsb
678
        lodsb
679
        stosb
679
        stosb
680
        test    al, al
680
        test    al, al
681
        jz      .end
681
        jz      .end
682
        jmp     .utf8
682
        jmp     .utf8
683
 
683
 
684
.utf16:
684
.utf16:
685
        call    UTF16to8_string
685
        call    UTF16to8_string
686
        jns     .end
686
        jns     .end
687
.fail:
687
.fail:
688
        mov     byte [edi], 0
688
        mov     byte [edi], 0
689
        pop     eax eax
689
        pop     eax eax
690
        xor     eax, eax
690
        xor     eax, eax
691
        ret
691
        ret
692
 
692
 
693
.relative:
693
.relative:
694
        push    eax edi
694
        push    eax edi
695
        mov     ebx, esi
695
        mov     ebx, esi
696
        mov     edi, [current_slot]
696
        mov     edi, [current_slot]
697
        mov     edi, [edi+APPDATA.cur_dir]
697
        mov     edi, [edi+APPDATA.cur_dir]
698
        mov     edx, edi
698
        mov     edx, edi
699
        mov     ecx, maxPathLength
699
        mov     ecx, maxPathLength
700
        xor     eax, eax
700
        xor     eax, eax
701
        repnz scasb
701
        repnz scasb
702
        mov     esi, edi
702
        mov     esi, edi
703
        mov     edi, [esp]
703
        mov     edi, [esp]
704
        jecxz   .fail
704
        jecxz   .fail
705
        cmp     byte [ebx], 0
705
        cmp     byte [ebx], 0
706
        jz      .set_ok
706
        jz      .set_ok
707
        dec     esi
707
        dec     esi
708
        cmp     edx, edi    ; is destination equal to cur_dir?
708
        cmp     edx, edi    ; is destination equal to cur_dir?
709
        mov     edi, esi
709
        mov     edi, esi
710
        jz      @f
710
        jz      @f
711
        mov     edi, [esp]
711
        mov     edi, [esp]
712
        mov     ecx, esi
712
        mov     ecx, esi
713
        sub     ecx, edx
713
        sub     ecx, edx
714
        mov     esi, edx
714
        mov     esi, edx
715
        mov     edx, edi
715
        mov     edx, edi
716
        rep movsb
716
        rep movsb
717
@@:
717
@@:
718
        mov     byte [edi], '/'
718
        mov     byte [edi], '/'
719
        inc     edi
719
        inc     edi
720
        mov     esi, ebx
720
        mov     esi, ebx
721
        mov     ecx, edx
721
        mov     ecx, edx
722
        add     ecx, maxPathLength
722
        add     ecx, maxPathLength
723
        sub     ecx, edi
723
        sub     ecx, edi
724
        jmp     .absolute
724
        jmp     .absolute
725
 
725
 
726
.set_ok:
726
.set_ok:
727
        cmp     edx, edi    ; is destination equal to cur_dir?
727
        cmp     edx, edi    ; is destination equal to cur_dir?
728
        jz      @f
728
        jz      @f
729
        mov     ecx, esi
729
        mov     ecx, esi
730
        sub     ecx, edx
730
        sub     ecx, edx
731
        mov     esi, edx
731
        mov     esi, edx
732
        rep movsb
732
        rep movsb
733
@@:
733
@@:
734
        pop     eax
734
        pop     eax
735
        sub     edi, eax
735
        sub     edi, eax
736
        pop     eax
736
        pop     eax
737
        mov     eax, edi
737
        mov     eax, edi
738
        ret
738
        ret
739
 
739
 
740
.end:
740
.end:
741
        or      ecx, -1
741
        or      ecx, -1
742
        mov     edi, [esp]
742
        mov     edi, [esp]
743
        xor     eax, eax
743
        xor     eax, eax
744
        push    edi
744
        push    edi
745
        repnz scasb
745
        repnz scasb
746
        not     ecx
746
        not     ecx
747
        pop     edi
747
        pop     edi
748
.parse:
748
.parse:
749
        mov     al, '/'
749
        mov     al, '/'
750
        repnz scasb
750
        repnz scasb
751
        jecxz   @b
751
        jecxz   @b
752
        cmp     byte [edi], '.'
752
        cmp     byte [edi], '.'
753
        jnz     .parse
753
        jnz     .parse
754
        mov     esi, edi
754
        mov     esi, edi
755
@@:
755
@@:
756
        lodsw
756
        lodsw
757
        sub     ecx, 2
757
        sub     ecx, 2
758
        cmp     ax, './'
758
        cmp     ax, './'
759
        jz      @b
759
        jz      @b
760
        cmp     ax, '..'
760
        cmp     ax, '..'
761
        jnz     @f
761
        jnz     @f
762
        cmp     byte [esi], '/'
762
        cmp     byte [esi], '/'
763
        jnz     @f
763
        jnz     @f
764
        mov     edx, ecx
764
        mov     edx, ecx
765
        mov     ecx, edi
765
        mov     ecx, edi
766
        sub     ecx, [esp]
766
        sub     ecx, [esp]
767
        sub     ecx, 2
767
        sub     ecx, 2
768
        jc      .fail
768
        jc      .fail
769
        sub     edi, 2
769
        sub     edi, 2
770
        lodsb
770
        lodsb
771
        dec     edx
771
        dec     edx
772
        std
772
        std
773
        repnz scasb
773
        repnz scasb
774
        cld
774
        cld
775
        add     edi, 2
775
        add     edi, 2
776
        mov     ecx, edx
776
        mov     ecx, edx
777
        jmp     @b
777
        jmp     @b
778
 
778
 
779
@@:
779
@@:
780
        sub     esi, 2
780
        sub     esi, 2
781
        add     ecx, 2
781
        add     ecx, 2
782
        cmp     esi, edi
782
        cmp     esi, edi
783
        jz      .parse
783
        jz      .parse
784
        push    edi ecx
784
        push    edi ecx
785
        rep movsb
785
        rep movsb
786
        pop     ecx edi
786
        pop     ecx edi
787
        jmp     .parse
787
        jmp     .parse
788
 
788
 
789
include "parse_fn.inc"
789
include "parse_fn.inc"
790
include "fs_common.inc"
790
include "fs_common.inc"
791
include "iso9660.inc"   ; read for CD filesystem
791
include "iso9660.inc"   ; read for CD filesystem
792
include "fat.inc"
792
include "fat.inc"
793
include "ntfs.inc"
793
include "ntfs.inc"
794
include "ext.inc"
794
include "ext.inc"
795
include "xfs.asm"
795
include "xfs.asm"