Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
2288 clevermous 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
2455 mario79 3
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
2288 clevermous 4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
6
;;                                                              ;;
7
;; System service for filesystem call                           ;;
8
;; (C) 2004 Ville Turjanmaa, License: GPL                       ;;
9
;; 29.04.2006 Elimination of hangup after the                   ;;
10
;;            expiration hd_wait_timeout (for LBA) -  Mario79   ;;
11
;; 15.01.2005 get file size/attr/date,                          ;;
12
;;            file_append (only for hd) - ATV                   ;;
13
;; 23.11.2004 test if hd/partition is set - ATV                 ;;
14
;; 18.11.2004 get_disk_info and more error codes - ATV          ;;
15
;; 08.11.2004 expand_pathz and rename (only for hd) - ATV       ;;
16
;; 20.10.2004 Makedir/Removedir (only for hd) - ATV             ;;
17
;;                                                              ;;
18
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19
 
20
$Revision: 3742 $
21
 
22
 
23
iglobal
3309 esevece 24
 
25
if lang eq sp
26
include 'fs/fs-sp.inc'
27
else
2288 clevermous 28
dir0:
29
             db  'HARDDISK   '
30
             db  'RAMDISK    '
31
             db  'FLOPPYDISK '
32
             db  0
33
 
34
dir1:
35
             db  'FIRST      '
36
             db  'SECOND     '
37
             db  'THIRD      '
38
             db  'FOURTH     '
39
             db  0
3309 esevece 40
end if
2288 clevermous 41
 
42
not_select_IDE db 0
43
 
44
hd_address_table:
45
                   dd  0x1f0,0x00,0x1f0,0x10
46
                   dd  0x170,0x00,0x170,0x10
47
endg
48
 
49
file_system:
50
 
51
; IN:
52
;
53
; eax = 0  ; read file          /RamDisk/First  6
54
; eax = 8  ; lba read
55
; eax = 15 ; get_disk_info
56
;
57
; OUT:
58
;
59
; eax = 0  : read ok
60
; eax = 1  : no hd base and/or partition defined
61
; eax = 2  : function is unsupported for this FS
62
; eax = 3  : unknown FS
63
; eax = 4  : partition not defined at hd
64
; eax = 5  : file not found
65
; eax = 6  : end of file
66
; eax = 7  : memory pointer not in application area
67
; eax = 8  : disk full
68
; eax = 9  : fat table corrupted
69
; eax = 10 : access denied
70
; eax = 11 : disk error
71
;
72
; ebx = size
73
 
74
; \begin{diamond}[18.03.2006]
75
; for subfunction 16 (start application) error codes must be negative
76
;    because positive values are valid PIDs
77
; so possible return values are:
78
; eax > 0 : process created, eax=PID
79
 
80
; -0x10 <= eax < 0 : -eax is filesystem error code:
81
; eax = -1  = 0xFFFFFFFF : no hd base and/or partition defined
82
; eax = -3  = 0xFFFFFFFD : unknown FS
83
; eax = -5  = 0xFFFFFFFB : file not found
84
; eax = -6  = 0xFFFFFFFA : unexpected end of file (probably not executable file)
85
; eax = -9  = 0xFFFFFFF7 : fat table corrupted
86
; eax = -10 = 0xFFFFFFF6 : access denied
87
 
88
; -0x20 <= eax < -0x10: eax is process creation error code:
89
; eax = -0x20 = 0xFFFFFFE0 : too many processes
90
; eax = -0x1F = 0xFFFFFFE1 : not Menuet/Kolibri executable
91
; eax = -0x1E = 0xFFFFFFE2 : no memory
92
 
93
; ebx is not changed
94
 
95
; \end{diamond}[18.03.2006]
96
 
97
    ; Extract parameters
98
 ;   add    eax, std_application_base_address    ; abs start of info block
99
 
100
        cmp     dword [eax+0], 15; GET_DISK_INFO
101
        je      fs_info
102
 
103
        cmp     dword [CURRENT_TASK], 1; no memory checks for kernel requests
104
        jz      no_checks_for_kernel
105
        mov     edx, eax
106
        cmp     dword [eax+0], 1
107
        jnz     .usual_check
108
        mov     ebx, [eax+12]
109
 ;   add   ebx,std_application_base_address
110
        mov     ecx, [eax+8]
111
        call    check_region
112
        test    eax, eax
113
        jnz     area_in_app_mem
114
 
