Subversion Repositories Kolibri OS

Rev

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

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