Subversion Repositories Kolibri OS

Rev

Rev 4700 | Rev 6262 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4700 Rev 5363
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
3
;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;;
4
;; Distributed under terms of the GNU General Public License    ;;
4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
5
;;                                                              ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7
 
7
 
8
$Revision: 4700 $
8
$Revision: 5363 $
9
 
9
 
10
;-----------------------------------------------------------------------------
10
;-----------------------------------------------------------------------------
11
uglobal
11
uglobal
12
cd_current_pointer_of_input    dd  0
12
cd_current_pointer_of_input    dd  0
13
cd_current_pointer_of_input_2  dd  0
13
cd_current_pointer_of_input_2  dd  0
14
cd_mem_location                dd  0
14
cd_mem_location                dd  0
15
cd_counter_block               dd  0
15
cd_counter_block               dd  0
16
endg
16
endg
17
;-----------------------------------------------------------------------------
17
;-----------------------------------------------------------------------------
18
reserve_cd:
18
reserve_cd:
19
        cli
19
        cli
20
        cmp     [cd_status], 0
20
        cmp     [cd_status], 0
21
        je      reserve_ok2
21
        je      reserve_ok2
22
 
22
 
23
        sti
23
        sti
24
        call    change_task
24
        call    change_task
25
        jmp     reserve_cd
25
        jmp     reserve_cd
26
;-----------------------------------------------------------------------------
26
;-----------------------------------------------------------------------------
27
reserve_ok2:
27
reserve_ok2:
28
        push    eax
28
        push    eax
29
        mov     eax, [CURRENT_TASK]
29
        mov     eax, [CURRENT_TASK]
30
        shl     eax, 5
30
        shl     eax, 5
31
        mov     eax, [eax+CURRENT_TASK+TASKDATA.pid]
31
        mov     eax, [eax+CURRENT_TASK+TASKDATA.pid]
32
        mov     [cd_status], eax
32
        mov     [cd_status], eax
33
        pop     eax
33
        pop     eax
34
        sti
34
        sti
35
        ret
35
        ret
36
;-----------------------------------------------------------------------------
36
;-----------------------------------------------------------------------------
37
reserve_cd_channel:
37
reserve_cd_channel:
38
        pushad
38
        pushad
39
        mov     eax, [cdpos]
39
        mov     eax, [cdpos]
40
        dec     eax
40
        dec     eax
41
        shr     eax, 2
41
        shr     eax, 2
42
 
42
 
43
        test    eax, eax
43
        test    eax, eax
44
        jnz     .1
44
        jnz     .1
45
 
45
 
46
        cmp     [ChannelNumber], 1
46
        cmp     [ChannelNumber], 1
47
        jne     @f
47
        jne     @f
48
 
48
 
49
        mov     ecx, ide_channel1_mutex
49
        mov     ecx, ide_channel1_mutex
50
        jmp     .mutex_lock
50
        jmp     .mutex_lock
51
;--------------------------------------
51
;--------------------------------------
52
@@:
52
@@:
53
        mov     ecx, ide_channel2_mutex
53
        mov     ecx, ide_channel2_mutex
54
        jmp     .mutex_lock
54
        jmp     .mutex_lock
55
;--------------------------------------
55
;--------------------------------------
56
.1:
56
.1:
57
        dec     eax
57
        dec     eax
58
        jnz     .2
58
        jnz     .2
59
 
59
 
60
        cmp     [ChannelNumber], 1
60
        cmp     [ChannelNumber], 1
61
        jne     @f
61
        jne     @f
62
 
62
 
63
        mov     ecx, ide_channel3_mutex
63
        mov     ecx, ide_channel3_mutex
64
        jmp     .mutex_lock
64
        jmp     .mutex_lock
65
;--------------------------------------
65
;--------------------------------------
66
@@:
66
@@:
67
        mov     ecx, ide_channel4_mutex
67
        mov     ecx, ide_channel4_mutex
68
        jmp     .mutex_lock
68
        jmp     .mutex_lock
69
;--------------------------------------
69
;--------------------------------------
70
.2:
70
.2:
71
        cmp     [ChannelNumber], 1
71
        cmp     [ChannelNumber], 1
72
        jne     @f
72
        jne     @f
73
 
73
 
74
        mov     ecx, ide_channel5_mutex
74
        mov     ecx, ide_channel5_mutex
75
        jmp     .mutex_lock
75
        jmp     .mutex_lock
76
;--------------------------------------
76
;--------------------------------------
77
@@:
77
@@:
78
        mov     ecx, ide_channel6_mutex
78
        mov     ecx, ide_channel6_mutex
79
.mutex_lock:
79
.mutex_lock:
80
        call    mutex_lock
80
        call    mutex_lock
81
        popad
81
        popad
82
        ret
82
        ret
83
;-----------------------------------------------------------------------------
83
;-----------------------------------------------------------------------------
84
free_cd_channel:
84
free_cd_channel:
85
        pushad
85
        pushad
86
        mov     eax, [cdpos]
86
        mov     eax, [cdpos]
87
        dec     eax
87
        dec     eax
88
        shr     eax, 2
88
        shr     eax, 2
89
 
89
 
90
        test    eax, eax
90
        test    eax, eax
91
        jnz     .1
91
        jnz     .1
92
 
92
 
93
        cmp     [ChannelNumber], 1
93
        cmp     [ChannelNumber], 1
94
        jne     @f
94
        jne     @f
95
 
95
 
96
        mov     ecx, ide_channel1_mutex
96
        mov     ecx, ide_channel1_mutex
97
        jmp     .mutex_unlock
97
        jmp     .mutex_unlock
98
;--------------------------------------
98
;--------------------------------------
99
@@:
99
@@:
100
        mov     ecx, ide_channel2_mutex
100
        mov     ecx, ide_channel2_mutex
101
        jmp     .mutex_unlock
101
        jmp     .mutex_unlock
102
;--------------------------------------
102
;--------------------------------------
103
.1:
103
.1:
104
        dec     eax
104
        dec     eax
105
        jnz     .2
105
        jnz     .2
106
 
106
 
107
        cmp     [ChannelNumber], 1
107
        cmp     [ChannelNumber], 1
108
        jne     @f
108
        jne     @f
109
 
109
 
110
        mov     ecx, ide_channel3_mutex
110
        mov     ecx, ide_channel3_mutex
111
        jmp     .mutex_unlock
111
        jmp     .mutex_unlock
112
;--------------------------------------
112
;--------------------------------------
113
@@:
113
@@:
114
        mov     ecx, ide_channel4_mutex
114
        mov     ecx, ide_channel4_mutex
115
        jmp     .mutex_unlock
115
        jmp     .mutex_unlock
116
;--------------------------------------
116
;--------------------------------------
117
.2:
117
.2:
118
        cmp     [ChannelNumber], 1
118
        cmp     [ChannelNumber], 1
119
        jne     @f
119
        jne     @f
120
 
120
 
121
        mov     ecx, ide_channel5_mutex
121
        mov     ecx, ide_channel5_mutex
122
        jmp     .mutex_unlock
122
        jmp     .mutex_unlock
123
;--------------------------------------
123
;--------------------------------------
124
@@:
124
@@:
125
        mov     ecx, ide_channel6_mutex