115
.error_output:
116
        mov     esi, buffer_failed
117
        call    sys_msg_board_str
118
;    mov   eax,7
119
        mov     dword [esp+36], 7
120
        ret
121
iglobal
122
  buffer_failed db 'K : Buffer check failed',13,10,0
123
endg
124
.usual_check:
125
        cmp     dword [eax+0], 0
126
        mov     ecx, 512
127
        jnz     .small_size
128
        mov     ecx, [eax+8]
129
        shl     ecx, 9
130
.small_size:
131
        mov     ebx, [eax+12]
132
 ;   add   ebx,std_application_base_address
133
        call    check_region
134
        test    eax, eax
135
        jz      .error_output
136
  area_in_app_mem:
137
        mov     eax, edx
138
  no_checks_for_kernel:
139
 
140
  fs_read:
141
 
142
        mov     ebx, [eax+20]   ; program wants root directory ?
143
        test    bl, bl
144
        je      fs_getroot
145
        test    bh, bh
146
        jne     fs_noroot
147
  fs_getroot:
148
; \begin{diamond}[18.03.2006]
149
; root - only read is allowed
150
; other operations return "access denied", eax=10
151
; (execute operation returns eax=-10)
152
        cmp     dword [eax], 0
153
        jz      .read_root
154
        mov     dword [esp+36], 10
155
        ret
156
.read_root:
157
; \end{diamond}[18.03.2006]
158
        mov     esi, dir0
159
        mov     edi, [eax+12]
160
 ;   add   edi,std_application_base_address
161
        mov     ecx, 11
162
        push    ecx
163
;    cld    ; already is
164
        rep movsb
165
        mov     al, 0x10
166
        stosb
167
        add     edi, 32-11-1
168
        pop     ecx
169
        rep movsb
170
        stosb
171
        and     dword [esp+36], 0; ok read
172
        mov     dword [esp+24], 32*2; size of root
173
        ret
174
 
175
  fs_info:                      ;start of code - Mihasik
176
        push    eax
177
        cmp     [eax+21], byte 'r'
178
        je      fs_info_r
179
        cmp     [eax+21], byte 'R'
180
        je      fs_info_r
181
        mov     eax, 3          ;if unknown disk
182
        xor     ebx, ebx
183
        xor     ecx, ecx
184
        xor     edx, edx
185
        jmp     fs_info1
186
  fs_info_r:
187
        call    ramdisk_free_space;if ramdisk
188
        mov     ecx, edi        ;free space in ecx
189
        shr     ecx, 9          ;free clusters
190
        mov     ebx, 2847       ;total clusters
191
        mov     edx, 512        ;cluster size
192
        xor     eax, eax        ;always 0
193
  fs_info1:
194
        pop     edi
195
        mov     [esp+36], eax
196
        mov     [esp+24], ebx    ; total clusters on disk
197
        mov     [esp+32], ecx    ; free clusters on disk
198
        mov     [edi], edx       ; cluster size in bytes
199
        ret                      ;end of code - Mihasik
200
 
201
  fs_noroot:
202
 
203
        push    dword [eax+0]   ; read/write/delete/.../makedir/rename/lba/run
204
        push    dword [eax+4]   ; 512 block number to read
205
        push    dword [eax+8]   ; bytes to write/append or 512 blocks to read
206
        mov     ebx, [eax+12]
207
 ;   add   ebx,std_application_base_address
208
        push    ebx             ; abs start of return/save area
209
 
210
        lea     esi, [eax+20]   ; abs start of dir + filename
211
        mov     edi, [eax+16]
212
 ;   add   edi,std_application_base_address    ; abs start of work area
213
 
214
        call    expand_pathz
215
 
216
        push    edi             ; dir start
217
        push    ebx             ; name of file start
218
 
219
        mov     eax, [edi+1]
220
        cmp     eax, 'RD  '
221
        je      fs_yesramdisk
222
        cmp     eax, 'RAMD'
223
        jne     fs_noramdisk
224
 
225
  fs_yesramdisk:
226
 
227
        cmp     byte [edi+1+11], 0
228
        je      fs_give_dir1
229
 
230
        mov     eax, [edi+1+12]
231
        cmp     eax, '1   '
232
        je      fs_yesramdisk_first
233
        cmp     eax, 'FIRS'
234
        jne     fs_noramdisk
235
 
236
  fs_yesramdisk_first:
237
 
238
        cmp     dword [esp+20], 8; LBA read ramdisk
