Subversion Repositories Kolibri OS

Rev

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