125
        mov     ecx, ide_channel6_mutex
126
.mutex_unlock:
126
.mutex_unlock:
127
        call    mutex_unlock
127
        call    mutex_unlock
128
        popad
128
        popad
129
        ret
129
        ret
130
;-----------------------------------------------------------------------------
130
;-----------------------------------------------------------------------------
131
uglobal
131
uglobal
132
cd_status dd 0
132
cd_status dd 0
133
endg
133
endg
134
;-----------------------------------------------------------------------------
134
;-----------------------------------------------------------------------------
135
;
135
;
136
;  fs_CdRead - LFN variant for reading CD disk
136
;  fs_CdRead - LFN variant for reading CD disk
137
;
137
;
138
;  esi  points to filename /dir1/dir2/.../dirn/file,0
138
;  esi  points to filename /dir1/dir2/.../dirn/file,0
139
;  ebx  pointer to 64-bit number = first wanted byte, 0+
139
;  ebx  pointer to 64-bit number = first wanted byte, 0+
140
;       may be ebx=0 - start from first byte
140
;       may be ebx=0 - start from first byte
141
;  ecx  number of bytes to read, 0+
141
;  ecx  number of bytes to read, 0+
142
;  edx  mem location to return data
142
;  edx  mem location to return data
143
;
143
;
144
;  ret ebx = bytes read or 0xffffffff file not found
144
;  ret ebx = bytes read or 0xffffffff file not found
145
;      eax = 0 ok read or other = errormsg
145
;      eax = 0 ok read or other = errormsg
146
;
146
;
147
;-----------------------------------------------------------------------------
147
;-----------------------------------------------------------------------------
148
fs_CdRead:
148
fs_CdRead:
149
        push    edi
149
        push    edi
150
        cmp     byte [esi], 0
150
        cmp     byte [esi], 0
151
        jnz     @f
151
        jnz     @f
152
;--------------------------------------
152
;--------------------------------------
153
.noaccess:
153
.noaccess:
154
        pop     edi
154
        pop     edi
155
;--------------------------------------
155
;--------------------------------------
156
.noaccess_2:
156
.noaccess_2:
157
        or      ebx, -1
157
        or      ebx, -1
158
        mov     eax, ERROR_ACCESS_DENIED
158
        mov     eax, ERROR_ACCESS_DENIED
159
        ret
159
        ret
160
;--------------------------------------
160
;--------------------------------------
161
.noaccess_3:
161
.noaccess_3:
162
        pop     eax edx ecx edi
162
        pop     eax edx ecx edi
163
        jmp     .noaccess_2
163
        jmp     .noaccess_2
164
;--------------------------------------
164
;--------------------------------------
165
@@:
165
@@:
166
        call    cd_find_lfn
166
        call    cd_find_lfn
167
        jnc     .found
167
        jnc     .found
168
 
168
 
169
        pop     edi
169
        pop     edi
170
        cmp     [DevErrorCode], 0
170
        cmp     [DevErrorCode], 0
171
        jne     .noaccess_2
171
        jne     .noaccess_2
172
 
172
 
173
        or      ebx, -1
173
        or      ebx, -1
174
        mov     eax, ERROR_FILE_NOT_FOUND
174
        mov     eax, ERROR_FILE_NOT_FOUND
175
        ret
175
        ret
176
;--------------------------------------
176
;--------------------------------------
177
.found:
177
.found:
178
        mov     edi, [cd_current_pointer_of_input]
178
        mov     edi, [cd_current_pointer_of_input]
179
        test    byte [edi+25], 10b; do not allow read directories
179
        test    byte [edi+25], 10b; do not allow read directories
180
        jnz     .noaccess
180
        jnz     .noaccess
181
 
181
 
182
        test    ebx, ebx
182
        test    ebx, ebx
183
        jz      .l1
183
        jz      .l1
184
 
184
 
185
        cmp     dword [ebx+4], 0
185
        cmp     dword [ebx+4], 0
186
        jz      @f
186
        jz      @f
187
 
187
 
188
        xor     ebx, ebx
188
        xor     ebx, ebx
189
;--------------------------------------
189
;--------------------------------------
190
.reteof:
190
.reteof:
191
        mov     eax, 6; end of file
191
        mov     eax, 6; end of file
192
        pop     edi
192
        pop     edi
193
        ret
193
        ret
194
;--------------------------------------
194
;--------------------------------------
195
@@:
195
@@:
196
        mov     ebx, [ebx]
196
        mov     ebx, [ebx]
197
;--------------------------------------
197
;--------------------------------------
198
.l1:
198
.l1:
199
        push    ecx edx
199
        push    ecx edx
200
        push    0
200
        push    0
201
        mov     eax, [edi+10] ; real size of the file section
201
        mov     eax, [edi+10] ; real size of the file section
202
        sub     eax, ebx
202
        sub     eax, ebx
203
        jb      .eof
203
        jb      .eof
204
 
204
 
205
        cmp     eax, ecx
205
        cmp     eax, ecx
206
        jae     @f
206
        jae     @f
207
 
207
 
208
        mov     ecx, eax
208
        mov     ecx, eax
209
        mov     byte [esp], 6
209
        mov     byte [esp], 6
210
;--------------------------------------
210
;--------------------------------------
211
@@:
211
@@:
212
        mov     eax, [edi+2]
212
        mov     eax, [edi+2]
213
        mov     [CDSectorAddress], eax
213
        mov     [CDSectorAddress], eax
214
;--------------------------------------
214
;--------------------------------------
215
; now eax=cluster, ebx=position, ecx=count, edx=buffer for data
215
; now eax=cluster, ebx=position, ecx=count, edx=buffer for data
216
.new_sector:
216
.new_sector:
217
        test    ecx, ecx
217
        test    ecx, ecx
218
        jz      .done
218
        jz      .done
219
 
219
 
220
        sub     ebx, 2048
220
        sub     ebx, 2048
221
        jae     .next
221
        jae     .next
222
 
222
 
223
        add     ebx, 2048
223
        add     ebx, 2048
224
        jnz     .incomplete_sector
224
        jnz     .incomplete_sector
225
 
225
 
226
        cmp     ecx, 2048
226
        cmp     ecx, 2048
227
        jb      .incomplete_sector
227
        jb      .incomplete_sector
228
; we may read and memmove complete sector
228
; we may read and memmove complete sector
229
        mov     [CDDataBuf_pointer], edx
229
        mov     [CDDataBuf_pointer], edx
230
        call    ReadCDWRetr ; read sector of file
230
        call    ReadCDWRetr ; read sector of file
231
        cmp     [DevErrorCode], 0
231
        cmp     [DevErrorCode], 0
232
        jne     .noaccess_3
232
        jne     .noaccess_3
233
 
233
 
234
        add     edx, 2048
234
        add     edx, 2048
235
        sub     ecx, 2048
235
        sub     ecx, 2048
236
;--------------------------------------
236
;--------------------------------------
237
.next:
237
.next:
238
        inc     dword [CDSectorAddress]
238
        inc     dword [CDSectorAddress]
239
        jmp     .new_sector
239
        jmp     .new_sector
240
;--------------------------------------
240
;--------------------------------------
241
.incomplete_sector:
241
.incomplete_sector:
242
; we must read and memmove incomplete sector
242
; we must read and memmove incomplete sector
243
        mov     [CDDataBuf_pointer], CDDataBuf