239
        jne     fs_no_LBA_read_ramdisk
240
 
241
        mov     eax, [esp+16]   ; LBA block to read
242
        mov     ecx, [esp+8]    ; abs pointer to return area
243
 
244
        call    LBA_read_ramdisk
245
        jmp     file_system_return
246
 
247
 
248
  fs_no_LBA_read_ramdisk:
249
 
250
        cmp     dword [esp+20], 0; READ
251
        jne     fs_noramdisk_read
252
 
253
        mov     eax, [esp+4]    ; fname
254
        add     eax, 2*12+1
255
        mov     ebx, [esp+16]   ; block start
256
        inc     ebx
257
        mov     ecx, [esp+12]   ; block count
258
        mov     edx, [esp+8]    ; return
259
        mov     esi, [esp+0]
260
        sub     esi, eax
261
        add     esi, 12+1       ; file name length
262
        call    fileread
263
 
264
        jmp     file_system_return
265
 
266
 
267
  fs_noramdisk_read:
268
  fs_noramdisk:
269
 
270
  ;********************************************************************
271
        mov     eax, [edi+1]
272
        cmp     eax, 'FD  '
273
        je      fs_yesflpdisk
274
        cmp     eax, 'FLOP'
275
        jne     fs_noflpdisk
276
 
277
  fs_yesflpdisk:
278
        call    reserve_flp
279
 
280
        cmp     byte [edi+1+11], 0
281
        je      fs_give_dir1
282
 
283
        mov     eax, [edi+1+12]
284
        cmp     eax, '1   '
285
        je      fs_yesflpdisk_first
286
        cmp     eax, 'FIRS'
287
        je      fs_yesflpdisk_first
288
        cmp     eax, '2   '
289
        je      fs_yesflpdisk_second
290
        cmp     eax, 'SECO'
291
        jne     fs_noflpdisk
292
        jmp     fs_yesflpdisk_second
293
 
294
  fs_yesflpdisk_first:
295
        mov     [flp_number], 1
296
        jmp     fs_yesflpdisk_start
297
  fs_yesflpdisk_second:
298
        mov     [flp_number], 2
299
  fs_yesflpdisk_start:
300
        cmp     dword [esp+20], 0; READ
301
        jne     fs_noflpdisk_read
302
 
303
        mov     eax, [esp+4]    ; fname
304
        add     eax, 2*12+1
305
        mov     ebx, [esp+16]   ; block start
306
        inc     ebx
307
        mov     ecx, [esp+12]   ; block count
308
        mov     edx, [esp+8]    ; return
309
        mov     esi, [esp+0]
310
        sub     esi, eax
311
        add     esi, 12+1       ; file name length
312
        call    floppy_fileread
313
 
314
        jmp     file_system_return
315
 
316
 
317
  fs_noflpdisk_read:
318
  fs_noflpdisk:
319
  ;*****************************************************************
320
 
321
 old_path_harddisk:
322
        mov     eax, [edi+1]
323
        cmp     eax, 'HD  '
324
        je      fs_yesharddisk
325
        cmp     eax, 'HARD'
326
        jne     fs_noharddisk
327
 
328
  fs_yesharddisk:
329
        cmp     dword [esp+20], 8; LBA read
330
        jne     fs_no_LBA_read
331
        mov     eax, [esp+16]   ; LBA block to read
332
        lea     ebx, [edi+1+12] ; pointer to FIRST/SECOND/THIRD/FOURTH
333
        mov     ecx, [esp+8]    ; abs pointer to return area
334
        call    LBA_read
335
        jmp     file_system_return
336
 
337
  fs_no_LBA_read:
338
 
339
hd_err_return:
340
 
341
  fs_noharddisk:
342
; \begin{diamond}[18.03.2006]
343
        mov     eax, 5   ; file not found
3539 clevermous 344
; а может быть, возвращать другой код ошибки?
2288 clevermous 345
        mov     ebx, [esp+24+24]; do not change ebx in application
346
; \end{diamond}[18.03.2006]
347
 
348
  file_system_return:
349
 
350
        add     esp, 24
351
 
352
        mov     [esp+36], eax
353
        mov     [esp+24], ebx
354
        ret
355
 
356
 
357
  fs_give_dir1:
358
 
359
; \begin{diamond}[18.03.2006]
360
; /RD,/FD,/HD - only read is allowed
361
; other operations return "access denied", eax=10
362
; (execute operation returns eax=-10)
363
        cmp     dword [esp+20], 0
