Subversion Repositories Kolibri OS

Rev

Rev 10051 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2288 clevermous 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
10051 ace_dent 3
;; Copyright (C) KolibriOS team 2004-2024. All rights reserved. ;;
6468 pathoswith 4
;;  Distributed under terms of the GNU General Public License.  ;;
2288 clevermous 5
;;                                                              ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7
 
8
 
6468 pathoswith 9
; CD external functions
10
;   in:
6471 pathoswith 11
; esi -> path string in UTF-8
6872 pathoswith 12
; ebx -> parameter structure +4
6468 pathoswith 13
; ecx = bytes to read
14
; edx -> buffer
15
;   out:
16
; eax, ebx = return values for sysfunc 70
17
iglobal
18
align 4
19
fs_CdServices:
20
        dd      fs_CdRead
21
        dd      fs_CdReadFolder
22
        dd      fs_NotImplemented
23
        dd      fs_NotImplemented
24
        dd      fs_NotImplemented
25
        dd      fs_CdGetFileInfo
26
        dd      fs_NotImplemented
27
        dd      0
28
        dd      fs_NotImplemented
29
        dd      fs_NotImplemented
30
fs_NumCdServices = ($ - fs_CdServices)/4
31
endg
32
 
2288 clevermous 33
uglobal
6468 pathoswith 34
align 4
35
cd_current_pointer_of_input     dd  0
36
cd_current_pointer_of_input_2   dd  0
37
cd_mem_location                 dd  0
38
cd_counter_block                dd  0
39
cd_status                       dd  0
2288 clevermous 40
endg
6468 pathoswith 41
 
4700 mario79 42
;-----------------------------------------------------------------------------
6468 pathoswith 43
fs_NotImplemented:
44
        movi    eax, ERROR_UNSUPPORTED_FS
45
        ret
46
;-----------------------------------------------------------------------------
2288 clevermous 47
reserve_cd:
48
        cli
49
        cmp     [cd_status], 0
50
        je      reserve_ok2
51
 
52
        sti
53
        call    change_task
54
        jmp     reserve_cd
4700 mario79 55
;-----------------------------------------------------------------------------
56
reserve_ok2:
2288 clevermous 57
        push    eax
9828 Doczom 58
        mov     eax, [current_slot]
59
        mov     eax, [eax + APPDATA.tid]
2288 clevermous 60
        mov     [cd_status], eax
61
        pop     eax
62
        sti
63
        ret
4700 mario79 64
;-----------------------------------------------------------------------------
65
reserve_cd_channel:
66
        pushad
67
        mov     eax, [cdpos]
68
        dec     eax
69
        shr     eax, 2
2288 clevermous 70
 
4700 mario79 71
        test    eax, eax
72
        jnz     .1
73
 
2288 clevermous 74
        cmp     [ChannelNumber], 1
4700 mario79 75
        jne     @f
76
 
3742 clevermous 77
        mov     ecx, ide_channel1_mutex
4700 mario79 78
        jmp     .mutex_lock
79
;--------------------------------------
80
@@:
81
        mov     ecx, ide_channel2_mutex
82
        jmp     .mutex_lock
83
;--------------------------------------
84
.1:
85
        dec     eax
86
        jnz     .2
87
 
88
        cmp     [ChannelNumber], 1
89
        jne     @f
90
 
91
        mov     ecx, ide_channel3_mutex
92
        jmp     .mutex_lock
93
;--------------------------------------
94
@@:
95
        mov     ecx, ide_channel4_mutex
96
        jmp     .mutex_lock
97
;--------------------------------------
98
.2:
99
        cmp     [ChannelNumber], 1
100
        jne     @f
101
 
102
        mov     ecx, ide_channel5_mutex
103
        jmp     .mutex_lock
104
;--------------------------------------
105
@@:
106
        mov     ecx, ide_channel6_mutex
107
.mutex_lock:
3742 clevermous 108
        call    mutex_lock
109
        popad
2288 clevermous 110
        ret
4700 mario79 111
;-----------------------------------------------------------------------------
112
free_cd_channel:
3742 clevermous 113
        pushad
4700 mario79 114
        mov     eax, [cdpos]
115
        dec     eax
116
        shr     eax, 2
2288 clevermous 117
 
4700 mario79 118
        test    eax, eax
119
        jnz     .1
120
 
2288 clevermous 121
        cmp     [ChannelNumber], 1
4700 mario79 122
        jne     @f
123
 
3742 clevermous 124
        mov     ecx, ide_channel1_mutex
4700 mario79 125
        jmp     .mutex_unlock
126
;--------------------------------------
127
@@:
3742 clevermous 128
        mov     ecx, ide_channel2_mutex
4700 mario79 129
        jmp     .mutex_unlock
130
;--------------------------------------
131
.1:
132
        dec     eax
133
        jnz     .2
134
 
135
        cmp     [ChannelNumber], 1
136
        jne     @f
137
 
138
        mov     ecx, ide_channel3_mutex
139
        jmp     .mutex_unlock
140
;--------------------------------------
141
@@:
142
        mov     ecx, ide_channel4_mutex
143
        jmp     .mutex_unlock
144
;--------------------------------------
145
.2:
146
        cmp     [ChannelNumber], 1
147
        jne     @f
148
 
149
        mov     ecx, ide_channel5_mutex
150
        jmp     .mutex_unlock
151
;--------------------------------------
152
@@:
153
        mov     ecx, ide_channel6_mutex
154
.mutex_unlock:
3742 clevermous 155
        call    mutex_unlock
156
        popad
2288 clevermous 157
        ret
6468 pathoswith 158
 
4700 mario79 159
;-----------------------------------------------------------------------------
2288 clevermous 160
fs_CdRead:
161
        call    cd_find_lfn
6845 pathoswith 162
        jc      .notFound
2288 clevermous 163
        mov     edi, [cd_current_pointer_of_input]
6845 pathoswith 164
        test    byte [edi+25], 10b  ; do not allow read directories
2288 clevermous 165
        jnz     .noaccess
166
        test    ebx, ebx
167
        jz      .l1
168
        cmp     dword [ebx+4], 0
169
        jz      @f
6845 pathoswith 170
        xor     ebx, ebx
171
        movi    eax, ERROR_END_OF_FILE
172
        ret
4700 mario79 173
 
6845 pathoswith 174
.notFound:
175
        cmp     [DevErrorCode], 0
176
        jne     .noaccess
2288 clevermous 177
        xor     ebx, ebx
6845 pathoswith 178
        movi    eax, ERROR_FILE_NOT_FOUND
2288 clevermous 179
        ret
6845 pathoswith 180
 
181
.noaccess_3:
182
        pop     eax edx ecx
183
.noaccess:
184
        xor     ebx, ebx
185
        movi    eax, ERROR_ACCESS_DENIED
186
        ret
187
 
2288 clevermous 188
@@:
189
        mov     ebx, [ebx]
190
.l1:
6845 pathoswith 191
        push    ecx edx 0
192
        mov     eax, [edi+10]   ; real size of the file section
2288 clevermous 193
        sub     eax, ebx
194
        jb      .eof
195
        cmp     eax, ecx
196
        jae     @f
197
        mov     ecx, eax
6845 pathoswith 198
        pop     eax
199
        push    ERROR_END_OF_FILE
2288 clevermous 200
@@:
201
        mov     eax, [edi+2]
202
        mov     [CDSectorAddress], eax
203
; now eax=cluster, ebx=position, ecx=count, edx=buffer for data
204
.new_sector:
205
        test    ecx, ecx
206
        jz      .done
207
        sub     ebx, 2048
208
        jae     .next
209
        add     ebx, 2048
210
        jnz     .incomplete_sector
211
        cmp     ecx, 2048
212
        jb      .incomplete_sector
213
; we may read and memmove complete sector
214
        mov     [CDDataBuf_pointer], edx
6845 pathoswith 215
        call    ReadCDWRetr
2288 clevermous 216
        cmp     [DevErrorCode], 0
217
        jne     .noaccess_3
218
        add     edx, 2048
219
        sub     ecx, 2048
220
.next:
221
        inc     dword [CDSectorAddress]
222
        jmp     .new_sector
6845 pathoswith 223
 
224
.eof:
225
        pop     eax
226
        push    ERROR_END_OF_FILE
227
.done:
228
        mov     ebx, edx
229
        pop     eax edx ecx
230
        sub     ebx, edx
231
        ret
232
 