243
        mov     [CDDataBuf_pointer], CDDataBuf
244
        call    ReadCDWRetr ; read sector of file
244
        call    ReadCDWRetr ; read sector of file
245
        cmp     [DevErrorCode], 0
245
        cmp     [DevErrorCode], 0
246
        jne     .noaccess_3
246
        jne     .noaccess_3
247
 
247
 
248
        push    ecx
248
        push    ecx
249
        add     ecx, ebx
249
        add     ecx, ebx
250
        cmp     ecx, 2048
250
        cmp     ecx, 2048
251
        jbe     @f
251
        jbe     @f
252
 
252
 
253
        mov     ecx, 2048
253
        mov     ecx, 2048
254
;--------------------------------------
254
;--------------------------------------
255
@@:
255
@@:
256
        sub     ecx, ebx
256
        sub     ecx, ebx
257
        push    edi esi ecx
257
        push    edi esi ecx
258
        mov     edi, edx
258
        mov     edi, edx
259
        lea     esi, [CDDataBuf + ebx]
259
        lea     esi, [CDDataBuf + ebx]
260
        cld
260
        cld
261
        rep movsb
261
        rep movsb
262
        pop     ecx esi edi
262
        pop     ecx esi edi
263
        add     edx, ecx
263
        add     edx, ecx
264
        sub     [esp], ecx
264
        sub     [esp], ecx
265
        pop     ecx
265
        pop     ecx
266
        xor     ebx, ebx
266
        xor     ebx, ebx
267
        jmp     .next
267
        jmp     .next
268
;--------------------------------------
268
;--------------------------------------
269
.done:
269
.done:
270
        mov     ebx, edx
270
        mov     ebx, edx
271
        pop     eax edx ecx edi
271
        pop     eax edx ecx edi
272
        sub     ebx, edx
272
        sub     ebx, edx
273
        ret
273
        ret
274
;--------------------------------------
274
;--------------------------------------
275
.eof:
275
.eof:
276
        mov     ebx, edx
276
        mov     ebx, edx
277
        pop     eax edx ecx
277
        pop     eax edx ecx
278
        sub     ebx, edx
278
        sub     ebx, edx
279
        jmp     .reteof
279
        jmp     .reteof
280
;-----------------------------------------------------------------------------
280
;-----------------------------------------------------------------------------
281
;
281
;
282
;  fs_CdReadFolder - LFN variant for reading CD disk folder
282
;  fs_CdReadFolder - LFN variant for reading CD disk folder
283
;
283
;
284
;  esi  points to filename  /dir1/dir2/.../dirn/file,0
284
;  esi  points to filename  /dir1/dir2/.../dirn/file,0
285
;  ebx  pointer to structure 32-bit number = first wanted block, 0+
285
;  ebx  pointer to structure 32-bit number = first wanted block, 0+
286
;                          & flags (bitfields)
286
;                          & flags (bitfields)
287
; flags: bit 0: 0=ANSI names, 1=UNICODE names
287
; flags: bit 0: 0=ANSI names, 1=UNICODE names
288
;  ecx  number of blocks to read, 0+
288
;  ecx  number of blocks to read, 0+
289
;  edx  mem location to return data
289
;  edx  mem location to return data
290
;
290
;
291
;  ret ebx = blocks read or 0xffffffff folder not found
291
;  ret ebx = blocks read or 0xffffffff folder not found
292
;      eax = 0 ok read or other = errormsg
292
;      eax = 0 ok read or other = errormsg
293
;
293
;
294
;-----------------------------------------------------------------------------
294
;-----------------------------------------------------------------------------
295
fs_CdReadFolder:
295
fs_CdReadFolder:
296
        push    edi
296
        push    edi
297
        call    cd_find_lfn
297
        call    cd_find_lfn
298
        jnc     .found
298
        jnc     .found
299
 
299
 
300
        pop     edi
300
        pop     edi
301
        cmp     [DevErrorCode], 0
301
        cmp     [DevErrorCode], 0
302
        jne     .noaccess_1
302
        jne     .noaccess_1
303
 
303
 
304
        or      ebx, -1
304
        or      ebx, -1
305
        mov     eax, ERROR_FILE_NOT_FOUND
305
        mov     eax, ERROR_FILE_NOT_FOUND
306
        ret
306
        ret
307
;--------------------------------------
307
;--------------------------------------
308
.found:
308
.found:
309
        mov     edi, [cd_current_pointer_of_input]
309
        mov     edi, [cd_current_pointer_of_input]
310
        test    byte [edi+25], 10b    ; do not allow read directories
310
        test    byte [edi+25], 10b    ; do not allow read directories
311
        jnz     .found_dir
311
        jnz     .found_dir
312
 
312
 
313
        pop     edi
313
        pop     edi
314
;--------------------------------------
314
;--------------------------------------
315
.noaccess_1:
315
.noaccess_1:
316
        or      ebx, -1
316
        or      ebx, -1
317
        mov     eax, ERROR_ACCESS_DENIED
317
        mov     eax, ERROR_ACCESS_DENIED
318
        ret
318
        ret
319
;--------------------------------------
319
;--------------------------------------
320
.found_dir:
320
.found_dir:
321
        mov     eax, [edi+2]    ; eax=cluster
321
        mov     eax, [edi+2]    ; eax=cluster
322
        mov     [CDSectorAddress], eax
322
        mov     [CDSectorAddress], eax
323
        mov     eax, [edi+10]   ; directory size
323
        mov     eax, [edi+10]   ; directory size
324
;--------------------------------------
324
;--------------------------------------
325
.doit:
325
.doit:
326
; init header
326
; init header
327
        push    eax ecx
327
        push    eax ecx
328
        mov     edi, edx
328
        mov     edi, edx
329
        mov     ecx, 32/4
329
        mov     ecx, 32/4
330
        xor     eax, eax
330
        xor     eax, eax
331
        rep stosd
331
        rep stosd
332
        pop     ecx eax
332
        pop     ecx eax
333
        mov     byte [edx], 1   ; version
333
        mov     byte [edx], 1   ; version
334
        mov     [cd_mem_location], edx
334
        mov     [cd_mem_location], edx
335
        add     [cd_mem_location], 32
335
        add     [cd_mem_location], 32
336
;.mainloop:
336
;.mainloop:
337
        mov     [cd_counter_block], dword 0
337
        mov     [cd_counter_block], dword 0
338
        dec     dword [CDSectorAddress]
338
        dec     dword [CDSectorAddress]
339
        push    ecx
339
        push    ecx
340
;--------------------------------------
340
;--------------------------------------
341
.read_to_buffer:
341
.read_to_buffer:
342
        inc     dword [CDSectorAddress]
342
        inc     dword [CDSectorAddress]
343
        mov     [CDDataBuf_pointer], CDDataBuf
343
        mov     [CDDataBuf_pointer], CDDataBuf
344
        call    ReadCDWRetr         ; read sector of directory
344
        call    ReadCDWRetr         ; read sector of directory
345
        cmp     [DevErrorCode], 0
345
        cmp     [DevErrorCode], 0
346
        jne     .noaccess_1