364
        jz      .read
365
        add     esp, 20
366
        pop     ecx
367
        mov     dword [esp+36], 10
368
        ret
369
.read:
370
; \end{diamond}[18.03.2006]
371
        mov     al, 0x10
372
        mov     ebx, 1
373
        mov     edi, [esp+8]
374
        mov     esi, dir1
375
  fs_d1_new:
376
        mov     ecx, 11
377
;    cld
378
        rep movsb
379
        stosb
380
        add     edi, 32-11-1
381
        dec     ebx
382
        jne     fs_d1_new
383
 
384
        add     esp, 24
385
 
386
        and     dword [esp+36], 0; ok read
387
        mov     dword [esp+24], 32*1; dir/data size
388
        ret
389
 
390
 
391
 
392
LBA_read_ramdisk:
393
 
394
        cmp     [lba_read_enabled], 1
395
        je      lbarrl1
396
 
397
        xor     ebx, ebx
398
        mov     eax, 2
399
        ret
400
 
401
  lbarrl1:
402
 
403
        cmp     eax, 18*2*80
404
        jb      lbarrl2
405
        xor     ebx, ebx
406
        mov     eax, 3
407
        ret
408
 
409
  lbarrl2:
410
 
411
        pushad
412
 
413
        call    restorefatchain
414
 
415
        mov     edi, ecx
416
        mov     esi, eax
417
 
418
        shl     esi, 9
419
        add     esi, RAMDISK
420
        mov     ecx, 512/4
421
;    cld
422
        rep movsd
423
 
424
        popad
425
 
426
        xor     ebx, ebx
427
        xor     eax, eax
428
        ret
429
 
430
LBA_read:
431
 
432
; IN:
433
;
434
; eax = LBA block to read
435
; ebx = pointer to FIRST/SECOND/THIRD/FOURTH
436
; ecx = abs pointer to return area
437
 
438
        cmp     [lba_read_enabled], 1
439
        je      lbarl1
440
        mov     eax, 2
441
        ret
442
 
443
  lbarl1:
444
 
3742 clevermous 445
        pushad
446
        mov     ecx, ide_mutex
447
        call    mutex_lock
448
        popad
2288 clevermous 449
 
450
        push    eax
451
        push    ecx
452
 
453
        mov     edi, hd_address_table
454
        mov     esi, dir1
455
        mov     eax, [ebx]
456
        mov     edx, '1   '
457
        mov     ecx, 4
458
  blar0:
459
        cmp     eax, [esi]
460
        je      blar2
461
        cmp     eax, edx
462
        je      blar2
463
        inc     edx
464
        add     edi, 8
465
        add     esi, 11
466
        dec     ecx
467
        jnz     blar0
468
 
469
        mov     eax, 1
470
        mov     ebx, 1
471
        jmp     LBA_read_ret
472
 
473
  blar2:
474
        mov     eax, [edi+0]
475
        mov     ebx, [edi+4]
476
 
477
        mov     [hdbase], eax
478
        mov     [hdid], ebx
479
 
480
        call    wait_for_hd_idle
481
        cmp     [hd_error], 0
482
        jne     hd_lba_error
483
 
484
    ; eax = hd port
485
    ; ebx = set for primary (0x00) or slave (0x10)
486
 
487
        cli
488
 
489
        mov     edx, eax
490
        inc     edx
491
        xor     eax, eax
492
        out     dx, al
493
        inc     edx
494
        inc     eax
495
        out     dx, al
496
        inc     edx
497
        mov     eax, [esp+4]
498
        out     dx, al
499
        shr     eax, 8
500
        inc     edx
501
        out     dx, al
502
        shr     eax, 8
503
        inc     edx
504
        out     dx, al
505
        shr     eax, 8
506
        inc     edx
507
        and     al, 1+2+4+8
508
        add     al, bl
509
        add     al, 128+64+32
510
        out     dx, al
511
 
512
        inc     edx
513
        mov     al, 20h
514
        out     dx, al
515
 
516
        sti
517
 
518
        call    wait_for_sector_buffer
519
        cmp     [hd_error], 0
520
        jne     hd_lba_error
521
 
522
        cli
523
 
524
        mov     edi, [esp+0]
525
        mov     ecx, 256
526
        sub     edx, 7
527
        cld
528
        rep insw
529
 
530
        sti
531
 
532
        xor     eax, eax