233
.incomplete_sector: ; we must read and memmove incomplete sector
2288 clevermous 234
        mov     [CDDataBuf_pointer], CDDataBuf
6845 pathoswith 235
        call    ReadCDWRetr
2288 clevermous 236
        cmp     [DevErrorCode], 0
237
        jne     .noaccess_3
238
        push    ecx
239
        add     ecx, ebx
240
        cmp     ecx, 2048
241
        jbe     @f
242
        mov     ecx, 2048
243
@@:
244
        sub     ecx, ebx
245
        push    edi esi ecx
246
        mov     edi, edx
247
        lea     esi, [CDDataBuf + ebx]
248
        cld
249
        rep movsb
250
        pop     ecx esi edi
251
        add     edx, ecx
252
        sub     [esp], ecx
253
        pop     ecx
254
        xor     ebx, ebx
255
        jmp     .next
6468 pathoswith 256
 
4700 mario79 257
;-----------------------------------------------------------------------------
2288 clevermous 258
fs_CdReadFolder:
259
        push    edi
260
        call    cd_find_lfn
261
        jnc     .found
262
        pop     edi
263
        cmp     [DevErrorCode], 0
264
        jne     .noaccess_1
6880 pathoswith 265
        xor     ebx, ebx
2288 clevermous 266
        mov     eax, ERROR_FILE_NOT_FOUND
267
        ret
6798 pathoswith 268
 
2288 clevermous 269
.found:
270
        mov     edi, [cd_current_pointer_of_input]
271
        test    byte [edi+25], 10b    ; do not allow read directories
272
        jnz     .found_dir
273
        pop     edi
274
.noaccess_1:
6880 pathoswith 275
        xor     ebx, ebx
2288 clevermous 276
        mov     eax, ERROR_ACCESS_DENIED
277
        ret
6798 pathoswith 278
 
279
.end_buffer:
280
        pop     edx eax
281
        sub     eax, 2048   ; directory is over?
282
        ja      .read_to_buffer
283
        mov     eax, [cd_counter_block]
284
        mov     [edx+8], eax
285
        mov     eax, [ebx]
286
        sub     [edx+4], eax
287
        xor     eax, eax
288
        dec     ecx
289
        js      @f
290
        mov     al, ERROR_END_OF_FILE
291
@@:
292
        pop     ecx edi
293
        mov     ebx, [edx+4]
294
        ret
295
 
2288 clevermous 296
.found_dir:
297
        mov     eax, [edi+2]    ; eax=cluster
298
        mov     [CDSectorAddress], eax
4700 mario79 299
        mov     eax, [edi+10]   ; directory size
2288 clevermous 300
        push    eax ecx
301
        mov     edi, edx
302
        mov     ecx, 32/4
303
        xor     eax, eax
304
        rep stosd
305
        pop     ecx eax
306
        mov     byte [edx], 1   ; version
307
        mov     [cd_mem_location], edx
308
        add     [cd_mem_location], 32
309
        mov     [cd_counter_block], dword 0
310
        dec     dword [CDSectorAddress]
311
        push    ecx
312
.read_to_buffer:
313
        inc     dword [CDSectorAddress]
314
        mov     [CDDataBuf_pointer], CDDataBuf
6798 pathoswith 315
        call    ReadCDWRetr     ; read sector of directory
2288 clevermous 316
        cmp     [DevErrorCode], 0
317
        jne     .noaccess_1
6798 pathoswith 318
        mov     [cd_current_pointer_of_input_2], CDDataBuf
319
        push    eax edx
2288 clevermous 320
.get_names_from_buffer:
321
        call    cd_get_name
322
        jc      .end_buffer
323
        inc     dword [cd_counter_block]
324
        mov     eax, [cd_counter_block]
325
        cmp     [ebx], eax
6798 pathoswith 326
        jae     .get_names_from_buffer
2288 clevermous 327
        test    ecx, ecx
6798 pathoswith 328
        jz      .get_names_from_buffer
2288 clevermous 329
        mov     edi, [cd_counter_block]
330
        mov     [edx+4], edi
331
        dec     ecx
332
        mov     esi, ebp
6798 pathoswith 333
        call    cd_get_parameters_of_file
2288 clevermous 334
        add     edi, 40
6798 pathoswith 335
        mov     ax, '.'
336
        cmp     dword[ebx+4], 2
337
        jz      .utf16
338
        cmp     dword[ebx+4], 3
339
        jz      .utf8
2288 clevermous 340
        cmp     [cd_counter_block], 2
6798 pathoswith 341
        jbe     .parentDirectory
342
@@:
2288 clevermous 343
        lodsw
344
        xchg    ah, al
345
        call    uni2ansi_char
346
        stosb
6798 pathoswith 347
        call    .checkForEnd
348
        jc      @b
349
@@:
2288 clevermous 350
        mov     [edi], byte 0
351
        add     [cd_mem_location], 304
6798 pathoswith 352
        jmp     .get_names_from_buffer
353
 
354
.parentDirectory:
355
        stosb
2288 clevermous 356
        cmp     [cd_counter_block], 2
6798 pathoswith 357
        jnz     @b
358
        stosb
359
        jmp     @b
4700 mario79 360
 
6798 pathoswith 361
.utf8:
362
        add     [cd_mem_location], 256
363
        cmp     [cd_counter_block], 2
364
        jbe     .parentDirectory
365
        push    ecx
366
        mov     ecx, 519
2288 clevermous 367
@@:
6798 pathoswith 368
        lodsw
369
        xchg    ah, al
370
        call    UTF16to8
371
        js      @f
372
        call    .checkForEnd
373
        jc      @b
374
@@:
375
        pop     ecx
376
        mov     [edi], byte 0
377
        add     [cd_mem_location], 304
378
        jmp     .get_names_from_buffer
4700 mario79 379
 
6798 pathoswith 380
.checkForEnd:
2288 clevermous 381
        mov     ax, [esi]
6798 pathoswith 382
        cmp     ax, 3B00h   ; ';'
383
        jz      @f
4700 mario79 384
; check for files not ending with separator
2288 clevermous 385
        movzx   eax, byte [ebp-33]
386
        add     eax, ebp
387
        sub     eax, 34
388
        cmp     esi, eax
6798 pathoswith 389
        jz      @f
4700 mario79 390
; check the end of the directory
2288 clevermous 391
        movzx   eax, byte [ebp-1]
392
        add     eax, ebp
393
        cmp     esi, eax
6798 pathoswith 394
@@:
395
        ret
396
 
397
.utf16:
398
        cmp     [cd_counter_block], 2
399
        jbe     .utf16ParentDirectory
400
@@:
401
        lodsw
402
        xchg    ah, al
403
        stosw
404
        call    .checkForEnd
405
        jc      @b
406
@@:
2288 clevermous 407
        mov     [edi], word 0
408
        add     [cd_mem_location], 560
6798 pathoswith 409
        jmp     .get_names_from_buffer
410
 
411
.utf16ParentDirectory:
412
        stosw
2288 clevermous 413
        cmp     [cd_counter_block], 2
6798 pathoswith 414
        jnz     @b
415
        stosw
416
        jmp     @b
4700 mario79 417
 
2288 clevermous 418
cd_get_parameters_of_file:
419
        mov     edi, [cd_mem_location]
420
cd_get_parameters_of_file_1:
4700 mario79 421
; get file attributes
2288 clevermous 422
        xor     eax, eax
4700 mario79 423
; file is not archived
2288 clevermous 424
        inc     eax
425
        shl     eax, 1
4700 mario79 426
; is a directory?
2288 clevermous 427
        test    [ebp-8], byte 2
428
        jz      .file
429
        inc     eax
430
.file:
4700 mario79 431
; not as a volume label in the FAT, in this form not available
432
; file is not a system
2288 clevermous 433
        shl     eax, 3
4700 mario79 434
; file is hidden? (attribute of existence)
2288 clevermous 435
        test    [ebp-8], byte 1
436
        jz      .hidden
437
        inc     eax
438
.hidden:
439
        shl     eax, 1
4700 mario79 440
; file is always read-only, as this CD
2288 clevermous 441
        inc     eax
442
        mov     [edi], eax
6798 pathoswith 443
        mov     eax, [ebx+4]
444
        mov     [edi+4], eax
4700 mario79 445
; get the time to file
446
; hour
2288 clevermous 447
        movzx   eax, byte [ebp-12]
448
        shl     eax, 8
4700 mario79 449
; minute
2288 clevermous 450
        mov     al, [ebp-11]