346
        jne     .noaccess_1
347
 
347
 
348
        call    .get_names_from_buffer
348
        call    .get_names_from_buffer
349
        sub     eax, 2048
349
        sub     eax, 2048
350
; directory is over?
350
; directory is over?
351
        ja      .read_to_buffer
351
        ja      .read_to_buffer
352
 
352
 
353
        mov     edi, [cd_counter_block]
353
        mov     edi, [cd_counter_block]
354
        mov     [edx+8], edi
354
        mov     [edx+8], edi
355
        mov     edi, [ebx]
355
        mov     edi, [ebx]
356
        sub     [edx+4], edi
356
        sub     [edx+4], edi
357
        xor     eax, eax
357
        xor     eax, eax
358
        dec     ecx
358
        dec     ecx
359
        js      @f
359
        js      @f
360
 
360
 
361
        mov     al, ERROR_END_OF_FILE
361
        mov     al, ERROR_END_OF_FILE
362
;--------------------------------------
362
;--------------------------------------
363
@@:
363
@@:
364
        pop     ecx edi
364
        pop     ecx edi
365
        mov     ebx, [edx+4]
365
        mov     ebx, [edx+4]
366
        ret
366
        ret
367
;--------------------------------------
367
;--------------------------------------
368
.get_names_from_buffer:
368
.get_names_from_buffer:
369
        mov     [cd_current_pointer_of_input_2], CDDataBuf
369
        mov     [cd_current_pointer_of_input_2], CDDataBuf
370
        push    eax esi edi edx
370
        push    eax esi edi edx
371
;--------------------------------------
371
;--------------------------------------
372
.get_names_from_buffer_1:
372
.get_names_from_buffer_1:
373
        call    cd_get_name
373
        call    cd_get_name
374
        jc      .end_buffer
374
        jc      .end_buffer
375
 
375
 
376
        inc     dword [cd_counter_block]
376
        inc     dword [cd_counter_block]
377
        mov     eax, [cd_counter_block]
377
        mov     eax, [cd_counter_block]
378
        cmp     [ebx], eax
378
        cmp     [ebx], eax
379
        jae     .get_names_from_buffer_1
379
        jae     .get_names_from_buffer_1
380
 
380
 
381
        test    ecx, ecx
381
        test    ecx, ecx
382
        jz      .get_names_from_buffer_1
382
        jz      .get_names_from_buffer_1
383
 
383
 
384
        mov     edi, [cd_counter_block]
384
        mov     edi, [cd_counter_block]
385
        mov     [edx+4], edi
385
        mov     [edx+4], edi
386
        dec     ecx
386
        dec     ecx
387
        mov     esi, ebp
387
        mov     esi, ebp
388
        mov     edi, [cd_mem_location]
388
        mov     edi, [cd_mem_location]
389
        add     edi, 40
389
        add     edi, 40
390
        test    dword [ebx+4], 1; 0=ANSI, 1=UNICODE
390
        test    dword [ebx+4], 1; 0=ANSI, 1=UNICODE
391
        jnz     .unicode
391
        jnz     .unicode
392
;--------------------------------------
392
;--------------------------------------
393
.ansi:
393
.ansi:
394
        cmp     [cd_counter_block], 2
394
        cmp     [cd_counter_block], 2
395
        jbe     .ansi_parent_directory
395
        jbe     .ansi_parent_directory
396
 
396
 
397
        cld
397
        cld
398
        lodsw
398
        lodsw
399
        xchg    ah, al
399
        xchg    ah, al
400
        call    uni2ansi_char
400
        call    uni2ansi_char
401
        cld
401
        cld
402
        stosb
402
        stosb
403
; check end of file
403
; check end of file
404
        mov     ax, [esi]
404
        mov     ax, [esi]
405
        cmp     ax, word 3B00h ; separator end of file ';'
405
        cmp     ax, word 3B00h ; separator end of file ';'
406
        je      .cd_get_parameters_of_file_1
406
        je      .cd_get_parameters_of_file_1
407
; check for files not ending with separator
407
; check for files not ending with separator
408
        movzx   eax, byte [ebp-33]
408
        movzx   eax, byte [ebp-33]
409
        add     eax, ebp
409
        add     eax, ebp
410
        sub     eax, 34
410
        sub     eax, 34
411
        cmp     esi, eax
411
        cmp     esi, eax
412
        je      .cd_get_parameters_of_file_1
412
        je      .cd_get_parameters_of_file_1
413
; check the end of the directory
413
; check the end of the directory
414
        movzx   eax, byte [ebp-1]
414
        movzx   eax, byte [ebp-1]
415
        add     eax, ebp
415
        add     eax, ebp
416
        cmp     esi, eax
416
        cmp     esi, eax
417
        jb      .ansi
417
        jb      .ansi
418
;--------------------------------------
418
;--------------------------------------
419
.cd_get_parameters_of_file_1:
419
.cd_get_parameters_of_file_1:
420
        mov     [edi], byte 0
420
        mov     [edi], byte 0
421
        call    cd_get_parameters_of_file
421
        call    cd_get_parameters_of_file
422
        add     [cd_mem_location], 304
422
        add     [cd_mem_location], 304
423
        jmp     .get_names_from_buffer_1
423
        jmp     .get_names_from_buffer_1
424
;--------------------------------------
424
;--------------------------------------
425
.ansi_parent_directory:
425
.ansi_parent_directory:
426
        cmp     [cd_counter_block], 2
426
        cmp     [cd_counter_block], 2
427
        je      @f
427
        je      @f
428
 
428
 
429
        mov     [edi], byte '.'
429
        mov     [edi], byte '.'
430
        inc     edi
430
        inc     edi
431
        jmp     .cd_get_parameters_of_file_1
431
        jmp     .cd_get_parameters_of_file_1
432
;--------------------------------------
432
;--------------------------------------
433
@@:
433
@@:
434
        mov     [edi], word '..'
434
        mov     [edi], word '..'
435
        add     edi, 2
435
        add     edi, 2
436
        jmp     .cd_get_parameters_of_file_1
436
        jmp     .cd_get_parameters_of_file_1
437
;--------------------------------------
437
;--------------------------------------
438
.unicode:
438
.unicode:
439
        cmp     [cd_counter_block], 2
439
        cmp     [cd_counter_block], 2
440
        jbe     .unicode_parent_directory
440
        jbe     .unicode_parent_directory
441
 
441
 
442
        cld
442
        cld
443
        movsw
443
        movsw
444
; check end of file
444
; check end of file
445
        mov     ax, [esi]
445
        mov     ax, [esi]
446
        cmp     ax, word 3B00h; separator end of file ';'
446
        cmp     ax, word 3B00h; separator end of file ';'
447
        je      .cd_get_parameters_of_file_2
447
        je      .cd_get_parameters_of_file_2
448
; check for files not ending with separator
448
; check for files not ending with separator
449
        movzx   eax, byte [ebp-33]
449
        movzx   eax, byte [ebp-33]
450
        add     eax, ebp
450
        add     eax, ebp
451
        sub     eax, 34
451
        sub     eax, 34
452
        cmp     esi, eax
452
        cmp     esi, eax
453
        je      .cd_get_parameters_of_file_2
453
        je      .cd_get_parameters_of_file_2
