Subversion Repositories Kolibri OS

Rev

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

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