451
        shl     eax, 8
4700 mario79 452
; second
2288 clevermous 453
        mov     al, [ebp-10]
4700 mario79 454
; file creation time
2288 clevermous 455
        mov     [edi+8], eax
4700 mario79 456
; last access time
2288 clevermous 457
        mov     [edi+16], eax
4700 mario79 458
; last write time
2288 clevermous 459
        mov     [edi+24], eax
4700 mario79 460
; get date for file
461
; year
2288 clevermous 462
        movzx   eax, byte [ebp-15]
463
        add     eax, 1900
464
        shl     eax, 8
4700 mario79 465
; month
2288 clevermous 466
        mov     al, [ebp-14]
467
        shl     eax, 8
4700 mario79 468
; day
2288 clevermous 469
        mov     al, [ebp-13]
4700 mario79 470
; file creation date
2288 clevermous 471
        mov     [edi+12], eax
4700 mario79 472
; last access date
2288 clevermous 473
        mov     [edi+20], eax
6468 pathoswith 474
; last write date
2288 clevermous 475
        mov     [edi+28], eax
4700 mario79 476
; get the file size in bytes
2288 clevermous 477
        xor     eax, eax
478
        mov     [edi+32+4], eax
479
        mov     eax, [ebp-23]
480
        mov     [edi+32], eax
481
        ret
6468 pathoswith 482
 
4700 mario79 483
;-----------------------------------------------------------------------------
2288 clevermous 484
fs_CdGetFileInfo:
6872 pathoswith 485
        call    cd_find_lfn
486
        movi    eax, ERROR_FILE_NOT_FOUND
487
        jc      @f
488
        mov     edi, edx
489
        mov     eax, [ebx+4]
490
        mov     [edx+4], eax
2288 clevermous 491
        cmp     byte [esi], 0
6872 pathoswith 492
        jz      .volume
493
        mov     ebp, [cd_current_pointer_of_input]
494
        add     ebp, 33
495
        call    cd_get_parameters_of_file_1
496
        xor     eax, eax
497
@@:
2288 clevermous 498
        ret
4700 mario79 499
 
6872 pathoswith 500
.volume:
6876 pathoswith 501
        test    eax, eax
502
        jz      .size
6872 pathoswith 503
        mov     ecx, 16
504
        mov     esi, CDDataBuf+40
505
        add     edi, 40
506
        cmp     eax, 2
507
        jz      .utf16
508
        cmp     eax, 3
509
        jz      .utf8
2288 clevermous 510
@@:
6872 pathoswith 511
        lodsw
512
        xchg    al, ah
513
        call    uni2ansi_char
514
        stosb
515
        loop    @b
516
        jmp     .size
4700 mario79 517
 
6872 pathoswith 518
.utf16:
519
        lodsw
520
        xchg    al, ah
521
        stosw
522
        loop    .utf16
523
        jmp     .size
524
 
525
.utf8:
526
        mov     ebx, ecx
527
        shl     ecx, 1
2288 clevermous 528
@@:
6872 pathoswith 529
        lodsw
530
        xchg    ah, al
531
        call    UTF16to8
532
        dec     ebx
533
        jnz     @b
534
.size:
535
        mov     eax, [CDDataBuf+80]
536
        shl     eax, 11
537
        mov     [edx+32], eax
2288 clevermous 538
        xor     eax, eax
6872 pathoswith 539
        mov     [edx+36], eax
540
        stosw
6876 pathoswith 541
        mov     byte [edx], 8
2288 clevermous 542
        ret
6872 pathoswith 543
 
4700 mario79 544
;-----------------------------------------------------------------------------
2288 clevermous 545
cd_find_lfn:
546
        mov     [cd_appl_data], 0
6471 pathoswith 547
; in: esi -> path string in UTF-8
548
; out: [cd_current_pointer_of_input] -> direntry, CF=1 -> file not found
2288 clevermous 549
        push    eax esi
4700 mario79 550
; Sector 16 - start set of volume descriptors
2288 clevermous 551
        call    WaitUnitReady
552
        cmp     [DevErrorCode], 0
553
        jne     .access_denied
554
 
555
        call    prevent_medium_removal
4700 mario79 556
; testing of reading
2288 clevermous 557
        mov     [CDSectorAddress], dword 16
558
        mov     [CDDataBuf_pointer], CDDataBuf
559
        call    ReadCDWRetr;_1
560
        cmp     [DevErrorCode], 0
561
        jne     .access_denied
562
 
4700 mario79 563
; calculation of the last session
2288 clevermous 564
        call    WaitUnitReady
565
        cmp     [DevErrorCode], 0
566
        jne     .access_denied
4700 mario79 567
 
2288 clevermous 568
        call    Read_TOC
569
        mov     ah, [CDDataBuf+4+4]
570
        mov     al, [CDDataBuf+4+5]
571
        shl     eax, 16
572
        mov     ah, [CDDataBuf+4+6]
573
        mov     al, [CDDataBuf+4+7]
574
        add     eax, 15
575
        mov     [CDSectorAddress], eax
576
;  mov  [CDSectorAddress],dword 15
577
        mov     [CDDataBuf_pointer], CDDataBuf
4700 mario79 578
;--------------------------------------
2288 clevermous 579
.start:
580
        inc     dword [CDSectorAddress]
581
        call    ReadCDWRetr;_1
582
        cmp     [DevErrorCode], 0
583
        jne     .access_denied
584
 
585
.start_check:
4700 mario79 586
; checking for "lice"
2288 clevermous 587
        cmp     [CDDataBuf+1], dword 'CD00'
588
        jne     .access_denied
4700 mario79 589
 
2288 clevermous 590
        cmp     [CDDataBuf+5], byte '1'
591
        jne     .access_denied
4700 mario79 592
; sector is the terminator of set of descriptors volumes?
2288 clevermous 593
        cmp     [CDDataBuf], byte 0xff
594
        je      .access_denied
4700 mario79 595
; sector is an additional and improved descriptor of volume?
2288 clevermous 596
        cmp     [CDDataBuf], byte 0x2
597
        jne     .start
4700 mario79 598
; sector is an additional descriptor of volume?
2288 clevermous 599
        cmp     [CDDataBuf+6], byte 0x1
600
        jne     .start
601
 
4700 mario79 602
; parameters of root directory
603
        mov     eax, [CDDataBuf+0x9c+2]; start of root directory
2288 clevermous 604
        mov     [CDSectorAddress], eax
4700 mario79 605
        mov     eax, [CDDataBuf+0x9c+10]; size of root directory
2288 clevermous 606
        cmp     byte [esi], 0
607
        jnz     @f
4700 mario79 608
 
2288 clevermous 609
        mov     [cd_current_pointer_of_input], CDDataBuf+0x9c
610
        jmp     .done
4700 mario79 611
;--------------------------------------
2288 clevermous 612
@@:
4700 mario79 613
; start the search
2288 clevermous 614
.mainloop:
615
        dec     dword [CDSectorAddress]
4700 mario79 616
;--------------------------------------
2288 clevermous 617
.read_to_buffer:
618
        inc     dword [CDSectorAddress]
619
        mov     [CDDataBuf_pointer], CDDataBuf
4700 mario79 620
        call    ReadCDWRetr      ; read sector of directory
2288 clevermous 621
        cmp     [DevErrorCode], 0
622
        jne     .access_denied
623
        call    cd_find_name_in_buffer
624
        jnc     .found
625
        sub     eax, 2048
4700 mario79 626
; directory is over?
2288 clevermous 627
        cmp     eax, 0
628
        ja      .read_to_buffer
4700 mario79 629
; desired element of chain is not found
2288 clevermous 630
.access_denied:
631
        pop     esi eax
632
        mov     [cd_appl_data], 1
633
        stc
634
        ret
4700 mario79 635
;--------------------------------------
636
; desired element of chain found
637
.found:
638
; the end of the file path
2288 clevermous 639
        cmp     byte [esi-1], 0
640
        jz      .done
641
        mov     eax, [cd_current_pointer_of_input]
642
        push    dword [eax+2]
4700 mario79 643
        pop     dword [CDSectorAddress] ; beginning of the directory
644
        mov     eax, [eax+2+8] ; size of directory
2288 clevermous 645
        jmp     .mainloop
4700 mario79 646
;--------------------------------------
647
; file pointer found
648
.done:
2288 clevermous 649
        pop     esi eax
650
        mov     [cd_appl_data], 1