454
; check the end of the directory
454
; check the end of the directory
455
        movzx   eax, byte [ebp-1]
455
        movzx   eax, byte [ebp-1]
456
        add     eax, ebp
456
        add     eax, ebp
457
        cmp     esi, eax
457
        cmp     esi, eax
458
        jb      .unicode
458
        jb      .unicode
459
;--------------------------------------
459
;--------------------------------------
460
.cd_get_parameters_of_file_2:
460
.cd_get_parameters_of_file_2:
461
        mov     [edi], word 0
461
        mov     [edi], word 0
462
        call    cd_get_parameters_of_file
462
        call    cd_get_parameters_of_file
463
        add     [cd_mem_location], 560
463
        add     [cd_mem_location], 560
464
        jmp     .get_names_from_buffer_1
464
        jmp     .get_names_from_buffer_1
465
;--------------------------------------
465
;--------------------------------------
466
.unicode_parent_directory:
466
.unicode_parent_directory:
467
        cmp     [cd_counter_block], 2
467
        cmp     [cd_counter_block], 2
468
        je      @f
468
        je      @f
469
 
469
 
470
        mov     [edi], word 2E00h; '.'
470
        mov     [edi], word 2E00h; '.'
471
        add     edi, 2
471
        add     edi, 2
472
        jmp     .cd_get_parameters_of_file_2
472
        jmp     .cd_get_parameters_of_file_2
473
;--------------------------------------
473
;--------------------------------------
474
@@:
474
@@:
475
        mov     [edi], dword 2E002E00h; '..'
475
        mov     [edi], dword 2E002E00h; '..'
476
        add     edi, 4
476
        add     edi, 4
477
        jmp     .cd_get_parameters_of_file_2
477
        jmp     .cd_get_parameters_of_file_2
478
;--------------------------------------
478
;--------------------------------------
479
.end_buffer:
479
.end_buffer:
480
        pop     edx edi esi eax
480
        pop     edx edi esi eax
481
        ret
481
        ret
482
;-----------------------------------------------------------------------------
482
;-----------------------------------------------------------------------------
483
cd_get_parameters_of_file:
483
cd_get_parameters_of_file:
484
        mov     edi, [cd_mem_location]
484
        mov     edi, [cd_mem_location]
485
cd_get_parameters_of_file_1:
485
cd_get_parameters_of_file_1:
486
; get file attributes
486
; get file attributes
487
        xor     eax, eax
487
        xor     eax, eax
488
; file is not archived
488
; file is not archived
489
        inc     eax
489
        inc     eax
490
        shl     eax, 1
490
        shl     eax, 1
491
; is a directory?
491
; is a directory?
492
        test    [ebp-8], byte 2
492
        test    [ebp-8], byte 2
493
        jz      .file
493
        jz      .file
494
 
494
 
495
        inc     eax
495
        inc     eax
496
;--------------------------------------
496
;--------------------------------------
497
.file:
497
.file:
498
; not as a volume label in the FAT, in this form not available
498
; not as a volume label in the FAT, in this form not available
499
; file is not a system
499
; file is not a system
500
        shl     eax, 3
500
        shl     eax, 3
501
; file is hidden? (attribute of existence)
501
; file is hidden? (attribute of existence)
502
        test    [ebp-8], byte 1
502
        test    [ebp-8], byte 1
503
        jz      .hidden
503
        jz      .hidden
504
 
504
 
505
        inc     eax
505
        inc     eax
506
;--------------------------------------
506
;--------------------------------------
507
.hidden:
507
.hidden:
508
        shl     eax, 1
508
        shl     eax, 1
509
; file is always read-only, as this CD
509
; file is always read-only, as this CD
510
        inc     eax
510
        inc     eax
511
        mov     [edi], eax
511
        mov     [edi], eax
512
; get the time to file
512
; get the time to file
513
; hour
513
; hour
514
        movzx   eax, byte [ebp-12]
514
        movzx   eax, byte [ebp-12]
515
        shl     eax, 8
515
        shl     eax, 8
516
; minute
516
; minute
517
        mov     al, [ebp-11]
517
        mov     al, [ebp-11]
518
        shl     eax, 8
518
        shl     eax, 8
519
; second
519
; second
520
        mov     al, [ebp-10]
520
        mov     al, [ebp-10]
521
; file creation time
521
; file creation time
522
        mov     [edi+8], eax
522
        mov     [edi+8], eax
523
; last access time
523
; last access time
524
        mov     [edi+16], eax
524
        mov     [edi+16], eax
525
; last write time
525
; last write time
526
        mov     [edi+24], eax
526
        mov     [edi+24], eax
527
; get date for file
527
; get date for file
528
; year
528
; year
529
        movzx   eax, byte [ebp-15]
529
        movzx   eax, byte [ebp-15]
530
        add     eax, 1900
530
        add     eax, 1900
531
        shl     eax, 8
531
        shl     eax, 8
532
; month
532
; month
533
        mov     al, [ebp-14]
533
        mov     al, [ebp-14]
534
        shl     eax, 8
534
        shl     eax, 8
535
; day
535
; day
536
        mov     al, [ebp-13]
536
        mov     al, [ebp-13]
537
; file creation date
537
; file creation date
538
        mov     [edi+12], eax
538
        mov     [edi+12], eax
539
; last access date
539
; last access date
540
        mov     [edi+20], eax
540
        mov     [edi+20], eax
541
; last write date 
541
; last write date 
542
        mov     [edi+28], eax
542
        mov     [edi+28], eax
543
; get the data type of name
543
; get the data type of name
544
        xor     eax, eax
544
        xor     eax, eax
545
        test    dword [ebx+4], 1; 0=ANSI, 1=UNICODE
545
        test    dword [ebx+4], 1; 0=ANSI, 1=UNICODE
546
        jnz     .unicode_1
546
        jnz     .unicode_1
547
 
547
 
548
        mov     [edi+4], eax
548
        mov     [edi+4], eax
549
        jmp     @f
549
        jmp     @f
550
;--------------------------------------
550
;--------------------------------------
551
.unicode_1:
551
.unicode_1:
552
        inc     eax
552
        inc     eax
553
        mov     [edi+4], eax
553
        mov     [edi+4], eax
554
;--------------------------------------
554
;--------------------------------------
555
@@:
555
@@:
556
; get the file size in bytes
556
; get the file size in bytes
557
        xor     eax, eax
557
        xor     eax, eax
558
        mov     [edi+32+4], eax
558
        mov     [edi+32+4], eax
559
        mov     eax, [ebp-23]
559
        mov     eax, [ebp-23]
560
        mov     [edi+32], eax
560
        mov     [edi+32], eax
561
        ret
561
        ret
562
;-----------------------------------------------------------------------------
562
;-----------------------------------------------------------------------------
563
;
563
;
564
;  fs_CdGetFileInfo - LFN variant for CD
564
;  fs_CdGetFileInfo - LFN variant for CD
565
;                     get file/directory attributes structure
565
;                     get file/directory attributes structure
566
;
566
;
567
;-----------------------------------------------------------------------------
567
;-----------------------------------------------------------------------------
568
fs_CdGetFileInfo:
568
fs_CdGetFileInfo:
569
        cmp     byte [esi], 0
569
        cmp     byte [esi], 0
