Subversion Repositories Kolibri OS

Rev

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

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