651
        clc
652
        ret
4700 mario79 653
;-----------------------------------------------------------------------------
2288 clevermous 654
cd_find_name_in_buffer:
655
        mov     [cd_current_pointer_of_input_2], CDDataBuf
4700 mario79 656
;--------------------------------------
2288 clevermous 657
.start:
658
        call    cd_get_name
659
        jc      .not_found
4700 mario79 660
 
2288 clevermous 661
        call    cd_compare_name
662
        jc      .start
4700 mario79 663
;--------------------------------------
2288 clevermous 664
.found:
665
        clc
666
        ret
4700 mario79 667
;--------------------------------------
2288 clevermous 668
.not_found:
669
        stc
670
        ret
4700 mario79 671
;-----------------------------------------------------------------------------
2288 clevermous 672
cd_get_name:
673
        push    eax
674
        mov     ebp, [cd_current_pointer_of_input_2]
675
        mov     [cd_current_pointer_of_input], ebp
676
        mov     eax, [ebp]
4700 mario79 677
        test    eax, eax ; entry's is over?
2288 clevermous 678
        jz      .next_sector
4700 mario79 679
 
680
        cmp     ebp, CDDataBuf+2048  ; buffer is over?
2288 clevermous 681
        jae     .next_sector
4700 mario79 682
 
2288 clevermous 683
        movzx   eax, byte [ebp]
4700 mario79 684
        add     [cd_current_pointer_of_input_2], eax ; next entry of directory
685
        add     ebp, 33; pointer is set to the beginning of the name
2288 clevermous 686
        pop     eax
687
        clc
688
        ret
4700 mario79 689
;--------------------------------------
2288 clevermous 690
.next_sector:
691
        pop     eax
692
        stc
693
        ret
4700 mario79 694
;-----------------------------------------------------------------------------
2288 clevermous 695
cd_compare_name:
6471 pathoswith 696
; in: esi -> UTF-8 name, ebp -> UTF-16BE name
697
; out: CF=0 -> names match, esi -> next component of name
698
;      CF=1 -> esi is not changed
699
        push    edx edi eax esi
2288 clevermous 700
        mov     edi, ebp
701
.loop:
6471 pathoswith 702
        call    utf8to16
703
        call    utf16toUpper
704
        mov     edx, eax
705
        mov     ax, [edi]
706
        xchg    al, ah
707
        call    utf16toUpper
708
        cmp     ax, dx
2288 clevermous 709
        jne     .name_not_coincide
6471 pathoswith 710
        add     edi, 2
4700 mario79 711
        cmp     [esi], byte '/' ; path separator is end of current element
2288 clevermous 712
        je      .done
4700 mario79 713
        cmp     [esi], byte 0 ; path separator end of name
6471 pathoswith 714
        jne     .loop
2288 clevermous 715
.done:
4700 mario79 716
; check end of file
717
        cmp     [edi], word 3B00h; separator end of file ';'
2288 clevermous 718
        je      .done_1
4700 mario79 719
; check for files not ending with separator
2288 clevermous 720
        movzx   eax, byte [ebp-33]
721
        add     eax, ebp
722
        sub     eax, 34
723
        cmp     edi, eax
724
        je      .done_1
4700 mario79 725
; check the end of directory
2288 clevermous 726
        movzx   eax, byte [ebp-1]
727
        add     eax, ebp
728
        cmp     edi, eax
729
        jne     .name_not_coincide
730
.done_1:
6471 pathoswith 731
        pop     eax eax edi edx
2288 clevermous 732
        inc     esi
733
        ret
6471 pathoswith 734
 
735
.name_not_coincide:
736
        pop     esi eax edi edx
737
        stc
738
        ret
10053 Doczom 739
 
740
;;; New driver
741
 
742
DESCRIPTOR_TYPE_BOOT          = 0x00    ; not used
743
DESCRIPTOR_TYPE_PRIMARY       = 0x01
744
DESCRIPTOR_TYPE_SUPPLEMENTARY = 0x02
745
; DESCRIPTOR_TYPE_PRIMARY for Juliet(UTF-16)
746
DESCRIPTOR_TYPE_PARTITION     = 0x02
747
DESCRIPTOR_TYPE_TERMANATOR    = 0xff    ; end scan descriptors
748
 
749
struct  ISO9660_VOLUME_DESCRIPTOR
750
        type    rb 1
751
        magic   rb 5  ; 'CD001'
752
        version rb 1
753
ends
754
 
755
struct  ISO9660_PRIMARY_DESCRIPTOR  ISO9660_VOLUME_DESCRIPTOR
756
                        rb 1
757
                        rb 32
758
        VolumeName      rb 32 ; ascii or utf-16
759
                        rb 8
760
        VolumeSpaceSize rb 8
761
                        rb 32
762
                        rb 4 ; +120
763
                        rb 4
764
        LBA_Size        rb 4 ; +128
765
        PathTableSize   rb 8         ; Do not use it!!!
766
        LBA_PathTable   rb 4 ; +140  ; Do not use it!!!
767
                        rb 4 ; +144  ; Do not use it!!!
768
                        rb 8
769
        root_dir_record rb 34  ;ISO9660_DIRECTORY_RECORD
770
                        rb 128*4 + 37*3
771
        date_created    rb 17
772
        date_modiffed   rb 17
773
                        rb 17
774
        file_struct_ver rb 1 ;always 0x01
775
ends
776
 
777
struct  ISO9660_DIRECTORY_RECORD
778
        size            rb 1
779
                        rb 1
780
        lba             rd 1
781
                        rd 1
782
        data_length     rd 1
783
                        rd 1
784
        date_time       rb 7
785
        flags           rb 1 ; 10b - directory  1b - hidden
786
                        rb 2+4
787
        name_len        rb 1
788
        name            rb 1 ;  rb [name_len]
789
ends
790
 
791
; Internal data for every ISO9660 partition.
792
struct ISO9660 PARTITION
793
       type_encoding    rd 1 ; 0 - ascii 1 - UCS-2
794
       lba_size         rd 1 ; default 2048 TODO
795
       primary_descr    rd 1 ; sector num
796
       root_dir_lba     rd 1 ; lba32
797
       root_dir_len     rd 1 ;
798
ends
799
;-----------------------------------------------------------------------------
800
 
801
; ISO9660 external functions
802
;   in:
803
; ebx -> parameter structure of sysfunc 70
804
; ebp -> ISO9660 structure
805
; esi -> path string in UTF-8
806
;   out:
807
; eax, ebx = return values for sysfunc 70
808
iglobal
809
align 4
810
iso9660_user_functions:
811
        dd      iso9660_free
812
        dd      (.end - $ - 4) / 4
813
        dd      iso9660_Read
814
        dd      iso9660_ReadFolder
815
        dd      0
816
        dd      0
817
        dd      0
818
        dd      iso9660_GetFileInfo
819
.end:
820
endg
821
 
822
; mount if it's a valid ISO9660 partition
823
iso9660_create_partition:
824
;   in:
825
; ebp -> PARTITION structure
826
; ebx -> boot sector
827
; ebx + 2048 -> buffer
828
; esi -> DISK structure
829
;   out:
830
; eax -> iso9660 partition structure, 0 = not iso9660
831
        cmp     dword [esi + DISK.MediaInfo.SectorSize], 2048 ; cd disks
832
        jnz     .fail_disk_sector
833
 
834
        push    ebx
835
        sub     esp, 4*3 ; locals value: primary_lba, encoding, select_sector
836
        mov     dword[esp], 16-1 ; sector number
837
        mov     eax, [esi + DISK.MediaInfo.LastSessionSector]
838
        add     [esp], eax
839
        mov     dword[esp + 4], 0 ; base encoding - ascii
840
 
841
        add     ebx, 2048
842
.new_descr:
843
        inc     dword[esp]
844
        ; read 16 sector, check header of descriptor
845
        xor     edx, edx
846
        mov     eax, [esp]
847
        mov     ecx, 1
848
        ; ebx - buffer
849
        ; edx:eax - num sector
850
        ; ebp - PARTITION
851
        ; ecx - number sectors
852
        call    fs_read64_sys
853
        test    eax, eax
854
        jnz     .err_disk_1
855
 
856
        cmp     dword[ebx + 1], 'CD00'
857
        jnz     .err_disk_1
858
        cmp     byte[ebx + 5], '1'
859
        jnz     .err_disk_1
860
 