570
        jnz     @f
570
        jnz     @f
571
 
571
 
572
        mov     eax, 2
572
        mov     eax, 2
573
        ret
573
        ret
574
;--------------------------------------
574
;--------------------------------------
575
@@:
575
@@:
576
        push    edi
576
        push    edi
577
        call    cd_find_lfn
577
        call    cd_find_lfn
578
        pushfd
578
        pushfd
579
        cmp     [DevErrorCode], 0
579
        cmp     [DevErrorCode], 0
580
        jz      @f
580
        jz      @f
581
 
581
 
582
        popfd
582
        popfd
583
        pop     edi
583
        pop     edi
584
        mov     eax, 11
584
        mov     eax, 11
585
        ret
585
        ret
586
;--------------------------------------
586
;--------------------------------------
587
@@:
587
@@:
588
        popfd
588
        popfd
589
        jnc     @f
589
        jnc     @f
590
 
590
 
591
        pop     edi
591
        pop     edi
592
        mov     eax, ERROR_FILE_NOT_FOUND
592
        mov     eax, ERROR_FILE_NOT_FOUND
593
        ret
593
        ret
594
;--------------------------------------
594
;--------------------------------------
595
@@:
595
@@:
596
 
596
 
597
        mov     edi, edx
597
        mov     edi, edx
598
        push    ebp
598
        push    ebp
599
        mov     ebp, [cd_current_pointer_of_input]
599
        mov     ebp, [cd_current_pointer_of_input]
600
        add     ebp, 33
600
        add     ebp, 33
601
        call    cd_get_parameters_of_file_1
601
        call    cd_get_parameters_of_file_1
602
        pop     ebp
602
        pop     ebp
603
        and     dword [edi+4], 0
603
        and     dword [edi+4], 0
604
        pop     edi
604
        pop     edi
605
        xor     eax, eax
605
        xor     eax, eax
606
        ret
606
        ret
607
;-----------------------------------------------------------------------------
607
;-----------------------------------------------------------------------------
608
cd_find_lfn:
608
cd_find_lfn:
609
        mov     [cd_appl_data], 0
609
        mov     [cd_appl_data], 0
610
; in: esi+ebp -> name
610
; in: esi+ebp -> name
611
; out: CF=1 - file not found
611
; out: CF=1 - file not found
612
; else CF=0 and [cd_current_pointer_of_input] direntry
612
; else CF=0 and [cd_current_pointer_of_input] direntry
613
        push    eax esi
613
        push    eax esi
614
; Sector 16 - start set of volume descriptors
614
; Sector 16 - start set of volume descriptors
615
        call    WaitUnitReady
615
        call    WaitUnitReady
616
        cmp     [DevErrorCode], 0
616
        cmp     [DevErrorCode], 0
617
        jne     .access_denied
617
        jne     .access_denied
618
 
618
 
619
        call    prevent_medium_removal
619
        call    prevent_medium_removal
620
; testing of reading
620
; testing of reading
621
        mov     [CDSectorAddress], dword 16
621
        mov     [CDSectorAddress], dword 16
622
        mov     [CDDataBuf_pointer], CDDataBuf
622
        mov     [CDDataBuf_pointer], CDDataBuf
623
        call    ReadCDWRetr;_1
623
        call    ReadCDWRetr;_1
624
        cmp     [DevErrorCode], 0
624
        cmp     [DevErrorCode], 0
625
        jne     .access_denied
625
        jne     .access_denied
626
 
626
 
627
; calculation of the last session
627
; calculation of the last session
628
        call    WaitUnitReady
628
        call    WaitUnitReady
629
        cmp     [DevErrorCode], 0
629
        cmp     [DevErrorCode], 0
630
        jne     .access_denied
630
        jne     .access_denied
631
 
631
 
632
        call    Read_TOC
632
        call    Read_TOC
633
        mov     ah, [CDDataBuf+4+4]
633
        mov     ah, [CDDataBuf+4+4]
634
        mov     al, [CDDataBuf+4+5]
634
        mov     al, [CDDataBuf+4+5]
635
        shl     eax, 16
635
        shl     eax, 16
636
        mov     ah, [CDDataBuf+4+6]
636
        mov     ah, [CDDataBuf+4+6]
637
        mov     al, [CDDataBuf+4+7]
637
        mov     al, [CDDataBuf+4+7]
638
        add     eax, 15
638
        add     eax, 15
639
        mov     [CDSectorAddress], eax
639
        mov     [CDSectorAddress], eax
640
;  mov  [CDSectorAddress],dword 15
640
;  mov  [CDSectorAddress],dword 15
641
        mov     [CDDataBuf_pointer], CDDataBuf
641
        mov     [CDDataBuf_pointer], CDDataBuf
642
;--------------------------------------
642
;--------------------------------------
643
.start:
643
.start:
644
        inc     dword [CDSectorAddress]
644
        inc     dword [CDSectorAddress]
645
        call    ReadCDWRetr;_1
645
        call    ReadCDWRetr;_1
646
        cmp     [DevErrorCode], 0
646
        cmp     [DevErrorCode], 0
647
        jne     .access_denied
647
        jne     .access_denied
648
 
648
 
649
.start_check:
649
.start_check:
650
; checking for "lice"
650
; checking for "lice"
651
        cmp     [CDDataBuf+1], dword 'CD00'
651
        cmp     [CDDataBuf+1], dword 'CD00'
652
        jne     .access_denied
652
        jne     .access_denied
653
 
653
 
654
        cmp     [CDDataBuf+5], byte '1'
654
        cmp     [CDDataBuf+5], byte '1'
655
        jne     .access_denied
655
        jne     .access_denied
656
; sector is the terminator of set of descriptors volumes?
656
; sector is the terminator of set of descriptors volumes?
657
        cmp     [CDDataBuf], byte 0xff
657
        cmp     [CDDataBuf], byte 0xff
658
        je      .access_denied
658
        je      .access_denied
659
; sector is an additional and improved descriptor of volume?
659
; sector is an additional and improved descriptor of volume?
660
        cmp     [CDDataBuf], byte 0x2
660
        cmp     [CDDataBuf], byte 0x2
661
        jne     .start
661
        jne     .start
662
; sector is an additional descriptor of volume?
662
; sector is an additional descriptor of volume?
663
        cmp     [CDDataBuf+6], byte 0x1
663
        cmp     [CDDataBuf+6], byte 0x1
664
        jne     .start
664
        jne     .start
665
 
665
 
666
; parameters of root directory
666
; parameters of root directory
667
        mov     eax, [CDDataBuf+0x9c+2]; start of root directory
667
        mov     eax, [CDDataBuf+0x9c+2]; start of root directory
668
        mov     [CDSectorAddress], eax
668
        mov     [CDSectorAddress], eax
669
        mov     eax, [CDDataBuf+0x9c+10]; size of root directory
669
        mov     eax, [CDDataBuf+0x9c+10]; size of root directory
670
        cmp     byte [esi], 0
670
        cmp     byte [esi], 0
671
        jnz     @f
671
        jnz     @f
672
 
672
 
673
        mov     [cd_current_pointer_of_input], CDDataBuf+0x9c
673
        mov     [cd_current_pointer_of_input], CDDataBuf+0x9c