533
        xor     ebx, ebx
534
 
535
  LBA_read_ret:
536
        mov     [hd_error], 0
537
        mov     [hd1_status], 0
538
        add     esp, 2*4
3742 clevermous 539
        pushad
540
        mov     ecx, ide_mutex
541
        call    mutex_unlock
542
        popad
2288 clevermous 543
 
544
        ret
545
 
546
 
547
expand_pathz:
548
; IN:
549
;   esi = asciiz path & file
550
;   edi = buffer for path & file name
551
; OUT:
552
;   edi = directory & file : / 11 + / 11 + / 11 - zero terminated
553
;   ebx = /file name - zero terminated
554
;   esi = pointer after source
555
 
556
        push    eax
557
        push    ecx
558
        push    edi;[esp+0]
559
 
560
  pathz_start:
561
        mov     byte [edi], '/'
562
        inc     edi
563
        mov     al, 32
564
        mov     ecx, 11
565
        cld
566
        rep stosb               ; clear filename area
567
        sub     edi, 11
568
        mov     ebx, edi        ; start of dir/file name
569
 
570
  pathz_new_char:
571
        mov     al, [esi]
572
        inc     esi
573
        cmp     al, 0
574
        je      pathz_end
575
 
576
        cmp     al, '/'
577
        jne     pathz_not_path
578
        cmp     edi, ebx        ; skip first '/'
579
        jz      pathz_new_char
580
        lea     edi, [ebx+11]   ; start of next directory
581
        jmp     pathz_start
582
 
583
  pathz_not_path:
584
        cmp     al, '.'
585
        jne     pathz_not_ext
586
        lea     edi, [ebx+8]    ; start of extension
587
        jmp     pathz_new_char
588
 
589
  pathz_not_ext:
590
        cmp     al, 'a'
591
        jb      pathz_not_low
592
        cmp     al, 'z'
593
        ja      pathz_not_low
594
        sub     al, 0x20        ; char to uppercase
595
 
596
  pathz_not_low:
597
        mov     [edi], al
598
        inc     edi
599
        mov     eax, [esp+0]    ; start_of_dest_path
600
        add     eax, 512        ; keep maximum path under 512 bytes
601
        cmp     edi, eax
602
        jb      pathz_new_char
603
 
604
  pathz_end:
605
        cmp     ebx, edi        ; if path end with '/'
606
        jnz     pathz_put_zero  ; go back 1 level
607
        sub     ebx, 12
608
 
609
  pathz_put_zero:
610
        mov     byte [ebx+11], 0
611
        dec     ebx             ; include '/' char into file name
612
        pop     edi
613
        pop     ecx
614
        pop     eax
615
        ret
616
 
617
;*******************************************
618
;* string to number
619
;* input eax - 4 byte string
620
;* output eax - number
621
;*******************************************
622
StringToNumber:
3539 clevermous 623
;    ПЕРЕВОД СТРОКОВОГО ЧИСЛА В ЧИСЛОВОЙ ВИД
624
;    Вход:
625
;        EDI - адрес строки с числом. Конец числа отмечен кодом 0Dh
626
;    Выход:
627
;        CF - индикатор ошибок:
628
;            0 - ошибок нет;
629
;            1 - ошибка
630
;        Если CF=0, то AX - число.
2288 clevermous 631
 
632
        push    bx
633
        push    cx
634
        push    dx
635
        push    edi
636
        mov     [partition_string], eax
637
        mov     edi, partition_string
638
        xor     cx, cx
639
i1:
640
        mov     al, [edi]
641
        cmp     al, 32;13
642
        je      i_exit
643
;    cmp    al,'0'
644
;    jb    err
645
;    cmp    al,'9'
646
;    ja    err
647
        sub     al, 48
648
        shl     cx, 1
649
        jc      error
650
        mov     bx, cx
651
        shl     cx, 1
652
        jc      error
653
        shl     cx, 1
654
        jc      error
655
        add     cx, bx
656
        jc      error
657
        cbw
658
        add     cx, ax
659
        jc      error
660
i3:
661
        inc     edi
662
        jmp     i1
663
i_exit:
664
        mov     ax, cx
665
        clc
666
i4:
667
        movzx   eax, ax
668
        pop     edi
669
        pop     dx
670
        pop     cx
671
        pop     bx
672
        ret
673
 
674
error:
675
        stc
676
        jmp     i4
677
 
678
partition_string:
679
                  dd 0
680
                  db 32