861
        cmp     byte[ebx], DESCRIPTOR_TYPE_TERMANATOR
862
        jz      .end_scan
863
 
864
        cmp     byte[ebx], DESCRIPTOR_TYPE_PRIMARY
865
        jnz     @f
866
 
867
        cmp     dword[esp + 4], 0
868
        jnz     .new_descr
869
 
870
        mov     dword[esp + 4], 0 ; set UCS-2 encoding
871
        mov     eax, [esp]
872
        mov     dword[esp + 8], eax ; set lba address
873
 
874
        jmp     .new_descr
875
@@:
876
        cmp     byte[ebx], DESCRIPTOR_TYPE_SUPPLEMENTARY
877
        jnz     .new_descr
878
 
879
        mov     dword[esp + 4], 1 ; set UCS-2 encoding
880
        mov     eax, [esp]
881
        mov     dword[esp + 8], eax ; set lba address
882
 
883
        jmp     .new_descr
884
.end_scan:
885
 
886
        ; get root dir lba, root dir size, size lba
887
        xor     edx, edx
888
        mov     eax, [esp + 8]
889
        mov     ecx, 1
890
        call    fs_read64_sys
891
        test    eax, eax
892
        jnz     .err_disk_1
893
 
894
        ; alloc memory for ISO9660 struct
895
        mov     eax, sizeof.ISO9660
896
        call    malloc
897
        test    eax, eax
898
        jz      .err_disk_1
899
        ; copy data on struct
900
        add     esp, 4
901
        pop     dword[eax + ISO9660.type_encoding]
902
        mov     dword[eax + ISO9660.lba_size], 2048 ;TODO
903
        pop     dword[eax + ISO9660.primary_descr]
904
 
905
        mov     ecx, dword[ebx + ISO9660_PRIMARY_DESCRIPTOR.root_dir_record + ISO9660_DIRECTORY_RECORD.lba]
906
        mov     [eax + ISO9660.root_dir_lba], ecx
907
 
908
        mov     ecx, dword[ebx + ISO9660_PRIMARY_DESCRIPTOR.root_dir_record + ISO9660_DIRECTORY_RECORD.data_length]
909
        mov     [eax + ISO9660.root_dir_len], ecx
910
 
911
        push    edi esi
912
        mov     edi, eax
913
        mov     esi, ebp
914
        mov     ecx, sizeof.PARTITION/4
915
        rep movsd
916
        pop     esi edi
917
        mov     [eax + PARTITION.FSUserFunctions], iso9660_user_functions
918
 
919
        pop     ebx
920
        ret
921
.err_disk_1:
922
        add     esp, 4*3
923
        pop     ebx
924
.fail_disk_sector:
925
        xor     eax, eax
926
        ret
927
 
928
; IN: eax - ptr PARTITION
929
; OUT: -
930
; SAVE: esi, edi
931
;  Function free PARTITION struct and all object this structure
932
iso9660_free:
933
        jmp     free
934
 
935
 
936
 
937
;-----------------------------------------------------------------------------
938
; ISO9660 external functions
939
;   in:
940
; ebx -> parameter structure of sysfunc 70
941
; ebp -> ISO9660 structure
942
; esi -> path string in UTF-8
943
;   out:
944
; eax, ebx = return values for sysfunc 70
945
iso9660_Read:
946
        sub     esp, 4 ; for ptr on memory page
947
        call    iso9660_find_file
948
        mov     esi, eax
949
        mov     edi, [ebx + 16] ; ptr to programm buffer
950
 
951
        test    byte[esi + ISO9660_DIRECTORY_RECORD.flags], 10b ; check dir
952
        jnz     iso9660_find_file.not_found
953
 
954
        ; check offset (offset <= size)
955
        mov     edx, [ebx + 4]  ; low offset
956
        cmp     dword[ebx + 8], 0  ; high offset
957
        jnz     iso9660_find_file.bad_offset ; error offset > max size
958
 
959
        cmp     edx, [esi + ISO9660_DIRECTORY_RECORD.data_length]
960
        jae     iso9660_find_file.bad_offset ; error offset > file length
961
 
962
        ; good file - copy file data
963
        sub     esp, 4*4
964
        mov     dword[esp + 3*4], 0
965
        mov     [esp + 1*4], edx ; offset to start copy
966
        mov     dword[esp], 0 ; count copping byte
967
 
968
        ; check end offset (offset+size_buff <= size)
969
        mov     ecx, [esi + ISO9660_DIRECTORY_RECORD.data_length]
970
        mov     eax, [ebx + 12] ;size copy data - buffer size
971
        sub     ecx, edx
972
        mov     [esp + 2*4], eax  ; set count copy = buffer size
973
        cmp     ecx, eax           ; max copy size > buffer size
974
        jae     @f
975
 
976
        mov     [esp + 2*4], ecx
977
        mov     dword[esp + 3*4], ERROR_END_OF_FILE
978
 
979
@@:
980
        mov     esi, [esi + ISO9660_DIRECTORY_RECORD.lba]
981
        ; [esp + 4*4] = ptr temp buffer
982
        ; [esp+3*4] = fs err code  [esp+2*4] = size copy data
983
        ; [esp+1*4] = offset copy  [esp] = count copying data
984
 
985
.full_size:
986
        ; check offset mod sector_size = 0
987
        test    edx, not -2048
988
        jz      .first_align ; no creat buffer for first align
989
 
990
        mov     ebx, [esp + 4*4]
991
 
992
        ; read sector
993
        push    edx
994
 
995
        and     edx, -2048
996
        shr     edx, BSF 2048
997
        mov     eax, esi ; ISO9660_DIRECTORY_RECORD.lba
998
        add     eax, edx
999
        mov     ecx, 1
1000
        xor     edx, edx
1001
        ; ebx - buffer
1002
        ; edx:eax - num sector
1003
        ; ebp - PARTITION
1004
        ; ecx - number sectors
1005
        call    fs_read64_app
1006
 
1007
        pop     edx
1008
        test    eax, eax
1009
        jnz     .err_disk_1
1010
 
1011
        mov     ecx, edx
1012
        neg     edx
1013
        and     edx, not -2048
1014
        and     ecx, not -2048
1015
        ; create new offset
1016
        add     dword[esp + 1*4], not -2048
1017
        and     dword[esp + 1*4], -2048
1018
 
1019
        cmp     dword[esp + 2*4], edx  ; copy data > read in this sector
1020
        jae     @f
1021
        mov     edx, [esp + 2*4]
1022
@@:
1023
        sub     dword[esp + 2*4], edx
1024
        add     dword[esp], edx
1025
 
1026
        ;DEBUGF  1, "K : iso c=%x d=%x Hz\n", ecx, edx
1027
        push    esi
1028
        ; copy (2048 - offset) and -2048
1029
        mov     esi, ebx ; buffer
1030
        add     esi, ecx
1031
        mov     ecx, edx
1032
        rep movsb
1033
        pop     esi
1034
 
1035
        ;stdcall kernel_free, ebx
1036
.first_align:
1037
 
1038
        mov     ecx, [esp + 2*4]
1039
        and     ecx, -2048
1040
 
1041
        cmp     ecx, 2048
1042
        jb      .copy_finish_block
1043
 
1044
        mov     eax, [esp + 1*4]
1045
        shr     eax, BSF 2048
1046
        ; copy main block
1047
        mov     ebx, edi
1048
        add     edi, ecx
1049
        sub     dword[esp + 2*4], ecx
1050
        add     dword[esp + 1*4], ecx
1051
        add     dword[esp], ecx
1052
 
1053
        shr     ecx, BSF 2048
1054
        xor     edx, edx
1055
        add     eax, esi ; ISO9660_DIRECTORY_RECORD.lba
1056
        ; ebx - buffer
1057
        ; edx:eax - num sector
1058
        ; ebp - PARTITION
1059
        ; ecx - number sectors
1060
        call    fs_read64_app
1061
        test    eax, eax
1062
        jnz     .err_disk
1063
 
1064
.copy_finish_block:
1065
 
1066
        cmp     dword[esp + 2*4], 0
1067
        jz      .end_align ; creat buffer for end read sector
1068
 
1069
        mov     ebx, [esp + 4*4]
1070
 
1071
        ;copy finish block
1072
        mov     eax, [esp + 1*4]
1073
        shr     eax, BSF 2048
1074
        xor     edx, edx
1075
 
1076
        mov     ecx, 1
1077
        add     eax, esi ; ISO9660_DIRECTORY_RECORD.lba