674
        jmp     .done
674
        jmp     .done
675
;--------------------------------------
675
;--------------------------------------
676
@@:
676
@@:
677
; start the search
677
; start the search
678
.mainloop:
678
.mainloop:
679
        dec     dword [CDSectorAddress]
679
        dec     dword [CDSectorAddress]
680
;--------------------------------------
680
;--------------------------------------
681
.read_to_buffer:
681
.read_to_buffer:
682
        inc     dword [CDSectorAddress]
682
        inc     dword [CDSectorAddress]
683
        mov     [CDDataBuf_pointer], CDDataBuf
683
        mov     [CDDataBuf_pointer], CDDataBuf
684
        call    ReadCDWRetr      ; read sector of directory
684
        call    ReadCDWRetr      ; read sector of directory
685
        cmp     [DevErrorCode], 0
685
        cmp     [DevErrorCode], 0
686
        jne     .access_denied
686
        jne     .access_denied
687
 
687
 
688
        push    ebp
688
        push    ebp
689
        call    cd_find_name_in_buffer
689
        call    cd_find_name_in_buffer
690
        pop     ebp
690
        pop     ebp
691
        jnc     .found
691
        jnc     .found
692
 
692
 
693
        sub     eax, 2048
693
        sub     eax, 2048
694
; directory is over?
694
; directory is over?
695
        cmp     eax, 0
695
        cmp     eax, 0
696
        ja      .read_to_buffer
696
        ja      .read_to_buffer
697
; desired element of chain is not found
697
; desired element of chain is not found
698
.access_denied:
698
.access_denied:
699
        pop     esi eax
699
        pop     esi eax
700
        mov     [cd_appl_data], 1
700
        mov     [cd_appl_data], 1
701
        stc
701
        stc
702
        ret
702
        ret
703
;--------------------------------------
703
;--------------------------------------
704
; desired element of chain found
704
; desired element of chain found
705
.found:
705
.found:
706
; the end of the file path
706
; the end of the file path
707
        cmp     byte [esi-1], 0
707
        cmp     byte [esi-1], 0
708
        jz      .done
708
        jz      .done
709
  .nested:
709
  .nested:
710
        mov     eax, [cd_current_pointer_of_input]
710
        mov     eax, [cd_current_pointer_of_input]
711
        push    dword [eax+2]
711
        push    dword [eax+2]
712
        pop     dword [CDSectorAddress] ; beginning of the directory
712
        pop     dword [CDSectorAddress] ; beginning of the directory
713
        mov     eax, [eax+2+8] ; size of directory
713
        mov     eax, [eax+2+8] ; size of directory
714
        jmp     .mainloop
714
        jmp     .mainloop
715
;--------------------------------------
715
;--------------------------------------
716
; file pointer found
716
; file pointer found
717
.done:
717
.done:
718
        test    ebp, ebp
718
        test    ebp, ebp
719
        jz      @f
719
        jz      @f
720
 
720
 
721
        mov     esi, ebp
721
        mov     esi, ebp
722
        xor     ebp, ebp
722
        xor     ebp, ebp
723
        jmp     .nested
723
        jmp     .nested
724
;--------------------------------------
724
;--------------------------------------
725
@@:
725
@@:
726
        pop     esi eax
726
        pop     esi eax
727
        mov     [cd_appl_data], 1
727
        mov     [cd_appl_data], 1
728
        clc
728
        clc
729
        ret
729
        ret
730
;-----------------------------------------------------------------------------
730
;-----------------------------------------------------------------------------
731
cd_find_name_in_buffer:
731
cd_find_name_in_buffer:
732
        mov     [cd_current_pointer_of_input_2], CDDataBuf
732
        mov     [cd_current_pointer_of_input_2], CDDataBuf
733
;--------------------------------------
733
;--------------------------------------
734
.start:
734
.start:
735
        call    cd_get_name
735
        call    cd_get_name
736
        jc      .not_found
736
        jc      .not_found
737
 
737
 
738
        call    cd_compare_name
738
        call    cd_compare_name
739
        jc      .start
739
        jc      .start
740
;--------------------------------------
740
;--------------------------------------
741
.found:
741
.found:
742
        clc
742
        clc
743
        ret
743
        ret
744
;--------------------------------------
744
;--------------------------------------
745
.not_found:
745
.not_found:
746
        stc
746
        stc
747
        ret
747
        ret
748
;-----------------------------------------------------------------------------
748
;-----------------------------------------------------------------------------
749
cd_get_name:
749
cd_get_name:
750
        push    eax
750
        push    eax
751
        mov     ebp, [cd_current_pointer_of_input_2]
751
        mov     ebp, [cd_current_pointer_of_input_2]
752
        mov     [cd_current_pointer_of_input], ebp
752
        mov     [cd_current_pointer_of_input], ebp
753
        mov     eax, [ebp]
753
        mov     eax, [ebp]
754
        test    eax, eax ; entry's is over?
754
        test    eax, eax ; entry's is over?
755
        jz      .next_sector
755
        jz      .next_sector
756
 
756
 
757
        cmp     ebp, CDDataBuf+2048  ; buffer is over?
757
        cmp     ebp, CDDataBuf+2048  ; buffer is over?
758
        jae     .next_sector
758
        jae     .next_sector
759
 
759
 
760
        movzx   eax, byte [ebp]
760
        movzx   eax, byte [ebp]
761
        add     [cd_current_pointer_of_input_2], eax ; next entry of directory
761
        add     [cd_current_pointer_of_input_2], eax ; next entry of directory
762
        add     ebp, 33; pointer is set to the beginning of the name
762
        add     ebp, 33; pointer is set to the beginning of the name
763
        pop     eax
763
        pop     eax
764
        clc
764
        clc
765
        ret
765
        ret
766
;--------------------------------------
766
;--------------------------------------
767
.next_sector:
767
.next_sector:
768
        pop     eax
768
        pop     eax
769
        stc
769
        stc
770
        ret
770
        ret
771
;-----------------------------------------------------------------------------
771
;-----------------------------------------------------------------------------
772
cd_compare_name:
772
cd_compare_name:
773
; compares ASCIIZ-names, case-insensitive (cp866 encoding)
773
; compares ASCIIZ-names, case-insensitive (cp866 encoding)
774
; in: esi->name, ebp->name
774
; in: esi->name, ebp->name
775
; out: if names match: ZF=1 and esi->next component of name
775
; out: if names match: ZF=1 and esi->next component of name
776
;      else: ZF=0, esi is not changed
776
;      else: ZF=0, esi is not changed
777
; destroys eax
777
; destroys eax
778
        push    esi eax edi
778
        push    esi eax edi
779
        mov     edi, ebp
779
        mov     edi, ebp
780
;--------------------------------------
780
;--------------------------------------
781
.loop:
781
.loop:
782
        cld
782
        cld
783
        lodsb
783
        lodsb
784
        push    eax
784
        push    eax
785
        call    char_todown
785
        call    char_todown
786
        call    ansi2uni_char
786
        call    ansi2uni_char
787
        xchg    ah, al
787
        xchg    ah, al
788
        scasw
788
        scasw
789
        pop     eax
789
        pop     eax
790
        je      .coincides
790
        je      .coincides
791
        call    char_toupper