1078
        ; ebx - buffer
1079
        ; edx:eax - num sector
1080
        ; ebp - PARTITION
1081
        ; ecx - number sectors
1082
        call    fs_read64_app
1083
        test    eax, eax
1084
        jnz     .err_disk_1
1085
 
1086
        mov     esi, ebx
1087
        mov     ecx, [esp + 2*4]
1088
        add     dword[esp], ecx
1089
        rep movsb
1090
 
1091
        ;stdcall kernel_free, ebx
1092
 
1093
.end_align:
1094
        ; set ebx size copy data
1095
        mov     ebx, [esp]
1096
        mov     esi, [esp + 3*4]
1097
        add     esp, 4*4
1098
        call    kernel_free
1099
 
1100
        mov     eax, esi
1101
        ret
1102
 
1103
.err_disk_1:
1104
        stdcall kernel_free, ebx
1105
.err_disk:
1106
        add     esp, 4*4
1107
        call    kernel_free
1108
        xor     ebx, ebx
1109
        mov     eax, ERROR_DEVICE
1110
        ret
1111
 
1112
;-----------------------------------------------------------------------------
1113
; ISO9660 external functions
1114
;   in:
1115
; ebx -> parameter structure of sysfunc 70
1116
; ebp -> ISO9660 structure
1117
; esi -> path string in UTF-8
1118
;   out:
1119
; eax, ebx = return values for sysfunc 70
1120
iso9660_ReadFolder:
1121
        sub     esp, 4 ; for ptr on memory page
1122
        call    iso9660_find_file
1123
 
1124
        test    byte[eax + ISO9660_DIRECTORY_RECORD.flags], 10b ; check dir
1125
        jz      iso9660_find_file.not_found
1126
 
1127
        mov     edi, [ebx + 16] ; buffer
1128
        push    dword[ebx + 16]
1129
        push    dword[ebx + 4]  ; first file
1130
        push    dword[ebx + 8]  ; encoding
1131
        push    dword 0
1132
        push    dword 0
1133
        push    dword[ebx + 12] ; count file
1134
        push    dword[eax + ISO9660_DIRECTORY_RECORD.data_length]
1135
        push    dword[eax + ISO9660_DIRECTORY_RECORD.lba]
1136
 
1137
        ; [esp] - lba   [esp + 4] - size
1138
        ; [esp + 8] - max count
1139
        ; [esp + 12] - counter
1140
        ; [esp + 16] - all count files
1141
        ; [esp + 20] - encoding
1142
        ; [esp + 24] - first item 0..(2^32 -1)
1143
        ; [esp + 28] - user buffer
1144
        ; edi - user buffer
1145
 
1146
        ; set header(32 byte) in buffer
1147
        mov     dword[edi], 1
1148
        add     edi, 32 ;set on first item
1149
 
1150
        ; loop copy file info and name
1151
.read_sector:
1152
        mov     ebx, [esp + 32]
1153
        mov     ecx, 1
1154
        xor     edx, edx
1155
        mov     eax, [esp]
1156
        ; ebx - buffer
1157
        ; edx:eax - num sector
1158
        ; ebp - PARTITION
1159
        ; ecx - number sectors
1160
        call    fs_read64_sys
1161
        test    eax, eax
1162
        jnz     .err_disk
1163
.new_file:
1164
        cmp     byte[ebx], 0
1165
        jz      .next_sector
1166
 
1167
        ; inc counter all files
1168
        inc     dword[esp + 16]
1169
        ; check copy
1170
        mov     eax, [esp + 24]
1171
        cmp     [esp + 16], eax
1172
        jbe     .skip
1173
 
1174
        mov     eax, [esp + 12]
1175
        cmp     [esp + 8], eax
1176
        je      .skip
1177
 
1178
        inc     dword[esp + 12]
1179
 
1180
        mov     eax, ebx
1181
        mov     ecx, edi
1182
        call    iso9660_GetFileInfo.copy_file_info
1183
 
1184
        ; copy encoding
1185
        movzx   eax, byte[esp + 20]
1186
        mov     [edi + 4], eax
1187
 
1188
        add     edi, 40
1189
;-----------------------------------------------------------------------------
1190
        ; copy name
1191
        push    ebx
1192
        push    edi
1193
        push    eax
1194
 
1195
        add     ebx, ISO9660_DIRECTORY_RECORD.name
1196
        mov     esi, ebx
1197
        mov     cl, [ebx - 1]
1198
        cmp     cl, 1
1199
        jne     @f
1200
        cmp     byte[ebx], 0
1201
        jne     @f
1202
        mov     dword[edi], '.'
1203
        jmp     .end_copy
1204
@@:
1205
        cmp     cl, byte[ebx]
1206
        jne     @f
1207
        mov     dword[edi], '..'
1208
        cmp     eax, 2
1209
        jne     .end_copy
1210
        mov     dword[edi], ('.' shl 16) + '.'
1211
        mov     word[edi+ 2], 0
1212
        jmp     .end_copy
1213
@@:
1214
;-----------------------------------------------------------------------------
1215
        ; copy real name
1216
        movzx   ecx, byte[ebx - 1]
1217
        cmp     [ebp + ISO9660.type_encoding], 0
1218
        jnz     .ucs2
1219
        cmp     eax, 2
1220
        je      .ascii2utf16
1221
@@:
1222
        sub     ecx, 1 ; CF + ZF
1223
        jbe     @f
1224
        movsd
1225
        cmp     byte[esi], ';'
1226
        jne     @b
1227
@@:
1228
        mov     byte[edi], 0
1229
        jmp     .end_copy
1230
;-----------------------------------------------------------------------------
1231
.ascii2utf16:
1232
        lodsb
1233
        call    ansi2uni_char
1234
        stosw
1235
        cmp     byte[esi], ';'
1236
        je      @f
1237
        loop    .ascii2utf16
1238
@@:
1239
        mov     word[edi], 0
1240
        jmp     .end_copy
1241
;-----------------------------------------------------------------------------
1242
.ucs2:
1243
        shr     ecx, 1
1244
        cmp     eax, 1
1245
        ja      .ucs2utf16
1246
        ; convert ucs2 to ascii
1247
@@:
1248
        lodsw
1249
        cmp     ax, 0x3B00
1250
        je      @f
1251
        xchg    al, ah
1252
        call    uni2ansi_char
1253
        stosb
1254
        loop    @b
1255
@@:
1256
        mov     byte[edi], 0
1257
        jmp     .end_copy
1258
;-----------------------------------------------------------------------------
1259
.ucs2utf16:
1260
        cmp     edx, 2 ; utf16 encoding
1261
        jne     .ucs2utf8
1262
        ; convert ucs2 to utf16LE
1263
@@:
1264
        lodsw
1265
        cmp     ax, 0x3B00
1266
        je      @f
1267
        xchg    al, ah
1268
        stosw
1269
        loop    @b
1270
@@:
1271
        mov     word[edi], 0
1272
        jmp     .end_copy
1273
;-----------------------------------------------------------------------------
1274
.ucs2utf8:
1275
        ; convert ucs2 to utf8
1276
        mov     ebx, ecx
1277
        shl     ecx, 1
1278
@@:
1279
        lodsw
1280
        cmp     ax, 0x3B00
1281
        je      @f
1282
        xchg    ah, al
1283
        call    UTF16to8
1284
        dec     ebx
1285
        jnz     @b
1286
@@:
1287
        mov     byte[edi], 0
1288
;-----------------------------------------------------------------------------
1289
.end_copy:
1290
        pop     eax
1291
        pop     edi
1292
        pop     ebx
1293
        add     edi, 264
1294
        cmp     eax, 2
1295
        jb      .skip
1296
        add     edi, 520-264
1297
.skip:
1298
        movzx   ecx, byte[ebx]
1299
        add     ebx, ecx
1300
 
1301
        test    ebx, 2048
1302
        jnz     .next_sector
1303
 
1304
        mov     eax, ebx
1305
        and     eax, not -2048
1306
        cmp     eax, [esp + 4]
1307
        jb      .new_file
1308
 
1309
        mov     eax, [esp + 12]
1310
        cmp     eax, [esp + 8]
1311
        jb      .new_file
1312
 
1313
        jmp     .end_loop
1314
 
1315
.next_sector:
1316
        inc     dword[esp]
1317
        sub     dword[esp + 4], 2048
1318
        ja      .read_sector
1319
.end_loop:
1320
        mov     ecx, [esp + 28]
1321
        mov     ebx, [esp + 12]
1322
        mov     [ecx + 4], ebx
1323
        mov     esi, [esp + 16]
1324
        mov     [ecx + 8], esi
1325
        mov     esi, [esp + 8] ; max count
1326
        ; free buffer
1327
        add     esp, 8*4
1328
        call    kernel_free
1329
 
1330
        xor     eax, eax
1331
        cmp     ebx, esi
1332
        je      @f
1333
        mov     eax, ERROR_END_OF_FILE
1334
@@:
1335
        ret
1336
.err_disk:
1337
        mov     ecx, [esp + 28]
1338
        mov     ebx, [esp + 12]
1339
        mov     [ecx + 4], ebx
1340
        mov     esi, [esp + 16]
1341
        mov     [ecx + 8], esi
1342
        ; free buffer
1343
        add     esp, 8*4
1344
        call    kernel_free
1345
 
1346
        mov     eax, ERROR_DEVICE
1347
        ret
1348
 
1349
;-----------------------------------------------------------------------------
1350
; ISO9660 external functions
1351
;   in:
1352
; ebx -> parameter structure of sysfunc 70
1353
; ebp -> ISO9660 structure
1354
; esi -> path string in UTF-8
1355
;   out:
1356
; eax, ebx = return values for sysfunc 70
1357
iso9660_GetFileInfo:
1358
        cmp     byte[esi], 0
1359
        jz      .rootdir
1360
 
1361
        sub     esp, 4 ; for ptr on memory page
1362
        call    iso9660_find_file
1363
 
1364
        mov     ecx, [ebx + 16] ; buffer
1365
 
1366
        call    .copy_file_info
1367
 
1368
        call    kernel_free
1369
        xor     eax, eax
1370
        mov     ebx, 40
1371
        ret
1372
 
1373
;  IN: eax -> ISO966_DIRECTORY_RECORD
1374
;      ecx -> buffer
1375
; destruct: edx
1376
.copy_file_info:
1377
         ; copy size
1378
        mov     [ecx + 36], dword 0
1379
        mov     edx, [eax + ISO9660_DIRECTORY_RECORD.data_length]
1380
        mov     [ecx + 32], edx
1381
 
1382
        ; copy flags(dir of file)
1383
        xor     edx, edx
1384
        or      dl, 000001b
1385
        test    byte[eax + ISO9660_DIRECTORY_RECORD.flags], 1b ; check hidden flag
1386
        jz      @f
1387
        or      dl, 10b
1388
@@:
1389
        test    byte[eax + ISO9660_DIRECTORY_RECORD.flags], 10b ; check dir
1390
        jz      @f
1391
        or      dl, 10000b ; dir flag
1392
        mov     dword[ecx + 32], 0 ; size = zero
1393
@@:
1394
        mov     [ecx], edx
1395
 
1396
        ; copy date creat file
1397
        movzx   edx, byte[eax + ISO9660_DIRECTORY_RECORD.date_time]
1398
        add     edx, 1900 ; year
1399
        shl     edx, 8
1400
 
1401
        mov     dl, byte[eax + ISO9660_DIRECTORY_RECORD.date_time + 1] ;month
1402
        shl     edx, 8
1403
        mov     dl, byte[eax + ISO9660_DIRECTORY_RECORD.date_time + 2] ;day
1404
 
1405
        mov     [ecx + 12], edx
1406
        mov     [ecx + 20], edx
1407
        mov     [ecx + 28], edx
1408
 
1409
        ; copy time creat file
1410
        movzx   edx, byte[eax + ISO9660_DIRECTORY_RECORD.date_time + 3] ;hour
1411
        shl     edx, 8
1412
        mov     dl, byte[eax + ISO9660_DIRECTORY_RECORD.date_time + 4] ; minute
1413
        shl     edx, 8
1414
        mov     dl, byte[eax + ISO9660_DIRECTORY_RECORD.date_time + 5] ; second
1415
 
1416
        mov     [ecx + 8], edx
1417
        mov     [ecx + 16], edx
1418
        mov     [ecx + 24], edx
1419
 
1420
        ret
1421
 
1422
.rootdir:
1423
        mov     edi, [ebx + 16] ; edi = buffer
1424
        ; copy flags (dir)
1425
        mov     byte [edi], 8
1426
        ; copy size drive
1427
        mov     eax, dword[ebp + PARTITION.Length+DQ.lo]
1428
        mov     edx, dword[ebp + PARTITION.Length+DQ.hi]
1429
        mov     ecx, [ebp + PARTITION.Disk]
1430
        mov     ecx, [ecx + DISK.MediaInfo.SectorSize]
1431
        bsf     ecx, ecx
1432
        shld    edx, eax, cl
1433
        shl     eax, cl
1434
        mov     [edi + 32], eax  ; bdfe.size.lo
1435
        mov     [edi + 36], edx  ; bdfe.size.hi
1436
 
1437
        mov     eax, [ebx + 8]
1438
        ; copy encoding
1439
        mov     [edi + 4], eax
1440
        ; check encoding on fs struct
1441
        test    eax, eax ; check f70s5arg.xflags
1442
        jz      .no_name
1443
 
1444
        ; stdcall is_region_userspace, edi, ecx
1445
 
1446
        ; alloc memory for read primary descriptor
1447
        stdcall kernel_alloc, PAGE_SIZE
1448
        test    eax, eax
1449
        jz      .no_memory
1450
 
1451
        push    eax
1452
        mov     esi, eax
1453
        ; read primary descriptor
1454
        mov     ebx, eax
1455
        mov     ecx, 1
1456
        xor     edx, edx
1457
        mov     eax, [ebp + ISO9660.primary_descr]
1458
        ; ebx - buffer
1459
        ; edx:eax - num sector
1460
        ; ebp - PARTITION
1461
        ; ecx - number sectors
1462
        call    fs_read64_sys
1463
        test    eax, eax
1464
        jnz     .err_read_part
1465
 
1466
        add     esi, ISO9660_PRIMARY_DESCRIPTOR.VolumeName
1467
        mov     edx, [edi + 4]
1468
        add     edi, 40 ; offset partition name
1469
        mov     ecx, 32
1470
        call    iso9660_copy_name
1471
 
1472
        ; free memory
1473
        call    kernel_free
1474
.no_name:
1475
        xor     eax, eax
1476
        mov     ebx, 40
1477
        ret
1478
.err_read_part:
1479
        call    kernel_free
1480
 
1481
        mov     eax, ERROR_DEVICE
1482
        ret
1483
.no_memory:
1484
        mov     eax, TASKMAN_ERROR_OUT_OF_MEMORY
1485
        ret
1486
 
1487
 
1488
;-----------------------------------------------------------------------------
1489
 
1490
; IN: esi - ptr string UTF-8 or zero for root directory
1491
; OUT: eax - ptr to directory record
1492
;      [esp + 4] - ptr to memory page for destruct
1493
iso9660_find_file:
1494
 
1495
        stdcall kernel_alloc, 4096 ;
1496
        test    eax, eax
1497
        jz      .err_get_memory
1498
 
1499
        mov     [esp + 4], eax
1500
 
1501
        cmp     byte[esi], 0
1502
        jz      .rootdir
1503
 
1504
        push    ebx     ; save and buffer = esp + 8
1505
        push    dword[ebp + ISO9660.root_dir_len]
1506
        push    dword[ebp + ISO9660.root_dir_lba]
1507
        ; [esp] - sector num  [esp + 4] - size dir
1508
        ; [esp + 8] - ebx     [esp + 16] - buffer
1509
        ; get size root dir (not record size)
1510
.read_sector:
1511
        ; get sector for directory
1512
        mov     edi, [esp + 16]
1513
        mov     ebx, [esp + 16]
1514
        mov     ecx, 1
1515
        xor     edx, edx
1516
        mov     eax, [esp]
1517
        ; ebx - buffer
1518
        ; edx:eax - num sector
1519
        ; ebp - PARTITION
1520
        ; ecx - number sectors
1521
        call    fs_read64_sys
1522
        test    eax, eax
1523
        jnz     .err_disk_1
1524
 
1525
        mov     ecx, [esp + 4]
1526
.next_record:
1527
 
1528
        ; check size
1529
        cmp     byte[edi], 0
1530
        jz      .next_sector
1531
 
1532
        ; check file name
1533
        call    iso9660_compare_name
1534
        jnc     .found
1535
 