791
        call    char_toupper
792
        call    ansi2uni_char
792
        call    ansi2uni_char
793
        xchg    ah, al
793
        xchg    ah, al
794
        sub     edi, 2
794
        sub     edi, 2
795
        scasw
795
        scasw
796
        jne     .name_not_coincide
796
        jne     .name_not_coincide
797
;--------------------------------------
797
;--------------------------------------
798
.coincides:
798
.coincides:
799
        cmp     [esi], byte '/' ; path separator is end of current element
799
        cmp     [esi], byte '/' ; path separator is end of current element
800
        je      .done
800
        je      .done
801
 
801
 
802
        cmp     [esi], byte 0 ; path separator end of name
802
        cmp     [esi], byte 0 ; path separator end of name
803
        je      .done
803
        je      .done
804
 
804
 
805
        jmp     .loop
805
        jmp     .loop
806
;--------------------------------------
806
;--------------------------------------
807
.name_not_coincide:
807
.name_not_coincide:
808
        pop     edi eax esi
808
        pop     edi eax esi
809
        stc
809
        stc
810
        ret
810
        ret
811
;--------------------------------------
811
;--------------------------------------
812
.done:
812
.done:
813
; check end of file
813
; check end of file
814
        cmp     [edi], word 3B00h; separator end of file ';'
814
        cmp     [edi], word 3B00h; separator end of file ';'
815
        je      .done_1
815
        je      .done_1
816
; check for files not ending with separator
816
; check for files not ending with separator
817
        movzx   eax, byte [ebp-33]
817
        movzx   eax, byte [ebp-33]
818
        add     eax, ebp
818
        add     eax, ebp
819
        sub     eax, 34
819
        sub     eax, 34
820
        cmp     edi, eax
820
        cmp     edi, eax
821
        je      .done_1
821
        je      .done_1
822
; check the end of directory
822
; check the end of directory
823
        movzx   eax, byte [ebp-1]
823
        movzx   eax, byte [ebp-1]
824
        add     eax, ebp
824
        add     eax, ebp
825
        cmp     edi, eax
825
        cmp     edi, eax
826
        jne     .name_not_coincide
826
        jne     .name_not_coincide
827
;--------------------------------------
827
;--------------------------------------
828
.done_1:
828
.done_1:
829
        pop     edi eax
829
        pop     edi eax
830
        add     esp, 4
830
        add     esp, 4
831
        inc     esi
831
        inc     esi
832
        clc
832
        clc
833
        ret
833
        ret
834
;-----------------------------------------------------------------------------
834
;-----------------------------------------------------------------------------
835
char_todown:
835
char_todown:
836
; convert character to uppercase, using cp866 encoding
836
; convert character to uppercase, using cp866 encoding
837
; in: al=symbol
837
; in: al=symbol
838
; out: al=converted symbol
838
; out: al=converted symbol
839
        cmp     al, 'A'
839
        cmp     al, 'A'
840
        jb      .ret
840
        jb      .ret
841
 
841
 
842
        cmp     al, 'Z'
842
        cmp     al, 'Z'
843
        jbe     .az
843
        jbe     .az
844
 
844
 
845
        cmp     al, 0x80 ; 'А'
845
        cmp     al, 0x80 ; 'А'
846
        jb      .ret
846
        jb      .ret
847
 
847
 
848
        cmp     al, 0x90 ; 'Р'
848
        cmp     al, 0x90 ; 'Р'
849
        jb      .rus1
849
        jb      .rus1
850
 
850
 
851
        cmp     al, 0x9F ; 'Я'
851
        cmp     al, 0x9F ; 'Я'
852
        ja      .ret
852
        ja      .ret
853
; 0x90-0x9F -> 0xE0-0xEF
853
; 0x90-0x9F -> 0xE0-0xEF
854
        add     al, 0xE0-0x90
854
        add     al, 0xE0-0x90
855
;--------------------------------------
855
;--------------------------------------
856
.ret:
856
.ret:
857
        ret
857
        ret
858
;--------------------------------------
858
;--------------------------------------
859
.rus1:
859
.rus1:
860
; 0x80-0x8F -> 0xA0-0xAF
860
; 0x80-0x8F -> 0xA0-0xAF
861
.az:
861
.az:
862
        add     al, 0x20
862
        add     al, 0x20
863
        ret
863
        ret
864
;-----------------------------------------------------------------------------
864
;-----------------------------------------------------------------------------
865
uni2ansi_char:
865
uni2ansi_char:
866
; convert UNICODE character in al to ANSI character in ax, using cp866 encoding
866
; convert UNICODE character in al to ANSI character in ax, using cp866 encoding
867
; in: ax=UNICODE character
867
; in: ax=UNICODE character
868
; out: al=converted ANSI character
868
; out: al=converted ANSI character
869
        cmp     ax, 0x80
869
        cmp     ax, 0x80
870
        jb      .ascii
870
        jb      .ascii
871
 
871
 
872
        cmp     ax, 0x401
872
        cmp     ax, 0x401
873
        jz      .yo1
873
        jz      .yo1
874
 
874
 
875
        cmp     ax, 0x451
875
        cmp     ax, 0x451
876
        jz      .yo2
876
        jz      .yo2
877
 
877
 
878
        cmp     ax, 0x410
878
        cmp     ax, 0x410
879
        jb      .unk
879
        jb      .unk
880
 
880
 
881
        cmp     ax, 0x440
881
        cmp     ax, 0x440
882
        jb      .rus1
882
        jb      .rus1
883
 
883
 
884
        cmp     ax, 0x450
884
        cmp     ax, 0x450
885
        jb      .rus2
885
        jb      .rus2
886
;--------------------------------------
886
;--------------------------------------
887
.unk:
887
.unk:
888
        mov     al, '_'
888
        mov     al, '_'
889
        jmp     .doit
889
        jmp     .doit
890
;--------------------------------------
890
;--------------------------------------
891
.yo1:
891
.yo1:
892
        mov     al, 0xF0 ; 'Ё' in cp866
892
        mov     al, 0xF0 ; 'Ё' in cp866
893
        jmp     .doit
893
        jmp     .doit
894
;--------------------------------------
894
;--------------------------------------
895
.yo2:
895
.yo2:
896
        mov     al, 0xF1 ; 'ё' in cp866
896
        mov     al, 0xF1 ; 'ё' in cp866
897
        jmp     .doit
897
        jmp     .doit
898
;--------------------------------------
898
;--------------------------------------
899
.rus1:
899
.rus1:
900
; 0x410-0x43F -> 0x80-0xAF
900
; 0x410-0x43F -> 0x80-0xAF
901
        add     al, 0x70
901
        add     al, 0x70
902
        jmp     .doit
902
        jmp     .doit
903
;--------------------------------------
903
;--------------------------------------
904
.rus2:
904
.rus2:
905
; 0x440-0x44F -> 0xE0-0xEF
905
; 0x440-0x44F -> 0xE0-0xEF
906
        add     al, 0xA0
906
        add     al, 0xA0
907
;--------------------------------------
907
;--------------------------------------
908
.ascii:
908
.ascii:
909
.doit:
909
.doit:
910
        ret
910
        ret
911
;-----------------------------------------------------------------------------
911
;-----------------------------------------------------------------------------