1536
        movzx   edx, byte[edi + ISO9660_DIRECTORY_RECORD.size]
1537
        add     edi, edx
1538
 
1539
        test    edi, 2048 ;worked for allocate of page
1540
        jnz     .next_sector
1541
 
1542
        sub     ecx, edx
1543
        jc      .not_found_2
1544
 
1545
        jmp     .next_record
1546
 
1547
.next_sector:
1548
        sub     dword[esp + 4], 2048
1549
        jbe     .not_found_2
1550
        inc     dword[esp]
1551
        jmp     .read_sector
1552
 
1553
.found:
1554
        ; finish name?
1555
        cmp     byte[esi], '/'
1556
        jne     .done
1557
 
1558
        inc     esi
1559
        mov     edx, [edi + ISO9660_DIRECTORY_RECORD.lba]
1560
        mov     dword[esp], edx
1561
        mov     edx, [edi + ISO9660_DIRECTORY_RECORD.data_length]
1562
        mov     dword[esp + 4], edx
1563
        jmp     .read_sector
1564
.done:
1565
        mov     ebx, [esp + 8]
1566
        add     esp, 4*3
1567
        mov     eax, edi
1568
        ret
1569
 
1570
;-----------------------------------------------------------------------------
1571
.rootdir:
1572
        ; read primary descriptor
1573
        pusha
1574
        mov     ebx, eax
1575
        mov     ecx, 1
1576
        xor     edx, edx
1577
        mov     eax, [ebp + ISO9660.primary_descr]
1578
        ; ebx - buffer
1579
        ; edx:eax - num sector
1580
        ; ebp - PARTITION
1581
        ; ecx - number sectors
1582
        call    fs_read64_sys
1583
        test    eax, eax
1584
        popa
1585
        jnz     .err_disk
1586
 
1587
        mov     eax, [esp + 4]
1588
        add     eax, ISO9660_PRIMARY_DESCRIPTOR.root_dir_record
1589
        ret
1590
 
1591
; errors
1592
.err_disk_1:
1593
        ; free stack values
1594
        mov     ebx, [esp + 8]
1595
        add     esp, 4*3
1596
.err_disk:
1597
        add     esp, 4
1598
        call    kernel_free
1599
        xor     ebx, ebx
1600
        mov     eax, ERROR_DEVICE
1601
        ret
1602
 
1603
.not_found_2:
1604
        mov     ebx, [esp + 8]
1605
        add     esp, 4*3
1606
.not_found_1:
1607
        add     esp, 4
1608
.not_found: ; [esp] - ptr to page
1609
        call    kernel_free
1610
 
1611
        mov     eax, ERROR_FILE_NOT_FOUND
1612
        xor     ebx, ebx
1613
        ret
1614
 
1615
.bad_offset: ; [esp] - ptr to page
1616
        call    kernel_free
1617
 
1618
        mov     eax, ERROR_END_OF_FILE
1619
        xor     ebx, ebx
1620
        ret
1621
 
1622
 
1623
.err_get_memory:
1624
        add     esp, 8   ; skip addr return and dword for ptr to buffer
1625
.no_memory:
1626
        mov     eax, TASKMAN_ERROR_OUT_OF_MEMORY
1627
        xor     ebx, ebx
1628
        ret
1629
 
1630
 
1631
 
1632
iso9660_compare_name:
1633
; in: esi -> UTF-8 name, ebp -> ISO9660 struct
1634
;     edi -> ISO9660_DIRECTORY_RECORD
1635
; out: CF=0 -> names match, esi -> next component of name
1636
;      CF=1 -> esi is not changed
1637
        push    ecx eax esi edi
1638
        add     edi, ISO9660_DIRECTORY_RECORD.name
1639
.loop:
1640
        call    utf8to16
1641
        call    utf16toUpper
1642
        mov     edx, eax
1643
 
1644
        mov     ax, [edi]
1645
 
1646
        cmp     [ebp + ISO9660.type_encoding], 0
1647
        jnz     @f
1648
        shl     ax, 8 ; ah=al al=0
1649
        dec     edi
1650
@@:
1651
        xchg    al, ah
1652
        call    utf16toUpper
1653
 
1654
        cmp     ax, dx
1655
        jne     .name_not_coincide
1656
 
1657
        add     edi, 2
1658
        cmp     byte[esi], '/' ; path separator is end of current element
1659
        je      .done
1660
        cmp     byte[esi], 0 ; path separator end of name
1661
        jne     .loop
1662
.done:
1663
; check end of file
1664
        cmp     [ebp + ISO9660.type_encoding], 0
1665
        jnz     @f
1666
        cmp     byte[edi], ';'
1667
        je      .done_1
1668
@@:
1669
        cmp     [ebp + ISO9660.type_encoding], 0
1670
        jz      @f
1671
        cmp     word[edi], 0x3B00; separator end of file ';'
1672
        je      .done_1
1673
@@:
1674
; check for files not ending with separator
1675
;        movzx   eax, byte [ebp-33]
1676
;        add     eax, ebp
1677
;        sub     eax, 34
1678
;        cmp     edi, eax
1679
;        je      .done_1
1680
; check the end of directory
1681
        mov     ecx, [esp]
1682
        movzx   eax, byte [ecx + ISO9660_DIRECTORY_RECORD.name_len]
1683
        add     ecx, ISO9660_DIRECTORY_RECORD.name
1684
        add     eax, ecx
1685
        cmp     edi, eax
1686
        jne     .name_not_coincide
1687
.done_1:
1688
        pop     edi eax eax ecx
1689
        ret
1690
 
1691
.name_not_coincide:
1692
        pop     edi esi eax ecx
1693
        stc
1694
        ret
1695
 
1696
 
1697
 
1698
 
1699
;IN: ebp -> PARTITION structure
1700
;    ebx -> FS structure
1701
;    esi -> input string (ascii or ucs2)
1702
;    ecx =  count bytes
1703
;    edi -> output string (buffer)
1704
;    edx =  encoding output string
1705
;OUT: edi increasing
1706
;     esi increasing
1707
;     ecx = 0 or other value
1708
iso9660_copy_name:
1709
        cmp     [ebp + ISO9660.type_encoding], 0
1710
        jnz     .ucs2
1711
 
1712
        cmp     edx, 1 ; cp866 encoding
1713
        jne     @f
1714
        ; no convert chars
1715
        rep movsb
1716
        jmp     .end_copy_name
1717
@@:
1718
        cmp     edx, 2 ; utf16 encoding
1719
        jne     .ascii2utf8
1720
        ; convert ascii to utf16LE
1721
@@:
1722
        lodsb
1723
        call    ansi2uni_char
1724
        stosw
1725
        loop    @b
1726
        jmp     .end_copy_name
1727
 
1728
.ascii2utf8:
1729
        cmp     edx, 3 ; utf8 encoding
1730
        jne     .end_copy_name
1731
        ; convert ascii to utf8
1732
        call    cp866toUTF8_string
1733
        jmp     .end_copy_name
1734
.ucs2:
1735
        shr     ecx, 1 ; ecx/2 - ucs2 chars
1736
 
1737
        cmp     edx, 1 ; cp866 encoding
1738
        jne     .ucs2utf16
1739
        ; convert ucs2 to ascii
1740
@@:
1741
        lodsw
1742
        xchg    al, ah
1743
        call    uni2ansi_char
1744
        stosb
1745
        loop    @b
1746
 
1747
        jmp     .end_copy_name
1748
.ucs2utf16:
1749
        cmp     edx, 2 ; utf16 encoding
1750
        jne     .ucs2utf8
1751
        ; convert ucs2 to utf16LE
1752
@@:
1753
        lodsw
1754
        xchg    al, ah
1755
        stosw
1756
        loop    @b
1757
        jmp     .end_copy_name
1758
 
1759
.ucs2utf8:
1760
        cmp     edx, 3 ; utf8 encoding
1761
        jne     .end_copy_name
1762
        ; convert ucs2 to utf8
1763
        mov     ebx, ecx
1764
        shl     ecx, 1
1765
@@:
1766
        lodsw
1767
        xchg    ah, al
1768
        call    UTF16to8
1769
        dec     ebx
1770
        jnz     @b
1771
 
1772
.end_copy_name:
1773
        mov     byte[edi], 0
1774
        cmp     [ebp + ISO9660.type_encoding], 0
1775
        jz      @f
1776
        mov     word[edi], 0
1777
@@:
1778
        ret
1779