Subversion Repositories Kolibri OS

Rev

Rev 3500 | Rev 4287 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 3500 Rev 3555
Line 7... Line 7...
7
;; (C) 2004 Ville Turjanmaa, License: GPL                       ;;
7
;; (C) 2004 Ville Turjanmaa, License: GPL                       ;;
8
;; Addings by M.Lisovin                                         ;;
8
;; Addings by M.Lisovin                                         ;;
9
;; LFN support by diamond                                       ;;
9
;; LFN support by diamond                                       ;;
10
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
10
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Line 11... Line 11...
11
 
11
 
Line 12... Line 12...
12
$Revision: 3500 $
12
$Revision: 3555 $
Line 13... Line 13...
13
 
13
 
Line 14... Line 14...
14
 
14
 
Line 15... Line 15...
15
; calculate fat chain
15
; calculate fat chain
16
 
16
 
Line 17... Line 17...
17
calculatefatchain:
17
calculatefatchain:
Line 43... Line 43...
43
        mov     dword [edi+12], edx
43
        mov     dword [edi+12], edx
44
        add     edi, 16
44
        add     edi, 16
45
        add     esi, 12
45
        add     esi, 12
Line 46... Line 46...
46
 
46
 
47
        cmp     edi, RAMDISK_FAT+2856*2;2849 clusters
47
        cmp     edi, RAMDISK_FAT+2856*2;2849 clusters
Line 48... Line 48...
48
   jnz	fcnew
48
        jnz     fcnew
49
 
49
 
Line 50... Line 50...
50
   popad
50
        popad
Line 51... Line 51...
51
   ret
51
        ret
Line 52... Line 52...
52
 
52
 
53
 
53
 
Line 54... Line 54...
54
restorefatchain:   ; restore fat chain
54
restorefatchain:   ; restore fat chain
Line 71... Line 71...
71
        mov     word [edi+4], bx
71
        mov     word [edi+4], bx
72
        add     edi, 6
72
        add     edi, 6
73
        add     esi, 8
73
        add     esi, 8
Line 74... Line 74...
74
 
74
 
75
        cmp     edi, RAMDISK+512+4278;4274 bytes - all used FAT
75
        cmp     edi, RAMDISK+512+4278;4274 bytes - all used FAT
Line 76... Line 76...
76
   jb	fcnew2
76
        jb      fcnew2
77
 
77
 
78
        mov     esi, RAMDISK+512  ; duplicate fat chain
78
        mov     esi, RAMDISK+512  ; duplicate fat chain
79
        mov     edi, RAMDISK+512+0x1200
79
        mov     edi, RAMDISK+512+0x1200
80
        mov     ecx, 1069;4274/4
80
        mov     ecx, 1069;4274/4
Line 81... Line 81...
81
   cld
81
        cld
82
   rep	movsd
82
        rep movsd
Line 83... Line 83...
83
 
83
 
84
   popad
84
        popad
85
   ret
85
        ret
86
 
86
 
87
 
87
 
88
ramdisk_free_space:
88
ramdisk_free_space:
Line 89... Line 89...
89
;---------------------------------------------
89
;---------------------------------------------
Line 90... Line 90...
90
;
90
;
91
; returns free space in edi
91
; returns free space in edi
92
; rewr.by Mihasik
92
; rewr.by Mihasik
93
;---------------------------------------------
93
;---------------------------------------------
94
 
94
 
95
	push   eax ebx ecx
95
        push    eax ebx ecx
96
 
96
 
97
        mov     edi, RAMDISK_FAT;start of FAT
97
        mov     edi, RAMDISK_FAT;start of FAT
98
        xor     ax, ax;Free cluster=0x0000 in FAT
98
        xor     ax, ax;Free cluster=0x0000 in FAT
99
        xor     ebx, ebx;counter
99
        xor     ebx, ebx;counter
100
        mov     ecx, 2849;2849 clusters
100
        mov     ecx, 2849;2849 clusters
101
	cld
101
        cld
102
    rdfs1:
102
    rdfs1:
103
	repne scasw
103
        repne scasw
Line 104... Line 104...
104
	jnz  rdfs2    ;if last cluster not 0
104
        jnz     rdfs2 ;if last cluster not 0
105
	inc  ebx
105
        inc     ebx
Line 106... Line 106...
106
	test	ecx, ecx
106
        test    ecx, ecx
107
	jnz	rdfs1
107
        jnz     rdfs1
108
    rdfs2:
108
    rdfs2:
109
        shl     ebx, 9;free clusters*512
109
        shl     ebx, 9;free clusters*512
110
        mov     edi, ebx
110
        mov     edi, ebx
111
 
111
 
Line 112... Line 112...
112
	pop    ecx ebx eax
112
        pop     ecx ebx eax
Line 113... Line 113...
113
	ret
113
        ret
114
 
114
 
Line 115... Line 115...
115
 
115
 
Line 133... Line 133...
133
        mov     [eax+8], dword '    '
133
        mov     [eax+8], dword '    '
Line 134... Line 134...
134
 
134
 
Line 135... Line 135...
135
      flr1:
135
      flr1:
136
 
136
 
137
        cmp     [esi], byte '.'
137
        cmp     [esi], byte '.'
138
	jne  flr2
138
        jne     flr2
139
        mov     edi, eax
139
        mov     edi, eax
Line 140... Line 140...
140
        add     edi, 7
140
        add     edi, 7
Line 141... Line 141...
141
	jmp  flr3
141
        jmp     flr3
142
 
142
 
Line 143... Line 143...
143
      flr2:
143
      flr2:
Line 144... Line 144...
144
 
144
 
145
        mov     bl, [esi]
145
        mov     bl, [esi]
Line 146... Line 146...
146
        mov     [edi], bl
146
        mov     [edi], bl
147
 
147
 
Line 148... Line 148...
148
      flr3:
148
      flr3:
149
 
149
 
Line 150... Line 150...
150
	inc  esi
150
        inc     esi
151
	inc  edi
151
        inc     edi
Line 152... Line 152...
152
 
152
 
153
        mov     ebx, eax
153
        mov     ebx, eax
154
        add     ebx, 11
154
        add     ebx, 11
155
 
155
 
Line 173... Line 173...
173
;  ret ebx = size or 0xffffffff file not found
173
;  ret ebx = size or 0xffffffff file not found
174
;      eax = 0 ok read or other = errormsg
174
;      eax = 0 ok read or other = errormsg
175
;
175
;
176
;--------------------------------------------------------------
176
;--------------------------------------------------------------
177
        test    ebx, ebx;if ebx=0 - set to 1
177
        test    ebx, ebx;if ebx=0 - set to 1
178
	jnz    frfl5
178
        jnz     frfl5
179
	inc    ebx
179
        inc     ebx
180
      frfl5:
180
      frfl5:
181
        test    ecx, ecx;if ecx=0 - set to 1
181
        test    ecx, ecx;if ecx=0 - set to 1
182
	jnz    frfl6
182
        jnz     frfl6
183
	inc    ecx
183
        inc     ecx
184
      frfl6:
184
      frfl6:
185
        test    esi, esi        ; return ramdisk root
185
        test    esi, esi        ; return ramdisk root
186
	jnz    fr_noroot	;if not root
186
        jnz     fr_noroot       ;if not root
187
        cmp     ebx, 14         ;14 clusters=root dir
187
        cmp     ebx, 14         ;14 clusters=root dir
188
	ja     oorr
188
        ja      oorr
189
        cmp     ecx, 14
189
        cmp     ecx, 14
190
	ja     oorr
190
        ja      oorr
191
	jmp    fr_do
191
        jmp     fr_do
192
      oorr:
192
      oorr:
193
        mov     eax, 5          ;out of root range (fnf)
193
        mov     eax, 5          ;out of root range (fnf)
194
        xor     ebx, ebx
194
        xor     ebx, ebx
195
	dec    ebx		;0xffffffff
195
        dec     ebx             ;0xffffffff
196
	ret
196
        ret
Line 197... Line 197...
197
 
197
 
198
      fr_do:			;reading rootdir
198
      fr_do:                    ;reading rootdir
199
        mov     edi, edx
199
        mov     edi, edx
200
	dec    ebx
200
        dec     ebx
201
	push   edx
201
        push    edx
202
        mov     edx, ecx
202
        mov     edx, ecx
203
        add     edx, ebx
203
        add     edx, ebx
204
        cmp     edx, 15   ;ebx+ecx=14+1
204
        cmp     edx, 15   ;ebx+ecx=14+1
205
	pushf
205
        pushf
206
	jbe    fr_do1
206
        jbe     fr_do1
207
        sub     edx, 14
207
        sub     edx, 14
208
        sub     ecx, edx
208
        sub     ecx, edx
209
      fr_do1:
209
      fr_do1:
210
        shl     ebx, 9
210
        shl     ebx, 9
211
        mov     esi, RAMDISK+512*19
211
        mov     esi, RAMDISK+512*19
212
        add     esi, ebx
212
        add     esi, ebx
213
        shl     ecx, 7
213
        shl     ecx, 7
214
	cld
214
        cld
215
	rep    movsd
215
        rep movsd
216
	popf
216
        popf
217
	pop    edx
217
        pop     edx
218
	jae    fr_do2
218
        jae     fr_do2
219
        xor     eax, eax; ok read
219
        xor     eax, eax; ok read
220
        xor     ebx, ebx
220
        xor     ebx, ebx
221
	ret
221
        ret
222
      fr_do2:	     ;if last cluster
222
      fr_do2:        ;if last cluster
223
        mov     eax, 6;end of file
223
        mov     eax, 6;end of file
224
        xor     ebx, ebx
224
        xor     ebx, ebx
Line 225... Line 225...
225
	ret
225
        ret
Line 226... Line 226...
226
 
226
 
227
     fr_noroot:
227
     fr_noroot:
Line 228... Line 228...
228
 
228
 
Line 229... Line 229...
229
        sub     esp, 32
229
        sub     esp, 32
Line 230... Line 230...
230
	call   expand_filename
230
        call    expand_filename
231
 
231
 
232
	dec    ebx
232
        dec     ebx
233
 
233
 
234
	push   eax
234
        push    eax
Line 235... Line 235...
235
 
235
 
Line 236... Line 236...
236
	push   eax ebx ecx edx esi edi
236
        push    eax ebx ecx edx esi edi
237
	call   rd_findfile
237
        call    rd_findfile
Line 255... Line 255...
255
        add     eax, RAMDISK           ;image base
255
        add     eax, RAMDISK           ;image base
256
        mov     ebx, [esp+8]
256
        mov     ebx, [esp+8]
257
        mov     ecx, 512                ;[esp+4]
257
        mov     ecx, 512                ;[esp+4]
Line 258... Line 258...
258
 
258
 
259
        cmp     [esp+16], dword 0       ; wanted cluster ?
259
        cmp     [esp+16], dword 0       ; wanted cluster ?
260
	jne    frfl7
260
        jne     frfl7
261
	call   memmove
261
        call    memmove
262
        add     [esp+8], dword 512
262
        add     [esp+8], dword 512
263
	dec    dword [esp+12]		; last wanted cluster ?
263
        dec     dword [esp+12]          ; last wanted cluster ?
264
	je     frnoread
264
        je      frnoread
265
	jmp    frfl8
265
        jmp     frfl8
266
      frfl7:
266
      frfl7:
267
	dec    dword [esp+16]
267
        dec     dword [esp+16]
268
      frfl8:
268
      frfl8:
269
        movzx   eax, word [edi*2+RAMDISK_FAT]      ; find next cluster from FAT
269
        movzx   eax, word [edi*2+RAMDISK_FAT]      ; find next cluster from FAT
270
        mov     edi, eax
270
        mov     edi, eax
271
        cmp     edi, 4095               ;eof  - cluster
271
        cmp     edi, 4095               ;eof  - cluster
Line 272... Line 272...
272
	jz     frnoread2
272
        jz      frnoread2
273
 
273
 
274
        cmp     [esp+24], dword 512     ;eof  - size
274
        cmp     [esp+24], dword 512     ;eof  - size
Line 275... Line 275...
275
	jb     frnoread
275
        jb      frnoread
Line 276... Line 276...
276
        sub     [esp+24], dword 512
276
        sub     [esp+24], dword 512
Line 277... Line 277...
277
 
277
 
278
	jmp    frnew
278
        jmp     frnew
Line 279... Line 279...
279
 
279
 
280
      frnoread2:
280
      frnoread2:
281
 
281
 
282
        cmp     [esp+16], dword 0       ; eof without read ?
282
        cmp     [esp+16], dword 0       ; eof without read ?
283
	je     frnoread
283
        je      frnoread
284
 
284
 
Line 285... Line 285...
285
	pop    edi esi edx ecx
285
        pop     edi esi edx ecx
Line 286... Line 286...
286
        add     esp, 4
286
        add     esp, 4
287
	pop    ebx     ; ebx <- eax : size of file
287
        pop     ebx    ; ebx <- eax : size of file
288
        add     esp, 36
288
        add     esp, 36
289
        mov     eax, 6 ; end of file
289
        mov     eax, 6 ; end of file
290
	ret
290
        ret
291
 
291
 
Line 292... Line 292...
292
      frnoread:
292
      frnoread:
293
 
293
 
294
	pop    edi esi edx ecx
294
        pop     edi esi edx ecx
Line 295... Line 295...
295
        add     esp, 4
295
        add     esp, 4
296
	pop    ebx     ; ebx <- eax : size of file
296
        pop     ebx    ; ebx <- eax : size of file
297
        add     esp, 36
297
        add     esp, 36
298
        xor     eax, eax;read ok
298
        xor     eax, eax;read ok
299
	ret
299
        ret
300
 
300
 
301
 
301
 
302
 
302
 
303
   rd_findfile:
303
   rd_findfile:
304
   ;by Mihasik
304
   ;by Mihasik
305
   ;IN: eax - pointer to filename OUT: filestring+11 in edi or notZero in flags and fnf in eax,ebx
305
   ;IN: eax - pointer to filename OUT: filestring+11 in edi or notZero in flags and fnf in eax,ebx
306
 
306
 
307
        mov     edi, RAMDISK+512*18+512;Point at directory
307
        mov     edi, RAMDISK+512*18+512;Point at directory
308
	cld
308
        cld
309
    rd_newsearch:
309
    rd_newsearch:
310
        mov     esi, eax
310
        mov     esi, eax
Line 311... Line 311...
311
        mov     ecx, 11
311
        mov     ecx, 11
Line 312... Line 312...
312
	rep    cmpsb
312
        rep cmpsb
313
	je     rd_ff
313
        je      rd_ff
314
        add     cl, 21
314
        add     cl, 21
315
        add     edi, ecx
315
        add     edi, ecx
316
        cmp     edi, RAMDISK+512*33
316
        cmp     edi, RAMDISK+512*33
317
	jb     rd_newsearch
317
        jb      rd_newsearch
318
        mov     eax, 5    ;if file not found - eax=5
318
        mov     eax, 5    ;if file not found - eax=5
319
        xor     ebx, ebx
319
        xor     ebx, ebx
320
	dec    ebx    ;ebx=0xffffffff and zf=0
320
        dec     ebx   ;ebx=0xffffffff and zf=0
321
     rd_ff:
321
     rd_ff:
322
	ret
322
        ret
323
 
323
 
324
; \begin{diamond}
324
; \begin{diamond}
325
 
325
 
326
uni2ansi_str:
326
uni2ansi_str:
327
; convert UNICODE zero-terminated string to ASCII-string (codepage 866)
327
; convert UNICODE zero-terminated string to ASCII-string (codepage 866)
328
; in: esi->source, edi->buffer (may be esi=edi)
328
; in: esi->source, edi->buffer (may be esi=edi)
329
; destroys: eax,esi,edi
329
; destroys: eax,esi,edi
330
	lodsw
330
        lodsw
331
	test	ax, ax
331
        test    ax, ax
332
	jz	.done
332
        jz      .done
333
	cmp	ax, 0x80
333
        cmp     ax, 0x80
334
	jb	.ascii
334
        jb      .ascii
335
	cmp	ax, 0x401
335
        cmp     ax, 0x401
336
	jz	.yo1
336
        jz      .yo1
337
	cmp	ax, 0x451
337
        cmp     ax, 0x451
338
	jz	.yo2
338
        jz      .yo2
339
	cmp	ax, 0x410
339
        cmp     ax, 0x410
340
	jb	.unk
340
        jb      .unk
341
	cmp	ax, 0x440
341
        cmp     ax, 0x440
342
	jb	.rus1
342
        jb      .rus1
343
	cmp	ax, 0x450
343
        cmp     ax, 0x450
344
	jb	.rus2
344
        jb      .rus2
345
.unk:
345
.unk:
346
	mov	al, '_'
346
        mov     al, '_'
347
	jmp	.doit
347
        jmp     .doit
348
.yo1:
348
.yo1:
349
	mov	al, 'ð'
349
        mov     al, 0xF0 ; 'Ё'
350
	jmp	.doit
350
        jmp     .doit
351
.yo2:
351
.yo2:
352
	mov	al, 'ñ'
352
        mov     al, 0xF1 ; 'ё'
353
	jmp	.doit
353
        jmp     .doit
Line 354... Line 354...
354
.rus1:
354
.rus1:
355
; 0x410-0x43F -> 0x80-0xAF
355
; 0x410-0x43F -> 0x80-0xAF
356
	add	al, 0x70
356
        add     al, 0x70
357
	jmp	.doit
357
        jmp     .doit
358
.rus2:
358
.rus2:
359
; 0x440-0x44F -> 0xE0-0xEF
359
; 0x440-0x44F -> 0xE0-0xEF
360
	add	al, 0xA0
360
        add     al, 0xA0
361
.ascii:
361
.ascii:
362
.doit:
362
.doit:
363
	stosb
363
        stosb
364
	jmp	uni2ansi_str
364
        jmp     uni2ansi_str
365
.done:
365
.done:
366
	mov	byte [edi], 0
366
        mov     byte [edi], 0
367
	ret
367
        ret
368
 
368
 
369
ansi2uni_char:
369
ansi2uni_char:
370
; convert ANSI character in al to UNICODE character in ax, using cp866 encoding
370
; convert ANSI character in al to UNICODE character in ax, using cp866 encoding
371
	mov	ah, 0
371
        mov     ah, 0
372
; 0x00-0x7F - trivial map
372
; 0x00-0x7F - trivial map
373
	cmp	al, 0x80
373
        cmp     al, 0x80
374
	jb	.ret
374
        jb      .ret
375
; 0x80-0xAF -> 0x410-0x43F
375
; 0x80-0xAF -> 0x410-0x43F
376
	cmp	al, 0xB0
376
        cmp     al, 0xB0
377
	jae	@f
377
        jae     @f
378
	add	ax, 0x410-0x80
378
        add     ax, 0x410-0x80
379
.ret:
379
.ret:
380
	ret
380
        ret
381
@@:
381
@@:
382
; 0xE0-0xEF -> 0x440-0x44F
382
; 0xE0-0xEF -> 0x440-0x44F
383
	cmp	al, 0xE0
383
        cmp     al, 0xE0
384
	jb	.unk
384
        jb      .unk
385
	cmp	al, 0xF0
385
        cmp     al, 0xF0
386
	jae	@f
386
        jae     @f
387
	add	ax, 0x440-0xE0
387
        add     ax, 0x440-0xE0
388
	ret
388
        ret
389
; 0xF0 -> 0x401
389
; 0xF0 -> 0x401
Line 390... Line 390...
390
; 0xF1 -> 0x451
390
; 0xF1 -> 0x451
391
@@:
391
@@:
392
	cmp	al, 'ð'
392
        cmp     al, 0xF0 ; 'Ё'
393
	jz	.yo1
393
        jz      .yo1
394
	cmp	al, 'ñ'
394
        cmp     al, 0xF1 ; 'ё'
395
	jz	.yo2
395
        jz      .yo2
396
.unk:
396
.unk:
397
	mov	al, '_' 	; ah=0
397
        mov     al, '_'         ; ah=0
398
	ret
398
        ret
399
.yo1:
399
.yo1:
400
	mov	ax, 0x401
400
        mov     ax, 0x401
401
	ret
401
        ret
402
.yo2:
402
.yo2:
403
	mov	ax, 0x451
403
        mov     ax, 0x451
404
	ret
404
        ret
405
 
405
 
406
char_toupper:
406
char_toupper:
407
; convert character to uppercase, using cp866 encoding
407
; convert character to uppercase, using cp866 encoding
408
; in: al=symbol
408
; in: al=symbol
409
; out: al=converted symbol
409
; out: al=converted symbol
410
	cmp	al, 'a'
410
        cmp     al, 'a'
411
	jb	.ret
411
        jb      .ret
412
	cmp	al, 'z'
412
        cmp     al, 'z'
413
	jbe	.az
413
        jbe     .az
414
        cmp     al, 'ñ'
414
        cmp     al, 0xF1 ; 'ё'
415
        jz      .yo1
415
        jz      .yo1
416
	cmp	al, ' '
416
        cmp     al, 0xA0 ; 'а'
417
	jb	.ret
417
        jb      .ret
418
	cmp	al, 'à'
418
        cmp     al, 0xE0 ; 'р'
Line 438... Line 438...
438
; out: CF=1 - no valid entry
438
; out: CF=1 - no valid entry
439
; else CF=0 and ebp->ASCIIZ-name
439
; else CF=0 and ebp->ASCIIZ-name
440
; (maximum length of filename is 255 (wide) symbols without trailing 0,
440
; (maximum length of filename is 255 (wide) symbols without trailing 0,
441
;  but implementation requires buffer 261 words)
441
;  but implementation requires buffer 261 words)
442
; destroys eax
442
; destroys eax
443
	cmp	byte [edi], 0
443
        cmp     byte [edi], 0
444
	jz	.no
444
        jz      .no
445
	cmp	byte [edi], 0xE5
445
        cmp     byte [edi], 0xE5
446
	jnz	@f
446
        jnz     @f
447
.no:
447
.no:
448
	stc
448
        stc
449
	ret
449
        ret
450
@@:
450
@@:
451
	cmp	byte [edi+11], 0xF
451
        cmp     byte [edi+11], 0xF
452
	jz	.longname
452
        jz      .longname
453
	test	byte [edi+11], 8
453
        test    byte [edi+11], 8
454
	jnz	.no
454
        jnz     .no
455
	push	ecx
455
        push    ecx
456
	push	edi ebp
456
        push    edi ebp
457
	test	byte [ebp-4], 1
457
        test    byte [ebp-4], 1
458
	jnz	.unicode_short
458
        jnz     .unicode_short
459
 
459
 
460
	mov	eax, [edi]
460
        mov     eax, [edi]
461
	mov	ecx, [edi+4]
461
        mov     ecx, [edi+4]
462
	mov	[ebp], eax
462
        mov     [ebp], eax
463
	mov	[ebp+4], ecx
463
        mov     [ebp+4], ecx
464
 
464
 
465
	mov	ecx, 8
465
        mov     ecx, 8
466
@@:
466
@@:
467
	cmp	byte [ebp+ecx-1], ' '
467
        cmp     byte [ebp+ecx-1], ' '
468
	loope	 @b
468
        loope   @b
469
 
469
 
470
	mov	eax, [edi+8]
470
        mov     eax, [edi+8]
471
	cmp	al, ' '
471
        cmp     al, ' '
472
	je	.done
472
        je      .done
473
	shl	eax, 8
473
        shl     eax, 8
474
	mov	al, '.'
474
        mov     al, '.'
475
 
475
 
476
	lea ebp, [ebp+ecx+1]
476
        lea     ebp, [ebp+ecx+1]
477
	mov	[ebp], eax
477
        mov     [ebp], eax
478
	mov	ecx, 3
478
        mov     ecx, 3
479
@@:
479
@@:
480
	rol eax, 8
480
        rol     eax, 8
481
	cmp al, ' '
481
        cmp     al, ' '
482
	jne .done
482
        jne     .done
483
	loop   @b
483
        loop    @b
484
	dec ebp
484
        dec     ebp
485
.done:
485
.done:
486
	and	byte [ebp+ecx+1], 0   ; CF=0
486
        and     byte [ebp+ecx+1], 0   ; CF=0
487
	pop	ebp edi ecx
487
        pop     ebp edi ecx
488
	ret
488
        ret
489
.unicode_short:
489
.unicode_short:
490
	mov	ecx, 8
490
        mov     ecx, 8
491
	push	ecx
491
        push    ecx
492
@@:
492
@@:
493
	mov	al, [edi]
493
        mov     al, [edi]
494
	inc	edi
494
        inc     edi
495
	call	ansi2uni_char
495
        call    ansi2uni_char
496
	mov	[ebp], ax
496
        mov     [ebp], ax
497
	inc	ebp
497
        inc     ebp
498
	inc	ebp
498
        inc     ebp
499
	loop	@b
499
        loop    @b
500
	pop	ecx
500
        pop     ecx
501
@@:
501
@@:
502
	cmp	word [ebp-2], ' '
502
        cmp     word [ebp-2], ' '
503
	jnz	@f
503
        jnz     @f
504
	dec	ebp
504
        dec     ebp
505
	dec	ebp
505
        dec     ebp
506
	loop	@b
506
        loop    @b
507
@@:
507
@@:
508
	mov	word [ebp], '.'
508
        mov     word [ebp], '.'
509
	inc	ebp
509
        inc     ebp
510
	inc	ebp
510
        inc     ebp
511
	mov	ecx, 3
511
        mov     ecx, 3
512
	push	ecx
512
        push    ecx
513
@@:
513
@@:
514
	mov	al, [edi]
514
        mov     al, [edi]
515
	inc	edi
515
        inc     edi
516
	call	ansi2uni_char
516
        call    ansi2uni_char
517
	mov	[ebp], ax
517
        mov     [ebp], ax
518
	inc	ebp
518
        inc     ebp
519
	inc	ebp
519
        inc     ebp
520
	loop	@b
520
        loop    @b
521
	pop	ecx
521
        pop     ecx
522
@@:
522
@@:
523
	cmp	word [ebp-2], ' '
523
        cmp     word [ebp-2], ' '
524
	jnz	@f
524
        jnz     @f
525
	dec	ebp
525
        dec     ebp
526
	dec	ebp
526
        dec     ebp
527
	loop	@b
527
        loop    @b
528
	dec	ebp
528
        dec     ebp
529
	dec	ebp
529
        dec     ebp
530
@@:
530
@@:
531
	and	word [ebp], 0	; CF=0
531
        and     word [ebp], 0   ; CF=0
532
	pop	ebp edi ecx
532
        pop     ebp edi ecx
533
	ret
533
        ret
534
.longname:
534
.longname:
535
; LFN
535
; LFN
536
	mov	al, byte [edi]
536
        mov     al, byte [edi]
537
	and	eax, 0x3F
537
        and     eax, 0x3F
538
	dec	eax
538
        dec     eax
539
	cmp	al, 20
539
        cmp     al, 20
540
	jae	.no	; ignore invalid entries
540
        jae     .no     ; ignore invalid entries
541
	mov	word [ebp+260*2], 0	; force null-terminating for orphans
541
        mov     word [ebp+260*2], 0     ; force null-terminating for orphans
542
	imul	eax, 13*2
542
        imul    eax, 13*2
543
	add	ebp, eax
543
        add     ebp, eax
544
	test	byte [edi], 0x40
544
        test    byte [edi], 0x40
545
	jz	@f
545
        jz      @f
546
	mov	word [ebp+13*2], 0
546
        mov     word [ebp+13*2], 0
547
@@:
547
@@:
548
	push	eax
548
        push    eax
549
; now copy name from edi to ebp ...
549
; now copy name from edi to ebp ...
550
	mov	eax, [edi+1]
550
        mov     eax, [edi+1]
551
	mov	[ebp], eax	; symbols 1,2
551
        mov     [ebp], eax      ; symbols 1,2
552
	mov	eax, [edi+5]
552
        mov     eax, [edi+5]
553
	mov	[ebp+4], eax	; 3,4
553
        mov     [ebp+4], eax    ; 3,4
554
	mov	eax, [edi+9]
554
        mov     eax, [edi+9]
555
	mov	[ebp+8], ax	; 5
555
        mov     [ebp+8], ax     ; 5
556
	mov	eax, [edi+14]
556
        mov     eax, [edi+14]
557
	mov	[ebp+10], eax	; 6,7
557
        mov     [ebp+10], eax   ; 6,7
558
	mov	eax, [edi+18]
558
        mov     eax, [edi+18]
559
	mov	[ebp+14], eax	; 8,9
559
        mov     [ebp+14], eax   ; 8,9
560
	mov	eax, [edi+22]
560
        mov     eax, [edi+22]
561
	mov	[ebp+18], eax	; 10,11
561
        mov     [ebp+18], eax   ; 10,11
562
	mov	eax, [edi+28]
562
        mov     eax, [edi+28]
563
	mov	[ebp+22], eax	; 12,13
563
        mov     [ebp+22], eax   ; 12,13
564
; ... done
564
; ... done
565
	pop	eax
565
        pop     eax
566
	sub	ebp, eax
566
        sub     ebp, eax
567
	test	eax, eax
567
        test    eax, eax
568
	jz	@f
568
        jz      @f
569
; if this is not first entry, more processing required
569
; if this is not first entry, more processing required
570
	stc
570
        stc
571
	ret
571
        ret
572
@@:
572
@@:
573
; if this is first entry:
573
; if this is first entry:
574
	test	byte [ebp-4], 1
574
        test    byte [ebp-4], 1
575
	jnz	.ret
575
        jnz     .ret
576
; buffer at ebp contains UNICODE name, convert it to ANSI
576
; buffer at ebp contains UNICODE name, convert it to ANSI
577
	push	esi edi
577
        push    esi edi
578
	mov	esi, ebp
578
        mov     esi, ebp
579
	mov	edi, ebp
579
        mov     edi, ebp
580
	call	uni2ansi_str
580
        call    uni2ansi_str
581
	pop	edi esi
581
        pop     edi esi
582
.ret:
582
.ret:
583
	clc
583
        clc
584
	ret
584
        ret
Line 585... Line 585...
585
 
585
 
586
fat_compare_name:
586
fat_compare_name:
587
; compares ASCIIZ-names, case-insensitive (cp866 encoding)
587
; compares ASCIIZ-names, case-insensitive (cp866 encoding)
588
; in: esi->name, ebp->name
588
; in: esi->name, ebp->name
589
; out: if names match: ZF=1 and esi->next component of name
589
; out: if names match: ZF=1 and esi->next component of name
590
;      else: ZF=0, esi is not changed
590
;      else: ZF=0, esi is not changed
591
; destroys eax
591
; destroys eax
592
	push	ebp esi
592
        push    ebp esi
593
.loop:
593
.loop:
594
	mov	al, [ebp]
594
        mov     al, [ebp]
595
	inc	ebp
595
        inc     ebp
596
	call	char_toupper
596
        call    char_toupper
597
	push	eax
597
        push    eax
598
	lodsb
598
        lodsb
599
	call	char_toupper
599
        call    char_toupper
600
	cmp	al, [esp]
600
        cmp     al, [esp]
601
	jnz	.done
601
        jnz     .done
602
	pop	eax
602
        pop     eax
603
	test	al, al
603
        test    al, al
604
	jnz	.loop
604
        jnz     .loop
605
	dec	esi
605
        dec     esi
606
	pop	eax
606
        pop     eax
607
	pop	ebp
607
        pop     ebp
608
	xor	eax, eax	; set ZF flag
608
        xor     eax, eax        ; set ZF flag
609
	ret
609
        ret
610
.done:
610
.done:
611
	cmp	al, '/'
611
        cmp     al, '/'
612
	jnz	@f
612
        jnz     @f
613
	cmp	byte [esp], 0
613
        cmp     byte [esp], 0
614
	jnz	@f
614
        jnz     @f
615
	mov	[esp+4], esi
615
        mov     [esp+4], esi
616
@@:
616
@@:
617
	pop	eax
617
        pop     eax
618
	pop	esi ebp
618
        pop     esi ebp
Line 619... Line 619...
619
	ret
619
        ret
620
 
620
 
621
fat_time_to_bdfe:
621
fat_time_to_bdfe:
622
; in: eax=FAT time
622
; in: eax=FAT time
623
; out: eax=BDFE time
623
; out: eax=BDFE time
624
	push	ecx edx
624
        push    ecx edx
625
	mov	ecx, eax
625
        mov     ecx, eax
626
	mov	edx, eax
626
        mov     edx, eax
627
	shr	eax, 11
627
        shr     eax, 11
628
	shl	eax, 16 ; hours
628
        shl     eax, 16 ; hours
629
	and	edx, 0x1F
629
        and     edx, 0x1F
630
	add	edx, edx
630
        add     edx, edx
631
	mov	al, dl	; seconds
631
        mov     al, dl  ; seconds
632
	shr	ecx, 5
632
        shr     ecx, 5
633
	and	ecx, 0x3F
633
        and     ecx, 0x3F
634
	mov	ah, cl	; minutes
634
        mov     ah, cl  ; minutes
Line 635... Line 635...
635
	pop	edx ecx
635
        pop     edx ecx
636
	ret
636
        ret
637
 
637
 
638
fat_date_to_bdfe:
638
fat_date_to_bdfe:
639
	push	ecx edx
639
        push    ecx edx
640
	mov	ecx, eax
640
        mov     ecx, eax
641
	mov	edx, eax
641
        mov     edx, eax
642
	shr	eax, 9
642
        shr     eax, 9
643
	add	ax, 1980
643
        add     ax, 1980
644
	shl	eax, 16 ; year
644
        shl     eax, 16 ; year
645
	and	edx, 0x1F
645
        and     edx, 0x1F
646
	mov	al, dl	; day
646
        mov     al, dl  ; day
647
	shr	ecx, 5
647
        shr     ecx, 5
648
	and	ecx, 0xF
648
        and     ecx, 0xF
Line 649... Line 649...
649
	mov	ah, cl	; month
649
        mov     ah, cl  ; month
650
	pop	edx ecx
650
        pop     edx ecx
651
	ret
651
        ret
652
 
652
 
653
bdfe_to_fat_time:
653
bdfe_to_fat_time:
654
	push	edx
654
        push    edx
655
	mov	edx, eax
655
        mov     edx, eax
656
	shr	eax, 16
656
        shr     eax, 16
657
	and	dh, 0x3F
657
        and     dh, 0x3F
658
	shl	eax, 6
658
        shl     eax, 6
659
	or	al, dh
659
        or      al, dh
660
	shr	dl, 1
660
        shr     dl, 1
661
	and	dl, 0x1F
661
        and     dl, 0x1F
Line 662... Line 662...
662
	shl	eax, 5
662
        shl     eax, 5
663
	or	al, dl
663
        or      al, dl
664
	pop	edx
664
        pop     edx
665
	ret
665
        ret
666
 
666
 
667
bdfe_to_fat_date:
667
bdfe_to_fat_date:
668
	push	edx
668
        push    edx
669
	mov	edx, eax
669
        mov     edx, eax
670
	shr	eax, 16
670
        shr     eax, 16
671
	sub	ax, 1980
671
        sub     ax, 1980
672
	and	dh, 0xF
672
        and     dh, 0xF
673
	shl	eax, 4
673
        shl     eax, 4
674
	or	al, dh
674
        or      al, dh
Line 675... Line 675...
675
	and	dl, 0x1F
675
        and     dl, 0x1F
676
	shl	eax, 5
676
        shl     eax, 5
677
	or	al, dl
677
        or      al, dl
678
	pop	edx
678
        pop     edx
679
	ret
679
        ret
680
 
680
 
681
fat_entry_to_bdfe:
681
fat_entry_to_bdfe:
682
; convert FAT entry at edi to BDFE (block of data of folder entry) at esi, advance esi
682
; convert FAT entry at edi to BDFE (block of data of folder entry) at esi, advance esi
683
; destroys eax
683
; destroys eax
684
	mov	eax, [ebp-4]
684
        mov     eax, [ebp-4]
685
	mov	[esi+4], eax	; ASCII/UNICODE name
685
        mov     [esi+4], eax    ; ASCII/UNICODE name
686
fat_entry_to_bdfe2:
686
fat_entry_to_bdfe2:
687
	movzx	eax, byte [edi+11]
687
        movzx   eax, byte [edi+11]
688
	mov	[esi], eax	; attributes
688
        mov     [esi], eax      ; attributes
689
	movzx	eax, word [edi+14]
689
        movzx   eax, word [edi+14]
690
	call	fat_time_to_bdfe
690
        call    fat_time_to_bdfe
691
	mov	[esi+8], eax	; creation time
691
        mov     [esi+8], eax    ; creation time
692
	movzx	eax, word [edi+16]
692
        movzx   eax, word [edi+16]
693
	call	fat_date_to_bdfe
693
        call    fat_date_to_bdfe
694
	mov	[esi+12], eax	; creation date
694
        mov     [esi+12], eax   ; creation date
695
	and	dword [esi+16], 0	; last access time is not supported on FAT
695
        and     dword [esi+16], 0       ; last access time is not supported on FAT
696
	movzx	eax, word [edi+18]
696
        movzx   eax, word [edi+18]
697
	call	fat_date_to_bdfe
697
        call    fat_date_to_bdfe
698
	mov	[esi+20], eax	; last access date
698
        mov     [esi+20], eax   ; last access date
699
	movzx	eax, word [edi+22]
699
        movzx   eax, word [edi+22]
700
	call	fat_time_to_bdfe
700
        call    fat_time_to_bdfe
701
	mov	[esi+24], eax	; last write time
701
        mov     [esi+24], eax   ; last write time
702
	movzx	eax, word [edi+24]
702
        movzx   eax, word [edi+24]
703
	call	fat_date_to_bdfe
703
        call    fat_date_to_bdfe
704
	mov	[esi+28], eax	; last write date
704
        mov     [esi+28], eax   ; last write date
705
	mov	eax, [edi+28]
705
        mov     eax, [edi+28]
706
	mov	[esi+32], eax	; file size (low dword)
706
        mov     [esi+32], eax   ; file size (low dword)
707
	xor	eax, eax
707
        xor     eax, eax
708
	mov	[esi+36], eax	; file size (high dword)
708
        mov     [esi+36], eax   ; file size (high dword)
709
	test	ebp, ebp
709
        test    ebp, ebp
710
	jz	.ret
710
        jz      .ret
711
	push	ecx edi
711
        push    ecx edi
712
	lea	edi, [esi+40]
712
        lea     edi, [esi+40]
713
	mov	esi, ebp
713
        mov     esi, ebp
714
	test	byte [esi-4], 1
714
        test    byte [esi-4], 1
715
	jz	.ansi
715
        jz      .ansi
716
	mov	ecx, 260/2
716
        mov     ecx, 260/2
717
	rep	movsd
717
        rep movsd
718
	mov	[edi-2], ax
718
        mov     [edi-2], ax
719
@@:
719
@@:
720
	mov	esi, edi
720
        mov     esi, edi
721
	pop	edi ecx
721
        pop     edi ecx
722
.ret:
722
.ret:
Line 723... Line 723...
723
	ret
723
        ret
724
.ansi:
724
.ansi:
725
	mov	ecx, 264/4
725
        mov     ecx, 264/4
726
	rep	movsd
726
        rep movsd
727
	mov	[edi-1], al
727
        mov     [edi-1], al
728
	jmp	@b
728
        jmp     @b
729
 
729
 
730
bdfe_to_fat_entry:
730
bdfe_to_fat_entry:
731
; convert BDFE at edx to FAT entry at edi
731
; convert BDFE at edx to FAT entry at edi
732
; destroys eax
732
; destroys eax
733
; attributes byte
733
; attributes byte
734
	test	byte [edi+11], 8	; volume label?
734
        test    byte [edi+11], 8        ; volume label?
735
	jnz	@f
735
        jnz     @f
736
	mov	al, [edx]
736
        mov     al, [edx]
737
	and	al, 0x27
737
        and     al, 0x27
738
	and	byte [edi+11], 0x10
738
        and     byte [edi+11], 0x10
739
	or	byte [edi+11], al
739
        or      byte [edi+11], al
740
@@:
740
@@:
741
	mov	eax, [edx+8]
741
        mov     eax, [edx+8]
742
	call	bdfe_to_fat_time
742
        call    bdfe_to_fat_time
743
	mov	[edi+14], ax		; creation time
743
        mov     [edi+14], ax            ; creation time
744
	mov	eax, [edx+12]
744
        mov     eax, [edx+12]
745
	call	bdfe_to_fat_date
745
        call    bdfe_to_fat_date
746
	mov	[edi+16], ax		; creation date
746
        mov     [edi+16], ax            ; creation date
747
	mov	eax, [edx+20]
747
        mov     eax, [edx+20]
748
	call	bdfe_to_fat_date
748
        call    bdfe_to_fat_date
749
	mov	[edi+18], ax		; last access date
749
        mov     [edi+18], ax            ; last access date
Line 750... Line 750...
750
	mov	eax, [edx+24]
750
        mov     eax, [edx+24]
751
	call	bdfe_to_fat_time
751
        call    bdfe_to_fat_time
752
	mov	[edi+22], ax		; last write time
752
        mov     [edi+22], ax            ; last write time
753
	mov	eax, [edx+28]
753
        mov     eax, [edx+28]
754
	call	bdfe_to_fat_date
754
        call    bdfe_to_fat_date
755
	mov	[edi+24], ax		; last write date
755
        mov     [edi+24], ax            ; last write date
756
	ret
756
        ret
757
 
757
 
758
ramdisk_root_first:
758
ramdisk_root_first:
Line 759... Line 759...
759
	mov	edi, RAMDISK+512*19
759
        mov     edi, RAMDISK+512*19
760
	clc
760
        clc
761
	ret
761
        ret
Line 762... Line 762...
762
ramdisk_root_next:
762
ramdisk_root_next:
763
	add	edi, 0x20
763
        add     edi, 0x20
764
	cmp	edi, RAMDISK+512*33
764
        cmp     edi, RAMDISK+512*33
765
	cmc
765
        cmc
766
	ret
766
        ret
Line 767... Line 767...
767
 
767
 
768
ramdisk_root_extend_dir:
768
ramdisk_root_extend_dir:
769
	stc
769
        stc
770
	ret
770
        ret
771
 
771
 
772
uglobal
772
uglobal
773
; this is for delete support
773
; this is for delete support
774
rd_prev_sector		dd	?
774
rd_prev_sector          dd      ?
775
rd_prev_prev_sector	dd	?
775
rd_prev_prev_sector     dd      ?
776
endg
776
endg
777
 
777
 
778
ramdisk_notroot_next:
778
ramdisk_notroot_next:
779
	add	edi, 0x20
779
        add     edi, 0x20
780
	test	edi, 0x1FF
780
        test    edi, 0x1FF
781
	jz	ramdisk_notroot_next_sector
781
        jz      ramdisk_notroot_next_sector
782
	ret	; CF=0
782
        ret     ; CF=0
783
ramdisk_notroot_next_sector:
783
ramdisk_notroot_next_sector:
784
	push	ecx
784
        push    ecx
785
	mov	ecx, [eax]
785
        mov     ecx, [eax]
786
	push	[rd_prev_sector]
786
        push    [rd_prev_sector]
787
	pop	[rd_prev_prev_sector]
787
        pop     [rd_prev_prev_sector]
788
	mov	[rd_prev_sector], ecx
788
        mov     [rd_prev_sector], ecx
789
	mov	ecx, [ecx*2+RAMDISK_FAT]
789
        mov     ecx, [ecx*2+RAMDISK_FAT]
790
	and	ecx, 0xFFF
790
        and     ecx, 0xFFF
791
	cmp	ecx, 2849
791
        cmp     ecx, 2849
792
	jae	ramdisk_notroot_first.err2
792
        jae     ramdisk_notroot_first.err2
793
	mov	[eax], ecx
793
        mov     [eax], ecx
794
	pop	ecx
794
        pop     ecx
795
ramdisk_notroot_first:
795
ramdisk_notroot_first:
796
	mov	eax, [eax]
796
        mov     eax, [eax]
797
	cmp	eax, 2
797
        cmp     eax, 2
798
	jb	.err
798
        jb      .err
799
	cmp	eax, 2849
799
        cmp     eax, 2849
800
	jae	.err
800
        jae     .err
801
	shl	eax, 9
801
        shl     eax, 9
802
	lea	edi, [eax+(31 shl 9)+RAMDISK]
802
        lea     edi, [eax+(31 shl 9)+RAMDISK]
803
	clc
803
        clc
Line 804... Line 804...
804
	ret
804
        ret
805
.err2:
805
.err2:
806
	pop	ecx
806
        pop     ecx
807
.err:
807
.err:
808
	stc
808
        stc
809
	ret
809
        ret
810
ramdisk_notroot_next_write:
810
ramdisk_notroot_next_write:
811
	test	edi, 0x1FF
811
        test    edi, 0x1FF
812
	jz	ramdisk_notroot_next_sector
812
        jz      ramdisk_notroot_next_sector
813
ramdisk_root_next_write:
813
ramdisk_root_next_write:
814
	ret
814
        ret
815
 
815
 
816
ramdisk_notroot_extend_dir:
816
ramdisk_notroot_extend_dir:
817
	pusha
817
        pusha
818
	xor	eax, eax
818
        xor     eax, eax
819
	mov	edi, RAMDISK_FAT
819
        mov     edi, RAMDISK_FAT
820
	mov	ecx, 2849
820
        mov     ecx, 2849
821
	repnz	scasw
821
        repnz scasw
822
	jnz	.notfound
822
        jnz     .notfound
823
	mov	word [edi-2], 0xFFF
823
        mov     word [edi-2], 0xFFF
824
	sub	edi, RAMDISK_FAT
824
        sub     edi, RAMDISK_FAT
825
	shr	edi, 1
825
        shr     edi, 1
826
	dec	edi
826
        dec     edi
827
	mov	eax, [esp+28]
827
        mov     eax, [esp+28]
828
	mov	ecx, [eax]
828
        mov     ecx, [eax]
829
	mov	[RAMDISK_FAT+ecx*2], di
829
        mov     [RAMDISK_FAT+ecx*2], di
830
	mov	[eax], edi
830
        mov     [eax], edi
831
	shl	edi, 9
831
        shl     edi, 9
Line 832... Line 832...
832
	add	edi, (31 shl 9)+RAMDISK
832
        add     edi, (31 shl 9)+RAMDISK
833
	mov	[esp], edi
833
        mov     [esp], edi
834
	xor	eax, eax
834
        xor     eax, eax
835
	mov	ecx, 128
835
        mov     ecx, 128
836
	rep	stosd
836
        rep stosd
837
	popa
837
        popa
838
	clc
838
        clc
839
	ret
839
        ret
840
.notfound:
840
.notfound:
841
	popa
841
        popa
842
	stc
842
        stc
843
	ret
843
        ret
844
 
844
 
845
rd_find_lfn:
845
rd_find_lfn:
846
; in: esi+ebp -> name
846
; in: esi+ebp -> name
847
; out: CF=1 - file not found
847
; out: CF=1 - file not found
848
;      else CF=0 and edi->direntry
848
;      else CF=0 and edi->direntry
849
	push	esi edi
849
        push    esi edi
850
	push	0
850
        push    0
851
	push	ramdisk_root_first
851
        push    ramdisk_root_first
852
	push	ramdisk_root_next
852
        push    ramdisk_root_next
853
.loop:
853
.loop:
854
	call	fat_find_lfn
854
        call    fat_find_lfn
855
	jc	.notfound
855
        jc      .notfound
856
	cmp	byte [esi], 0
856
        cmp     byte [esi], 0
857
	jz	.found
857
        jz      .found
858
.continue:
858
.continue:
859
	test	byte [edi+11], 10h
859
        test    byte [edi+11], 10h
860
	jz	.notfound
860
        jz      .notfound
861
	movzx	eax, word [edi+26]
861
        movzx   eax, word [edi+26]
862
	mov	[esp+8], eax
862
        mov     [esp+8], eax
863
	mov	dword [esp+4], ramdisk_notroot_first
863
        mov     dword [esp+4], ramdisk_notroot_first
864
	mov	dword [esp], ramdisk_notroot_next
864
        mov     dword [esp], ramdisk_notroot_next
865
	test	eax, eax
865
        test    eax, eax
866
	jnz	.loop
866
        jnz     .loop
867
	mov	dword [esp+4], ramdisk_root_first
867
        mov     dword [esp+4], ramdisk_root_first
868
	mov	dword [esp], ramdisk_notroot_next
868
        mov     dword [esp], ramdisk_notroot_next
869
	jmp	.loop
869
        jmp     .loop
870
.notfound:
870
.notfound:
871
	add	esp, 12
871
        add     esp, 12
872
	pop	edi esi
872
        pop     edi esi
Line 873... Line 873...
873
	stc
873
        stc
874
	ret
874
        ret
875
.found:
875
.found:
876
	test	ebp, ebp
876
        test    ebp, ebp
Line 897... Line 897...
897
;  ret ebx = bytes read or 0xffffffff file not found
897
;  ret ebx = bytes read or 0xffffffff file not found
898
;      eax = 0 ok read or other = errormsg
898
;      eax = 0 ok read or other = errormsg
899
;
899
;
900
;--------------------------------------------------------------
900
;--------------------------------------------------------------
901
fs_RamdiskRead:
901
fs_RamdiskRead:
902
	cmp	byte [esi], 0
902
        cmp     byte [esi], 0
903
	jnz	@f
903
        jnz     @f
904
	or	ebx, -1
904
        or      ebx, -1
905
	mov	eax, 10 	; access denied
905
        mov     eax, 10         ; access denied
906
	ret
906
        ret
907
@@:
907
@@:
908
	push	edi
908
        push    edi
909
	call	rd_find_lfn
909
        call    rd_find_lfn
910
	jnc	.found
910
        jnc     .found
911
	pop	edi
911
        pop     edi
912
	or	ebx, -1
912
        or      ebx, -1
913
	mov	eax, 5		; file not found
913
        mov     eax, 5          ; file not found
914
	ret
914
        ret
915
.found:
915
.found:
916
	test	ebx, ebx
916
        test    ebx, ebx
917
	jz	.l1
917
        jz      .l1
918
	cmp	dword [ebx+4], 0
918
        cmp     dword [ebx+4], 0
919
	jz	@f
919
        jz      @f
920
	xor	ebx, ebx
920
        xor     ebx, ebx
921
.reteof:
921
.reteof:
922
	mov	eax, 6		; EOF
922
        mov     eax, 6          ; EOF
923
	pop	edi
923
        pop     edi
924
	ret
924
        ret
925
@@:
925
@@:
926
	mov	ebx, [ebx]
926
        mov     ebx, [ebx]
927
.l1:
927
.l1:
928
	push	ecx edx
928
        push    ecx edx
929
	push	0
929
        push    0
930
	mov	eax, [edi+28]
930
        mov     eax, [edi+28]
931
	sub	eax, ebx
931
        sub     eax, ebx
932
	jb	.eof
932
        jb      .eof
933
	cmp	eax, ecx
933
        cmp     eax, ecx
934
	jae	@f
934
        jae     @f
935
	mov	ecx, eax
935
        mov     ecx, eax
936
	mov	byte [esp], 6		; EOF
936
        mov     byte [esp], 6           ; EOF
937
@@:
937
@@:
938
	movzx	edi, word [edi+26]	; cluster
938
        movzx   edi, word [edi+26]      ; cluster
939
.new:
939
.new:
940
	jecxz	.done
940
        jecxz   .done
941
	test	edi, edi
941
        test    edi, edi
942
	jz	.eof
942
        jz      .eof
943
	cmp	edi, 0xFF8
943
        cmp     edi, 0xFF8
944
	jae	.eof
944
        jae     .eof
945
	lea	eax, [edi+31]		; bootsector+2*fat+filenames
945
        lea     eax, [edi+31]           ; bootsector+2*fat+filenames
946
	shl	eax, 9			; *512
946
        shl     eax, 9                  ; *512
947
	add	eax, RAMDISK	       ; image base
947
        add     eax, RAMDISK           ; image base
948
; now eax points to data of cluster
948
; now eax points to data of cluster
949
	sub	ebx, 512
949
        sub     ebx, 512
950
	jae	.skip
950
        jae     .skip
951
	lea	eax, [eax+ebx+512]
951
        lea     eax, [eax+ebx+512]
952
	neg	ebx
952
        neg     ebx
953
	push	ecx
953
        push    ecx
954
	cmp	ecx, ebx
954
        cmp     ecx, ebx
955
	jbe	@f
955
        jbe     @f
956
	mov	ecx, ebx
956
        mov     ecx, ebx
957
@@:
957
@@:
958
	mov	ebx, edx
958
        mov     ebx, edx
959
	call	memmove
959
        call    memmove
960
	add	edx, ecx
960
        add     edx, ecx
961
	sub	[esp], ecx
961
        sub     [esp], ecx
962
	pop	ecx
962
        pop     ecx
963
	xor	ebx, ebx
963
        xor     ebx, ebx
964
.skip:
964
.skip:
965
	movzx	edi, word [edi*2+RAMDISK_FAT]	   ; find next cluster from FAT
965
        movzx   edi, word [edi*2+RAMDISK_FAT]      ; find next cluster from FAT
966
	jmp	.new
966
        jmp     .new
967
.eof:
967
.eof:
968
	mov	ebx, edx
968
        mov     ebx, edx
969
	pop	eax edx ecx
969
        pop     eax edx ecx
970
	sub	ebx, edx
970
        sub     ebx, edx
971
	jmp	.reteof
971
        jmp     .reteof
972
.done:
972
.done:
973
	mov	ebx, edx
973
        mov     ebx, edx
974
	pop	eax edx ecx edi
974
        pop     eax edx ecx edi
975
	sub	ebx, edx
975
        sub     ebx, edx
976
	ret
976
        ret
Line 977... Line 977...
977
 
977
 
978
;----------------------------------------------------------------
978
;----------------------------------------------------------------
979
;
979
;
980
;  fs_RamdiskReadFolder - LFN variant for reading sys floppy folder
980
;  fs_RamdiskReadFolder - LFN variant for reading sys floppy folder
Line 989... Line 989...
989
;  ret ebx = size or 0xffffffff file not found
989
;  ret ebx = size or 0xffffffff file not found
990
;      eax = 0 ok read or other = errormsg
990
;      eax = 0 ok read or other = errormsg
991
;
991
;
992
;--------------------------------------------------------------
992
;--------------------------------------------------------------
993
fs_RamdiskReadFolder:
993
fs_RamdiskReadFolder:
994
	push	edi
994
        push    edi
995
	cmp	byte [esi], 0
995
        cmp     byte [esi], 0
996
	jz	.root
996
        jz      .root
997
	call	rd_find_lfn
997
        call    rd_find_lfn
998
	jnc	.found
998
        jnc     .found
999
	pop	edi
999
        pop     edi
1000
	or	ebx, -1
1000
        or      ebx, -1
1001
	mov	eax, ERROR_FILE_NOT_FOUND
1001
        mov     eax, ERROR_FILE_NOT_FOUND
1002
	ret
1002
        ret
1003
.found:
1003
.found:
1004
	test	byte [edi+11], 0x10
1004
        test    byte [edi+11], 0x10
1005
	jnz	.found_dir
1005
        jnz     .found_dir
1006
	pop	edi
1006
        pop     edi
1007
	or	ebx, -1
1007
        or      ebx, -1
1008
	mov	eax, ERROR_ACCESS_DENIED
1008
        mov     eax, ERROR_ACCESS_DENIED
1009
	ret
1009
        ret
1010
.found_dir:
1010
.found_dir:
1011
	movzx	eax, word [edi+26]
1011
        movzx   eax, word [edi+26]
1012
	add	eax, 31
1012
        add     eax, 31
1013
	push	0
1013
        push    0
1014
	jmp	.doit
1014
        jmp     .doit
1015
.root:
1015
.root:
1016
	mov	eax, 19
1016
        mov     eax, 19
1017
	push	14
1017
        push    14
1018
.doit:
1018
.doit:
1019
	push	esi ecx ebp
1019
        push    esi ecx ebp
1020
	sub	esp, 262*2	; reserve space for LFN
1020
        sub     esp, 262*2      ; reserve space for LFN
1021
	mov	ebp, esp
1021
        mov     ebp, esp
1022
	push	dword [ebx+4]	; for fat_get_name: read ANSI/UNICODE names
1022
        push    dword [ebx+4]   ; for fat_get_name: read ANSI/UNICODE names
1023
	mov	ebx, [ebx]
1023
        mov     ebx, [ebx]
1024
; init header
1024
; init header
1025
	push	eax ecx
1025
        push    eax ecx
1026
	mov	edi, edx
1026
        mov     edi, edx
1027
	mov	ecx, 32/4
1027
        mov     ecx, 32/4
1028
	xor	eax, eax
1028
        xor     eax, eax
1029
	rep	stosd
1029
        rep stosd
1030
	mov	byte [edx], 1	; version
1030
        mov     byte [edx], 1   ; version
1031
	pop	ecx eax
1031
        pop     ecx eax
1032
	mov	esi, edi	; esi points to block of data of folder entry (BDFE)
1032
        mov     esi, edi        ; esi points to block of data of folder entry (BDFE)
1033
.main_loop:
1033
.main_loop:
1034
	mov	edi, eax
1034
        mov     edi, eax
1035
	shl	edi, 9
1035
        shl     edi, 9
1036
	add	edi, RAMDISK
1036
        add     edi, RAMDISK
1037
	push	eax
1037
        push    eax
1038
.l1:
1038
.l1:
1039
	call	fat_get_name
1039
        call    fat_get_name
1040
	jc	.l2
1040
        jc      .l2
1041
	cmp	byte [edi+11], 0xF
1041
        cmp     byte [edi+11], 0xF
1042
	jnz	.do_bdfe
1042
        jnz     .do_bdfe
1043
	add	edi, 0x20
1043
        add     edi, 0x20
1044
	test	edi, 0x1FF
1044
        test    edi, 0x1FF
1045
	jnz	.do_bdfe
1045
        jnz     .do_bdfe
1046
	pop	eax
1046
        pop     eax
1047
	inc	eax
1047
        inc     eax
1048
	dec	byte [esp+262*2+16]
1048
        dec     byte [esp+262*2+16]
1049
	jz	.done
1049
        jz      .done
1050
	jns	@f
1050
        jns     @f
1051
; read next sector from FAT
1051
; read next sector from FAT
1052
	mov	eax, [(eax-31-1)*2+RAMDISK_FAT]
1052
        mov     eax, [(eax-31-1)*2+RAMDISK_FAT]
1053
	and	eax, 0xFFF
1053
        and     eax, 0xFFF
1054
	cmp	eax, 0xFF8
1054
        cmp     eax, 0xFF8
1055
	jae	.done
1055
        jae     .done
1056
	add	eax, 31
1056
        add     eax, 31
1057
	mov	byte [esp+262*2+16], 0
1057
        mov     byte [esp+262*2+16], 0
1058
@@:
1058
@@:
1059
	mov	edi, eax
1059
        mov     edi, eax
1060
	shl	edi, 9
1060
        shl     edi, 9
1061
	add	edi, RAMDISK
1061
        add     edi, RAMDISK
1062
	push	eax
1062
        push    eax
1063
.do_bdfe:
1063
.do_bdfe:
1064
	inc	dword [edx+8]	; new file found
1064
        inc     dword [edx+8]   ; new file found
1065
	dec	ebx
1065
        dec     ebx
1066
	jns	.l2
1066
        jns     .l2
1067
	dec	ecx
1067
        dec     ecx
1068
	js	.l2
1068
        js      .l2
1069
	inc	dword [edx+4]  ; new file block copied
1069
        inc     dword [edx+4]  ; new file block copied
1070
	call	fat_entry_to_bdfe
1070
        call    fat_entry_to_bdfe
1071
.l2:
1071
.l2:
1072
	add	edi, 0x20
1072
        add     edi, 0x20
1073
	test	edi, 0x1FF
1073
        test    edi, 0x1FF
1074
	jnz	.l1
1074
        jnz     .l1
1075
	pop	eax
1075
        pop     eax
1076
	inc	eax
1076
        inc     eax
1077
	dec	byte [esp+262*2+16]
1077
        dec     byte [esp+262*2+16]
1078
	jz	.done
1078
        jz      .done
1079
	jns	@f
1079
        jns     @f
1080
; read next sector from FAT
1080
; read next sector from FAT
1081
	mov	eax, [(eax-31-1)*2+RAMDISK_FAT]
1081
        mov     eax, [(eax-31-1)*2+RAMDISK_FAT]
1082
	and	eax, 0xFFF
1082
        and     eax, 0xFFF
1083
	cmp	eax, 0xFF8
1083
        cmp     eax, 0xFF8
1084
	jae	.done
1084
        jae     .done
1085
	add	eax, 31
1085
        add     eax, 31
1086
	mov	byte [esp+262*2+16], 0
1086
        mov     byte [esp+262*2+16], 0
1087
@@:
1087
@@:
1088
	jmp	.main_loop
1088
        jmp     .main_loop
1089
.done:
1089
.done:
1090
	add	esp, 262*2+4
1090
        add     esp, 262*2+4
1091
	pop	ebp
1091
        pop     ebp
1092
	mov	ebx, [edx+4]
1092
        mov     ebx, [edx+4]
1093
	xor	eax, eax
1093
        xor     eax, eax
1094
	dec	ecx
1094
        dec     ecx
1095
	js	@f
1095
        js      @f
1096
	mov	al, ERROR_END_OF_FILE
1096
        mov     al, ERROR_END_OF_FILE
1097
@@:
1097
@@:
1098
	pop	ecx esi edi edi
1098
        pop     ecx esi edi edi
1099
	ret
1099
        ret
Line 1100... Line 1100...
1100
 
1100
 
1101
iglobal
1101
iglobal
1102
label fat_legal_chars byte
1102
label fat_legal_chars byte
1103
; 0 = not allowed
1103
; 0 = not allowed
1104
; 1 = allowed only in long names
1104
; 1 = allowed only in long names
1105
; 3 = allowed
1105
; 3 = allowed
1106
	times 32 db 0
1106
        times 32 db 0
1107
;                 ! " # $ % & ' ( ) * + , - . /
1107
;                 ! " # $ % & ' ( ) * + , - . /
1108
	db	1,3,0,3,3,3,3,3,3,3,0,1,1,3,3,0
1108
        db      1,3,0,3,3,3,3,3,3,3,0,1,1,3,3,0
1109
;               0 1 2 3 4 5 6 7 8 9 : ; < = > ?
1109
;               0 1 2 3 4 5 6 7 8 9 : ; < = > ?
1110
	db	3,3,3,3,3,3,3,3,3,3,0,1,0,1,0,0
1110
        db      3,3,3,3,3,3,3,3,3,3,0,1,0,1,0,0
1111
;               @ A B C D E F G H I J K L M N O
1111
;               @ A B C D E F G H I J K L M N O
1112
	db	3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3
1112
        db      3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3
1113
;               P Q R S T U V W X Y Z [ \ ] ^ _
1113
;               P Q R S T U V W X Y Z [ \ ] ^ _
1114
	db	3,3,3,3,3,3,3,3,3,3,3,1,0,1,3,3
1114
        db      3,3,3,3,3,3,3,3,3,3,3,1,0,1,3,3
1115
;               ` a b c d e f g h i j k l m n o
1115
;               ` a b c d e f g h i j k l m n o
1116
	db	3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3
1116
        db      3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3
1117
;               p q r s t u v w x y z { | } ~
1117
;               p q r s t u v w x y z { | } ~
1118
	db	3,3,3,3,3,3,3,3,3,3,3,3,0,3,3,0
1118
        db      3,3,3,3,3,3,3,3,3,3,3,3,0,3,3,0
Line 1119... Line 1119...
1119
endg
1119
endg
1120
 
1120
 
1121
fat_name_is_legal:
1121
fat_name_is_legal:
1122
; in: esi->(long) name
1122
; in: esi->(long) name
1123
; out: CF set <=> legal
1123
; out: CF set <=> legal
1124
; destroys eax
1124
; destroys eax
1125
	push	esi
1125
        push    esi
1126
	xor	eax, eax
1126
        xor     eax, eax
1127
@@:
1127
@@:
1128
	lodsb
1128
        lodsb
1129
	test	al, al
1129
        test    al, al
1130
	jz	.done
1130
        jz      .done
1131
	cmp	al, 80h
1131
        cmp     al, 80h
1132
	jae	.big
1132
        jae     .big
1133
	test	[fat_legal_chars+eax], 1
1133
        test    [fat_legal_chars+eax], 1
1134
	jnz	@b
1134
        jnz     @b
1135
.err:
1135
.err:
1136
	pop	esi
1136
        pop     esi
1137
	clc
1137
        clc
1138
	ret
1138
        ret
1139
.big:
1139
.big:
1140
; 0x80-0xAF, 0xE0-0xEF
1140
; 0x80-0xAF, 0xE0-0xEF
1141
	cmp	al, 0xB0
1141
        cmp     al, 0xB0
1142
	jb	@b
1142
        jb      @b
1143
	cmp	al, 0xE0
1143
        cmp     al, 0xE0
1144
	jb	.err
1144
        jb      .err
1145
	cmp	al, 0xF0
1145
        cmp     al, 0xF0
1146
	jb	@b
1146
        jb      @b
1147
	jmp	.err
1147
        jmp     .err
1148
.done:
1148
.done:
1149
	sub	esi, [esp]
1149
        sub     esi, [esp]
1150
	cmp	esi, 257
1150
        cmp     esi, 257
Line 1151... Line 1151...
1151
	pop	esi
1151
        pop     esi
1152
	ret
1152
        ret
1153
 
1153
 
1154
fat_next_short_name:
1154
fat_next_short_name:
1155
; in: edi->8+3 name
1155
; in: edi->8+3 name
1156
; out: name corrected
1156
; out: name corrected
1157
;      CF=1 <=> error
1157
;      CF=1 <=> error
1158
	pushad
1158
        pushad
1159
	mov	ecx, 8
1159
        mov     ecx, 8
1160
	mov	al, '~'
1160
        mov     al, '~'
1161
	std
1161
        std
1162
	push	edi
1162
        push    edi
1163
	add	edi, 7
1163
        add     edi, 7
1164
	repnz	scasb
1164
        repnz scasb
1165
	pop	edi
1165
        pop     edi
1166
	cld
1166
        cld
1167
	jz	.tilde
1167
        jz      .tilde
1168
; tilde is not found, insert "~1" at end
1168
; tilde is not found, insert "~1" at end
1169
	add	edi, 6
1169
        add     edi, 6
1170
	cmp	word [edi], '  '
1170
        cmp     word [edi], '  '
1171
	jnz	.insert_tilde
1171
        jnz     .insert_tilde
1172
@@:
1172
@@:
1173
        dec     edi
1173
        dec     edi
1174
	cmp	byte [edi], ' '
1174
        cmp     byte [edi], ' '
1175
	jz	@b
1175
        jz      @b
1176
	inc	edi
1176
        inc     edi
1177
.insert_tilde:
1177
.insert_tilde:
1178
	mov	word [edi], '~1'
1178
        mov     word [edi], '~1'
1179
	popad
1179
        popad
1180
	clc
1180
        clc
1181
	ret
1181
        ret
1182
.tilde:
1182
.tilde:
1183
	push	edi
1183
        push    edi
1184
	add	edi, 7
1184
        add     edi, 7
1185
	xor	ecx, ecx
1185
        xor     ecx, ecx
1186
@@:
1186
@@:
1187
; after tilde may be only digits and trailing spaces
1187
; after tilde may be only digits and trailing spaces
1188
	cmp	byte [edi], '~'
1188
        cmp     byte [edi], '~'
1189
	jz	.break
1189
        jz      .break
1190
	cmp	byte [edi], ' '
1190
        cmp     byte [edi], ' '
1191
	jz	.space
1191
        jz      .space
1192
	cmp	byte [edi], '9'
1192
        cmp     byte [edi], '9'
1193
	jnz	.found
1193
        jnz     .found
1194
	dec	edi
1194
        dec     edi
1195
	jmp	@b
1195
        jmp     @b
1196
.space:
1196
.space:
1197
	dec	edi
1197
        dec     edi
1198
	inc	ecx
1198
        inc     ecx
1199
	jmp	@b
1199
        jmp     @b
1200
.found:
1200
.found:
1201
	inc	byte [edi]
1201
        inc     byte [edi]
1202
	add	dword [esp], 8
1202
        add     dword [esp], 8
1203
	jmp	.zerorest
1203
        jmp     .zerorest
1204
.break:
1204
.break:
1205
	jecxz	.noplace
1205
        jecxz   .noplace
1206
	inc	edi
1206
        inc     edi
1207
	mov	al, '1'
1207
        mov     al, '1'
1208
@@:
1208
@@:
1209
	xchg	al, [edi]
1209
        xchg    al, [edi]
1210
	inc	edi
1210
        inc     edi
1211
	cmp	al, ' '
1211
        cmp     al, ' '
1212
	mov	al, '0'
1212
        mov     al, '0'
1213
	jnz	@b
1213
        jnz     @b
1214
.succ:
1214
.succ:
1215
	pop	edi
1215
        pop     edi
1216
	popad
1216
        popad
1217
	clc
1217
        clc
1218
	ret
1218
        ret
1219
.noplace:
1219
.noplace:
1220
	dec	edi
1220
        dec     edi
1221
	cmp	edi, [esp]
1221
        cmp     edi, [esp]
1222
	jz	.err
1222
        jz      .err
1223
	add	dword [esp], 8
1223
        add     dword [esp], 8
1224
	mov	word [edi], '~1'
1224
        mov     word [edi], '~1'
1225
	inc	edi
1225
        inc     edi
1226
	inc	edi
1226
        inc     edi
1227
@@:
1227
@@:
1228
	mov	byte [edi], '0'
1228
        mov     byte [edi], '0'
1229
.zerorest:
1229
.zerorest:
1230
	inc	edi
1230
        inc     edi
1231
	cmp	edi, [esp]
1231
        cmp     edi, [esp]
1232
	jb	@b
1232
        jb      @b
1233
	pop	edi
1233
        pop     edi
1234
	popad
1234
        popad
1235
	;clc    ; automatically
1235
        ;clc    ; automatically
1236
	ret
1236
        ret
1237
.err:
1237
.err:
1238
	pop	edi
1238
        pop     edi
Line 1239... Line 1239...
1239
	popad
1239
        popad
1240
	stc
1240
        stc
1241
	ret
1241
        ret
1242
 
1242
 
1243
fat_gen_short_name:
1243
fat_gen_short_name:
1244
; in: esi->long name
1244
; in: esi->long name
1245
;     edi->buffer (8+3=11 chars)
1245
;     edi->buffer (8+3=11 chars)
1246
; out: buffer filled
1246
; out: buffer filled
1247
	pushad
1247
        pushad
1248
	mov	eax, '    '
1248
        mov     eax, '    '
1249
	push	edi
1249
        push    edi
1250
	stosd
1250
        stosd
1251
	stosd
1251
        stosd
1252
	stosd
1252
        stosd
1253
	pop	edi
1253
        pop     edi
1254
	xor	eax, eax
1254
        xor     eax, eax
1255
	push	8
1255
        push    8
1256
	pop	ebx
1256
        pop     ebx
1257
	lea	ecx, [edi+8]
1257
        lea     ecx, [edi+8]
1258
.loop:
1258
.loop:
1259
	lodsb
1259
        lodsb
1260
	test	al, al
1260
        test    al, al
1261
	jz	.done
1261
        jz      .done
1262
	call	char_toupper
1262
        call    char_toupper
1263
	cmp	al, ' '
1263
        cmp     al, ' '
1264
	jz	.space
1264
        jz      .space
1265
	cmp	al, 80h
1265
        cmp     al, 80h
1266
	ja	.big
1266
        ja      .big
1267
	test	[fat_legal_chars+eax], 2
1267
        test    [fat_legal_chars+eax], 2
1268
	jnz	.symbol
1268
        jnz     .symbol
1269
.inv_symbol:
1269
.inv_symbol:
1270
	mov	al, '_'
1270
        mov     al, '_'
1271
	or	bh, 1
1271
        or      bh, 1
1272
.symbol:
1272
.symbol:
1273
	cmp	al, '.'
1273
        cmp     al, '.'
1274
	jz	.dot
1274
        jz      .dot
1275
.normal_symbol:
1275
.normal_symbol:
1276
	dec	bl
1276
        dec     bl
1277
	jns	.store
1277
        jns     .store
1278
	mov	bl, 0
1278
        mov     bl, 0
1279
.space:
1279
.space:
1280
	or	bh, 1
1280
        or      bh, 1
1281
	jmp	.loop
1281
        jmp     .loop
1282
.store:
1282
.store:
1283
	stosb
1283
        stosb
1284
	jmp	.loop
1284
        jmp     .loop
1285
.big:
1285
.big:
1286
	cmp	al, 0xB0
1286
        cmp     al, 0xB0
1287
	jb	.normal_symbol
1287
        jb      .normal_symbol
1288
	cmp	al, 0xE0
1288
        cmp     al, 0xE0
1289
	jb	.inv_symbol
1289
        jb      .inv_symbol
1290
	cmp	al, 0xF0
1290
        cmp     al, 0xF0
1291
	jb	.normal_symbol
1291
        jb      .normal_symbol
1292
	jmp	.inv_symbol
1292
        jmp     .inv_symbol
1293
.dot:
1293
.dot:
1294
	test	bh, 2
1294
        test    bh, 2
1295
	jz	.firstdot
1295
        jz      .firstdot
1296
	pop	ebx
1296
        pop     ebx
1297
	add	ebx, edi
1297
        add     ebx, edi
1298
	sub	ebx, ecx
1298
        sub     ebx, ecx
1299
	push	ebx
1299
        push    ebx
1300
	cmp	ebx, ecx
1300
        cmp     ebx, ecx
1301
	jb	@f
1301
        jb      @f
1302
	pop	ebx
1302
        pop     ebx
1303
	push	ecx
1303
        push    ecx
1304
@@:
1304
@@:
1305
	cmp	edi, ecx
1305
        cmp     edi, ecx
1306
	jbe	.skip
1306
        jbe     .skip
1307
@@:
1307
@@:
1308
	dec	edi
1308
        dec     edi
1309
	mov	al, [edi]
1309
        mov     al, [edi]
1310
	dec	ebx
1310
        dec     ebx
1311
	mov	[ebx], al
1311
        mov     [ebx], al
1312
	mov	byte [edi], ' '
1312
        mov     byte [edi], ' '
1313
	cmp	edi, ecx
1313
        cmp     edi, ecx
1314
	ja	@b
1314
        ja      @b
1315
.skip:
1315
.skip:
1316
	mov	bh, 3
1316
        mov     bh, 3
1317
	jmp	@f
1317
        jmp     @f
1318
.firstdot:
1318
.firstdot:
1319
	cmp	bl, 8
1319
        cmp     bl, 8
1320
	jz	.space
1320
        jz      .space
1321
	push	edi
1321
        push    edi
1322
	or	bh, 2
1322
        or      bh, 2
1323
@@:
1323
@@:
1324
	mov	edi, ecx
1324
        mov     edi, ecx
1325
	mov	bl, 3
1325
        mov     bl, 3
1326
	jmp	.loop
1326
        jmp     .loop
1327
.done:
1327
.done:
1328
	test	bh, 2
1328
        test    bh, 2
1329
	jz	@f
1329
        jz      @f
1330
	pop	edi
1330
        pop     edi
1331
@@:
1331
@@:
1332
	lea	edi, [ecx-8]
1332
        lea     edi, [ecx-8]
1333
	test	bh, 1
1333
        test    bh, 1
1334
	jz	@f
1334
        jz      @f
Line 1335... Line 1335...
1335
	call	fat_next_short_name
1335
        call    fat_next_short_name
1336
@@:
1336
@@:
1337
	popad
1337
        popad
1338
	ret
1338
        ret
Line 1350... Line 1350...
1350
;  ret ebx = number of written bytes
1350
;  ret ebx = number of written bytes
1351
;      eax = 0 ok read or other = errormsg
1351
;      eax = 0 ok read or other = errormsg
1352
;
1352
;
1353
;--------------------------------------------------------------
1353
;--------------------------------------------------------------
1354
@@:
1354
@@:
1355
	mov	eax, ERROR_ACCESS_DENIED
1355
        mov     eax, ERROR_ACCESS_DENIED
1356
	xor	ebx, ebx
1356
        xor     ebx, ebx
1357
	ret
1357
        ret
Line 1358... Line 1358...
1358
 
1358
 
1359
fs_RamdiskCreateFolder:
1359
fs_RamdiskCreateFolder:
1360
	mov	al, 1		; create folder
1360
        mov     al, 1           ; create folder
Line 1361... Line 1361...
1361
	jmp	fs_RamdiskRewrite.common
1361
        jmp     fs_RamdiskRewrite.common
1362
 
1362
 
1363
fs_RamdiskRewrite:
1363
fs_RamdiskRewrite:
1364
	xor	eax, eax	; create file
1364
        xor     eax, eax        ; create file
1365
.common:
1365
.common:
1366
	cmp	byte [esi], 0
1366
        cmp     byte [esi], 0
1367
	jz	@b
1367
        jz      @b
1368
	pushad
1368
        pushad
1369
	xor	edi, edi
1369
        xor     edi, edi
1370
	push	esi
1370
        push    esi
1371
	test	ebp, ebp
1371
        test    ebp, ebp
1372
	jz	@f
1372
        jz      @f
1373
	mov	esi, ebp
1373
        mov     esi, ebp
1374
@@:
1374
@@:
1375
	lodsb
1375
        lodsb
1376
	test	al, al
1376
        test    al, al
1377
	jz	@f
1377
        jz      @f
1378
	cmp	al, '/'
1378
        cmp     al, '/'
1379
	jnz	@b
1379
        jnz     @b
1380
	lea	edi, [esi-1]
1380
        lea     edi, [esi-1]
1381
	jmp	@b
1381
        jmp     @b
1382
@@:
1382
@@:
1383
	pop	esi
1383
        pop     esi
1384
	test	edi, edi
1384
        test    edi, edi
1385
	jnz	.noroot
1385
        jnz     .noroot
1386
	test	ebp, ebp
1386
        test    ebp, ebp
1387
	jnz	.hasebp
1387
        jnz     .hasebp
1388
	push	ramdisk_root_extend_dir
1388
        push    ramdisk_root_extend_dir
1389
	push	ramdisk_root_next_write
1389
        push    ramdisk_root_next_write
1390
	push	edi
1390
        push    edi
1391
	push	ramdisk_root_first
1391
        push    ramdisk_root_first
1392
	push	ramdisk_root_next
1392
        push    ramdisk_root_next
1393
	jmp	.common1
1393
        jmp     .common1
1394
.hasebp:
1394
.hasebp:
1395
	mov	eax, ERROR_ACCESS_DENIED
1395
        mov     eax, ERROR_ACCESS_DENIED
1396
	cmp	byte [ebp], 0
1396
        cmp     byte [ebp], 0
1397
	jz	.ret1
1397
        jz      .ret1
1398
	push	ebp
1398
        push    ebp
1399
	xor	ebp, ebp
1399
        xor     ebp, ebp
1400
	call	rd_find_lfn
1400
        call    rd_find_lfn
1401
	pop	esi
1401
        pop     esi
1402
	jc	.notfound0
1402
        jc      .notfound0
1403
	jmp	.common0
1403
        jmp     .common0
1404
.noroot:
1404
.noroot:
1405
	mov	eax, ERROR_ACCESS_DENIED
1405
        mov     eax, ERROR_ACCESS_DENIED
1406
	cmp	byte [edi+1], 0
1406
        cmp     byte [edi+1], 0
1407
	jz	.ret1
1407
        jz      .ret1
1408
; check existence
1408
; check existence
1409
	mov	byte [edi], 0
1409
        mov     byte [edi], 0
1410
	push	edi
1410
        push    edi
1411
	call	rd_find_lfn
1411
        call    rd_find_lfn
1412
	pop	esi
1412
        pop     esi
1413
	mov	byte [esi], '/'
1413
        mov     byte [esi], '/'
1414
	jnc	@f
1414
        jnc     @f
1415
.notfound0:
1415
.notfound0:
1416
	mov	eax, ERROR_FILE_NOT_FOUND
1416
        mov     eax, ERROR_FILE_NOT_FOUND
1417
.ret1:
1417
.ret1:
1418
	mov	[esp+28], eax
1418
        mov     [esp+28], eax
1419
	popad
1419
        popad
1420
	xor	ebx, ebx
1420
        xor     ebx, ebx
1421
	ret
1421
        ret
1422
@@:
1422
@@:
1423
	inc	esi
1423
        inc     esi
1424
.common0:
1424
.common0:
1425
	test	byte [edi+11], 0x10	; must be directory
1425
        test    byte [edi+11], 0x10     ; must be directory
1426
	mov	eax, ERROR_ACCESS_DENIED
1426
        mov     eax, ERROR_ACCESS_DENIED
1427
	jz	.ret1
1427
        jz      .ret1
1428
	movzx	ebp, word [edi+26]	; ebp=cluster
1428
        movzx   ebp, word [edi+26]      ; ebp=cluster
1429
	mov	eax, ERROR_FAT_TABLE
1429
        mov     eax, ERROR_FAT_TABLE
1430
	cmp	ebp, 2
1430
        cmp     ebp, 2
1431
	jb	.ret1
1431
        jb      .ret1
1432
	cmp	ebp, 2849
1432
        cmp     ebp, 2849
1433
	jae	.ret1
1433
        jae     .ret1
1434
	push	ramdisk_notroot_extend_dir
1434
        push    ramdisk_notroot_extend_dir
1435
	push	ramdisk_notroot_next_write
1435
        push    ramdisk_notroot_next_write
1436
	push	ebp
1436
        push    ebp
1437
	push	ramdisk_notroot_first
1437
        push    ramdisk_notroot_first
1438
	push	ramdisk_notroot_next
1438
        push    ramdisk_notroot_next
1439
.common1:
1439
.common1:
1440
	call	fat_find_lfn
1440
        call    fat_find_lfn
1441
	jc	.notfound
1441
        jc      .notfound
1442
; found
1442
; found
1443
	test	byte [edi+11], 10h
1443
        test    byte [edi+11], 10h
1444
	jz	.exists_file
1444
        jz      .exists_file
1445
; found directory; if we are creating directory, return OK,
1445
; found directory; if we are creating directory, return OK,
1446
;                  if we are creating file, say "access denied"
1446
;                  if we are creating file, say "access denied"
1447
	add	esp, 20
1447
        add     esp, 20
1448
	popad
1448
        popad
1449
	test	al, al
1449
        test    al, al
1450
	mov	eax, ERROR_ACCESS_DENIED
1450
        mov     eax, ERROR_ACCESS_DENIED
1451
	jz	@f
1451
        jz      @f
1452
	mov	al, 0
1452
        mov     al, 0
1453
@@:
1453
@@:
1454
	xor	ebx, ebx
1454
        xor     ebx, ebx
1455
	ret
1455
        ret
1456
.exists_file:
1456
.exists_file:
1457
; found file; if we are creating directory, return "access denied",
1457
; found file; if we are creating directory, return "access denied",
1458
;             if we are creating file, delete existing file and continue
1458
;             if we are creating file, delete existing file and continue
1459
	cmp	byte [esp+20+28], 0
1459
        cmp     byte [esp+20+28], 0
1460
	jz	@f
1460
        jz      @f
1461
	add	esp, 20
1461
        add     esp, 20
1462
	popad
1462
        popad
1463
	mov	eax, ERROR_ACCESS_DENIED
1463
        mov     eax, ERROR_ACCESS_DENIED
1464
	xor	ebx, ebx
1464
        xor     ebx, ebx
1465
	ret
1465
        ret
1466
@@:
1466
@@:
1467
; delete FAT chain
1467
; delete FAT chain
1468
	push	edi
1468
        push    edi
1469
	xor	eax, eax
1469
        xor     eax, eax
1470
	mov	dword [edi+28], eax	; zero size
1470
        mov     dword [edi+28], eax     ; zero size
1471
	xchg	ax, word [edi+26]	; start cluster
1471
        xchg    ax, word [edi+26]       ; start cluster
1472
	test	eax, eax
1472
        test    eax, eax
1473
	jz	.done1
1473
        jz      .done1
1474
@@:
1474
@@:
1475
	cmp	eax, 0xFF8
1475
        cmp     eax, 0xFF8
1476
	jae	.done1
1476
        jae     .done1
1477
	lea	edi, [RAMDISK_FAT + eax*2] ; position in FAT
1477
        lea     edi, [RAMDISK_FAT + eax*2] ; position in FAT
1478
	xor	eax, eax
1478
        xor     eax, eax
1479
	xchg	ax, [edi]
1479
        xchg    ax, [edi]
1480
	jmp	@b
1480
        jmp     @b
1481
.done1:
1481
.done1:
1482
	pop	edi
1482
        pop     edi
1483
	call	get_time_for_file
1483
        call    get_time_for_file
1484
	mov	[edi+22], ax
1484
        mov     [edi+22], ax
1485
	call	get_date_for_file
1485
        call    get_date_for_file
1486
	mov	[edi+24], ax
1486
        mov     [edi+24], ax
1487
	mov	[edi+18], ax
1487
        mov     [edi+18], ax
1488
	or	byte [edi+11], 20h	; set 'archive' attribute
1488
        or      byte [edi+11], 20h      ; set 'archive' attribute
1489
	jmp	.doit
1489
        jmp     .doit
1490
.notfound:
1490
.notfound:
1491
; file is not found; generate short name
1491
; file is not found; generate short name
1492
	call	fat_name_is_legal
1492
        call    fat_name_is_legal
1493
	jc	@f
1493
        jc      @f
1494
	add	esp, 20
1494
        add     esp, 20
1495
	popad
1495
        popad
1496
	mov	eax, ERROR_FILE_NOT_FOUND
1496
        mov     eax, ERROR_FILE_NOT_FOUND
1497
	xor	ebx, ebx
1497
        xor     ebx, ebx
1498
	ret
1498
        ret
1499
@@:
1499
@@:
1500
	sub	esp, 12
1500
        sub     esp, 12
1501
	mov	edi, esp
1501
        mov     edi, esp
1502
	call	fat_gen_short_name
1502
        call    fat_gen_short_name
1503
.test_short_name_loop:
1503
.test_short_name_loop:
1504
	push	esi edi ecx
1504
        push    esi edi ecx
1505
	mov	esi, edi
1505
        mov     esi, edi
1506
	lea	eax, [esp+12+12+8]
1506
        lea     eax, [esp+12+12+8]
1507
	mov	[eax], ebp
1507
        mov     [eax], ebp
1508
	call	dword [eax-4]
1508
        call    dword [eax-4]
1509
	jc	.found
1509
        jc      .found
1510
.test_short_name_entry:
1510
.test_short_name_entry:
1511
	cmp	byte [edi+11], 0xF
1511
        cmp     byte [edi+11], 0xF
1512
	jz	.test_short_name_cont
1512
        jz      .test_short_name_cont
1513
	mov	ecx, 11
1513
        mov     ecx, 11
1514
	push	esi edi
1514
        push    esi edi
1515
	repz	cmpsb
1515
        repz cmpsb
1516
	pop	edi esi
1516
        pop     edi esi
1517
	jz	.short_name_found
1517
        jz      .short_name_found
1518
.test_short_name_cont:
1518
.test_short_name_cont:
1519
	lea	eax, [esp+12+12+8]
1519
        lea     eax, [esp+12+12+8]
1520
	call	dword [eax-8]
1520
        call    dword [eax-8]
1521
	jnc	.test_short_name_entry
1521
        jnc     .test_short_name_entry
1522
	jmp	.found
1522
        jmp     .found
1523
.short_name_found:
1523
.short_name_found:
1524
	pop	ecx edi esi
1524
        pop     ecx edi esi
1525
	call	fat_next_short_name
1525
        call    fat_next_short_name
1526
	jnc	.test_short_name_loop
1526
        jnc     .test_short_name_loop
1527
.disk_full:
1527
.disk_full:
1528
	add	esp, 12+20
1528
        add     esp, 12+20
1529
	popad
1529
        popad
1530
	mov	eax, ERROR_DISK_FULL
1530
        mov     eax, ERROR_DISK_FULL
1531
	xor	ebx, ebx
1531
        xor     ebx, ebx
1532
	ret
1532
        ret
1533
.found:
1533
.found:
1534
	pop	ecx edi esi
1534
        pop     ecx edi esi
1535
; now find space in directory
1535
; now find space in directory
1536
; we need to save LFN <=> LFN is not equal to short name <=> generated name contains '~'
1536
; we need to save LFN <=> LFN is not equal to short name <=> generated name contains '~'
1537
	mov	al, '~'
1537
        mov     al, '~'
1538
	push	ecx edi
1538
        push    ecx edi
1539
	mov	ecx, 8
1539
        mov     ecx, 8
1540
	repnz	scasb
1540
        repnz scasb
1541
	push	1
1541
        push    1
1542
	pop	eax	; 1 entry
1542
        pop     eax     ; 1 entry
1543
	jnz	.notilde
1543
        jnz     .notilde
1544
; we need ceil(strlen(esi)/13) additional entries = floor((strlen(esi)+12+13)/13) total
1544
; we need ceil(strlen(esi)/13) additional entries = floor((strlen(esi)+12+13)/13) total
1545
	xor	eax, eax
1545
        xor     eax, eax
1546
@@:
1546
@@:
1547
	cmp	byte [esi], 0
1547
        cmp     byte [esi], 0
1548
	jz	@f
1548
        jz      @f
1549
	inc	esi
1549
        inc     esi
1550
	inc	eax
1550
        inc     eax
1551
	jmp	@b
1551
        jmp     @b
1552
@@:
1552
@@:
1553
	sub	esi, eax
1553
        sub     esi, eax
1554
	add	eax, 12+13
1554
        add     eax, 12+13
1555
	mov	ecx, 13
1555
        mov     ecx, 13
1556
	push	edx
1556
        push    edx
1557
	cdq
1557
        cdq
1558
	div	ecx
1558
        div     ecx
1559
	pop	edx
1559
        pop     edx
1560
.notilde:
1560
.notilde:
1561
	push	-1
1561
        push    -1
1562
	push	-1
1562
        push    -1
1563
; find  successive entries in directory
1563
; find  successive entries in directory
1564
	xor	ecx, ecx
1564
        xor     ecx, ecx
1565
	push	eax
1565
        push    eax
1566
	lea	eax, [esp+12+8+12+8]
1566
        lea     eax, [esp+12+8+12+8]
1567
	mov	[eax], ebp
1567
        mov     [eax], ebp
1568
	call	dword [eax-4]
1568
        call    dword [eax-4]
1569
	pop	eax
1569
        pop     eax
1570
.scan_dir:
1570
.scan_dir:
1571
	cmp	byte [edi], 0
1571
        cmp     byte [edi], 0
1572
	jz	.free
1572
        jz      .free
1573
	cmp	byte [edi], 0xE5
1573
        cmp     byte [edi], 0xE5
1574
	jz	.free
1574
        jz      .free
1575
	xor	ecx, ecx
1575
        xor     ecx, ecx
1576
.scan_cont:
1576
.scan_cont:
1577
	push	eax
1577
        push    eax
1578
	lea	eax, [esp+12+8+12+8]
1578
        lea     eax, [esp+12+8+12+8]
1579
	call	dword [eax-8]
1579
        call    dword [eax-8]
1580
	pop	eax
1580
        pop     eax
1581
	jnc	.scan_dir
1581
        jnc     .scan_dir
1582
	push	eax
1582
        push    eax
1583
	lea	eax, [esp+12+8+12+8]
1583
        lea     eax, [esp+12+8+12+8]
1584
	call	dword [eax+8]		; extend directory
1584
        call    dword [eax+8]           ; extend directory
1585
	pop	eax
1585
        pop     eax
1586
	jnc	.scan_dir
1586
        jnc     .scan_dir
1587
	add	esp, 8+8+12+20
1587
        add     esp, 8+8+12+20
1588
	popad
1588
        popad
1589
	mov	eax, ERROR_DISK_FULL
1589
        mov     eax, ERROR_DISK_FULL
1590
	xor	ebx, ebx
1590
        xor     ebx, ebx
1591
	ret
1591
        ret
1592
.free:
1592
.free:
1593
	test	ecx, ecx
1593
        test    ecx, ecx
1594
	jnz	@f
1594
        jnz     @f
1595
	mov	[esp], edi
1595
        mov     [esp], edi
1596
	mov	ecx, [esp+8+8+12+8]
1596
        mov     ecx, [esp+8+8+12+8]
1597
	mov	[esp+4], ecx
1597
        mov     [esp+4], ecx
1598
	xor	ecx, ecx
1598
        xor     ecx, ecx
1599
@@:
1599
@@:
1600
	inc	ecx
1600
        inc     ecx
1601
	cmp	ecx, eax
1601
        cmp     ecx, eax
-
 
1602
        jb      .scan_cont
-
 
1603
; found!
-
 
1604
; If creating a directory, allocate one data cluster now and fail immediately
-
 
1605
; if this is impossible. This prevents from creating an invalid directory entry
-
 
1606
; on a full disk.
-
 
1607
; yup, the argument is quite non-intuitive... but what should I do if
-
 
1608
; the entire function uses such arguments? BTW, it refers to al from pushad,
-
 
1609
; which in turn is filled with 0 in fs_RamdiskRewrite and 1 in fs_RamdiskCreateFolder.
-
 
1610
        push    esi ecx
-
 
1611
        cmp     byte [esp+24+12+20+28], 0
-
 
1612
        jz      .no.preallocate.folder.data
-
 
1613
        mov     ecx, 2849
-
 
1614
        mov     edi, RAMDISK_FAT
-
 
1615
        xor     eax, eax
-
 
1616
        repnz scasw
-
 
1617
        jz      @f
-
 
1618
        add     esp, 24
-
 
1619
        jmp     .disk_full
-
 
1620
@@:
1602
	jb	.scan_cont
1621
        mov     [esp+24+12+20+20], edi  ; store the cluster somewhere
1603
; found!
-
 
1604
; calculate name checksum
1622
.no.preallocate.folder.data:
1605
	push	esi ecx
1623
; calculate name checksum
1606
	mov	esi, [esp+8+8]
1624
        mov     esi, [esp+8+8]
1607
	mov	ecx, 11
1625
        mov     ecx, 11
1608
	xor	eax, eax
1626
        xor     eax, eax
1609
@@:
1627
@@:
1610
	ror	al, 1
1628
        ror     al, 1
1611
	add	al, [esi]
1629
        add     al, [esi]
1612
	inc	esi
1630
        inc     esi
1613
	loop	@b
1631
        loop    @b
1614
	pop	ecx esi
1632
        pop     ecx esi
1615
	pop	edi
1633
        pop     edi
1616
	pop	dword [esp+8+12+8]
1634
        pop     dword [esp+8+12+8]
1617
; edi points to last entry in free chunk
1635
; edi points to last entry in free chunk
1618
	dec	ecx
1636
        dec     ecx
1619
	jz	.nolfn
1637
        jz      .nolfn
1620
	push	esi
1638
        push    esi
1621
	push	eax
1639
        push    eax
1622
	mov	al, 40h
1640
        mov     al, 40h
1623
.writelfn:
1641
.writelfn:
1624
	or	al, cl
1642
        or      al, cl
1625
	mov	esi, [esp+4]
1643
        mov     esi, [esp+4]
1626
	push	ecx
1644
        push    ecx
1627
	dec	ecx
1645
        dec     ecx
1628
	imul	ecx, 13
1646
        imul    ecx, 13
1629
	add	esi, ecx
1647
        add     esi, ecx
1630
	stosb
1648
        stosb
1631
	mov	cl, 5
1649
        mov     cl, 5
1632
	call	.read_symbols
1650
        call    .read_symbols
1633
	mov	ax, 0xF
1651
        mov     ax, 0xF
1634
	stosw
1652
        stosw
1635
	mov	al, [esp+4]
1653
        mov     al, [esp+4]
1636
	stosb
1654
        stosb
1637
	mov	cl, 6
1655
        mov     cl, 6
1638
	call	.read_symbols
1656
        call    .read_symbols
1639
	xor	eax, eax
1657
        xor     eax, eax
1640
	stosw
1658
        stosw
1641
	mov	cl, 2
1659
        mov     cl, 2
1642
	call	.read_symbols
1660
        call    .read_symbols
1643
	pop	ecx
1661
        pop     ecx
1644
	lea	eax, [esp+8+8+12+8]
1662
        lea     eax, [esp+8+8+12+8]
1645
	call	dword [eax+4]	; next write
1663
        call    dword [eax+4]   ; next write
1646
	xor	eax, eax
1664
        xor     eax, eax
1647
	loop	.writelfn
1665
        loop    .writelfn
1648
	pop	eax
1666
        pop     eax
1649
	pop	esi
1667
        pop     esi
1650
.nolfn:
1668
.nolfn:
1651
	xchg	esi, [esp]
1669
        xchg    esi, [esp]
1652
	mov	ecx, 11
1670
        mov     ecx, 11
1653
	rep	movsb
1671
        rep movsb
1654
	mov	word [edi], 20h 	; attributes
1672
        mov     word [edi], 20h         ; attributes
1655
	sub	edi, 11
1673
        sub     edi, 11
1656
	pop	esi ecx
1674
        pop     esi ecx
1657
	add	esp, 12
1675
        add     esp, 12
1658
	mov	byte [edi+13], 0	; tenths of a second at file creation time
1676
        mov     byte [edi+13], 0        ; tenths of a second at file creation time
1659
	call	get_time_for_file
1677
        call    get_time_for_file
1660
	mov	[edi+14], ax		; creation time
1678
        mov     [edi+14], ax            ; creation time
1661
	mov	[edi+22], ax		; last write time
1679
        mov     [edi+22], ax            ; last write time
1662
	call	get_date_for_file
1680
        call    get_date_for_file
1663
	mov	[edi+16], ax		; creation date
1681
        mov     [edi+16], ax            ; creation date
1664
	mov	[edi+24], ax		; last write date
1682
        mov     [edi+24], ax            ; last write date
1665
	mov	[edi+18], ax		; last access date
1683
        mov     [edi+18], ax            ; last access date
1666
	and	word [edi+20], 0	; high word of cluster
1684
        and     word [edi+20], 0        ; high word of cluster
1667
	and	word [edi+26], 0	; low word of cluster - to be filled
1685
        and     word [edi+26], 0        ; low word of cluster - to be filled
1668
	and	dword [edi+28], 0	; file size - to be filled
1686
        and     dword [edi+28], 0       ; file size - to be filled
1669
	cmp	byte [esp+20+28], 0
1687
        cmp     byte [esp+20+28], 0
1670
	jz	.doit
1688
        jz      .doit
1671
; create directory
1689
; create directory
1672
	mov	byte [edi+11], 10h	   ; attributes: folder
1690
        mov     byte [edi+11], 10h         ; attributes: folder
-
 
1691
        mov     ecx, 32*2
-
 
1692
        mov     edx, edi
-
 
1693
        push    edx
-
 
1694
        push    ecx
-
 
1695
        push    edi
-
 
1696
        add     edi, 26         ; edi points to low word of cluster
-
 
1697
        push    edi
1673
	mov	ecx, 32*2
1698
        mov     edi, [esp+16+20+20]
1674
	mov	edx, edi
1699
        jmp     .doit2
1675
.doit:
1700
.doit:
1676
	push	edx
1701
        push    edx
1677
	push	ecx
1702
        push    ecx
1678
	push	edi
1703
        push    edi
1679
	add	edi, 26 	; edi points to low word of cluster
1704
        add     edi, 26         ; edi points to low word of cluster
1680
	push	edi
1705
        push    edi
1681
	jecxz	.done
1706
        jecxz   .done
1682
	mov	ecx, 2849
1707
        mov     ecx, 2849
1683
	mov	edi, RAMDISK_FAT
1708
        mov     edi, RAMDISK_FAT
1684
.write_loop:
1709
.write_loop:
1685
; allocate new cluster
1710
; allocate new cluster
1686
	xor	eax, eax
1711
        xor     eax, eax
1687
	repnz	scasw
1712
        repnz scasw
-
 
1713
        jnz     .disk_full2
1688
	jnz	.disk_full2
1714
.doit2:
Line 1689... Line 1715...
1689
	dec	edi
1715
        dec     edi
Line 1690... Line 1716...
1690
	dec	edi
1716
        dec     edi
1691
 
1717
 
Line 1692... Line 1718...
1692
    ;    lea     eax, [edi-(RAMDISK_FAT)]
1718
    ;    lea     eax, [edi-(RAMDISK_FAT)]
1693
 
1719
 
1694
	mov eax, edi
1720
        mov     eax, edi
1695
	sub eax, RAMDISK_FAT
1721
        sub     eax, RAMDISK_FAT
1696
 
1722
 
1697
	shr	eax, 1			; eax = cluster
1723
        shr     eax, 1                  ; eax = cluster
1698
	mov	word [edi], 0xFFF	; mark as last cluster
1724
        mov     word [edi], 0xFFF       ; mark as last cluster
1699
	xchg	edi, [esp]
1725
        xchg    edi, [esp]
1700
	stosw
1726
        stosw
1701
	pop	edi
1727
        pop     edi
1702
	push	edi
1728
        push    edi
1703
	inc	ecx
1729
        inc     ecx
1704
; write data
1730
; write data
1705
	cmp	byte [esp+16+20+28], 0
1731
        cmp     byte [esp+16+20+28], 0
1706
	jnz	.writedir
1732
        jnz     .writedir
1707
	shl	eax, 9
1733
        shl     eax, 9
1708
	add	eax, RAMDISK+31*512
1734
        add     eax, RAMDISK+31*512
1709
.writefile:
1735
.writefile:
1710
	mov	ebx, edx
1736
        mov     ebx, edx
1711
	xchg	eax, ebx
1737
        xchg    eax, ebx
1712
	push	ecx
1738
        push    ecx
1713
	mov	ecx, 512
1739
        mov     ecx, 512
1714
	cmp	dword [esp+12], ecx
1740
        cmp     dword [esp+12], ecx
1715
	jae	@f
1741
        jae     @f
1716
	mov	ecx, [esp+12]
1742
        mov     ecx, [esp+12]
1717
@@:
1743
@@:
1718
	call	memmove
1744
        call    memmove
1719
	add	edx, ecx
1745
        add     edx, ecx
1720
	sub	[esp+12], ecx
1746
        sub     [esp+12], ecx
1721
	pop	ecx
1747
        pop     ecx
1722
	jnz	.write_loop
1748
        jnz     .write_loop
1723
.done:
1749
.done:
1724
	mov	ebx, edx
1750
        mov     ebx, edx
1725
	pop	edi edi ecx edx
1751
        pop     edi edi ecx edx
1726
	sub	ebx, edx
1752
        sub     ebx, edx
1727
	mov	[edi+28], ebx
1753
        mov     [edi+28], ebx
1728
	add	esp, 20
1754
        add     esp, 20
1729
	mov	[esp+16], ebx
1755
        mov     [esp+16], ebx
1730
	popad
1756
        popad
1731
	xor	eax, eax
1757
        xor     eax, eax
1732
	ret
1758
        ret
1733
.disk_full2:
1759
.disk_full2:
1734
	mov	ebx, edx
1760
        mov     ebx, edx
1735
	pop	edi edi ecx edx
1761
        pop     edi edi ecx edx
1736
	sub	ebx, edx
1762
        sub     ebx, edx
1737
	mov	[edi+28], ebx
1763
        mov     [edi+28], ebx
1738
	add	esp, 20
1764
        add     esp, 20
1739
	mov	[esp+16], ebx
1765
        mov     [esp+16], ebx
1740
	popad
1766
        popad
1741
	push	ERROR_DISK_FULL
1767
        push    ERROR_DISK_FULL
1742
	pop	eax
1768
        pop     eax
1743
	ret
1769
        ret
1744
.writedir:
1770
.writedir:
1745
	mov	edi, eax
1771
        mov     edi, eax
1746
	shl	edi, 9
1772
        shl     edi, 9
1747
	add	edi, RAMDISK+31*512
1773
        add     edi, RAMDISK+31*512
1748
	mov	esi, edx
1774
        mov     esi, edx
1749
	mov	ecx, 32/4
1775
        mov     ecx, 32/4
1750
	push	ecx
1776
        push    ecx
1751
	rep	movsd
1777
        rep movsd
1752
	mov	dword [edi-32], '.   '
1778
        mov     dword [edi-32], '.   '
1753
	mov	dword [edi-32+4], '    '
1779
        mov     dword [edi-32+4], '    '
1754
	mov	dword [edi-32+8], '    '
1780
        mov     dword [edi-32+8], '    '
1755
	mov	byte [edi-32+11], 10h
1781
        mov     byte [edi-32+11], 10h
1756
	mov	word [edi-32+26], ax
1782
        mov     word [edi-32+26], ax
1757
	mov	esi, edx
1783
        mov     esi, edx
1758
	pop	ecx
1784
        pop     ecx
1759
	rep	movsd
1785
        rep movsd
1760
	mov	dword [edi-32], '..  '
1786
        mov     dword [edi-32], '..  '
1761
	mov	dword [edi-32+4], '    '
1787
        mov     dword [edi-32+4], '    '
1762
	mov	dword [edi-32+8], '    '
1788
        mov     dword [edi-32+8], '    '
1763
	mov	byte [edi-32+11], 10h
1789
        mov     byte [edi-32+11], 10h
1764
	mov	eax, [esp+16+8]
1790
        mov     eax, [esp+16+8]
1765
	mov	word [edi-32+26], ax
1791
        mov     word [edi-32+26], ax
1766
	xor	eax, eax
1792
        xor     eax, eax
1767
	mov	ecx, (512-32*2)/4
1793
        mov     ecx, (512-32*2)/4
1768
	rep	stosd
1794
        rep stosd
1769
	pop	edi edi ecx edx
1795
        pop     edi edi ecx edx
Line 1770... Line 1796...
1770
	add	esp, 20
1796
        add     esp, 20
1771
	popad
1797
        popad
1772
	xor	eax, eax
1798
        xor     eax, eax
1773
	xor	ebx, ebx
1799
        xor     ebx, ebx
1774
	ret
1800
        ret
1775
 
1801
 
1776
.read_symbol:
1802
.read_symbol:
1777
	or	ax, -1
1803
        or      ax, -1
1778
	test	esi, esi
1804
        test    esi, esi
1779
	jz	.retFFFF
1805
        jz      .retFFFF
1780
	lodsb
1806
        lodsb
Line 1781... Line 1807...
1781
	test	al, al
1807
        test    al, al
1782
	jnz	ansi2uni_char
1808
        jnz     ansi2uni_char
1783
	xor	eax, eax
1809
        xor     eax, eax
1784
	xor	esi, esi
1810
        xor     esi, esi
1785
.retFFFF:
1811
.retFFFF:
Line 1786... Line 1812...
1786
	ret
1812
        ret
1787
 
1813
 
1788
.read_symbols:
1814
.read_symbols:
1789
	call	.read_symbol
1815
        call    .read_symbol
Line 1804... Line 1830...
1804
;  ret ebx = bytes written (maybe 0)
1830
;  ret ebx = bytes written (maybe 0)
1805
;      eax = 0 ok write or other = errormsg
1831
;      eax = 0 ok write or other = errormsg
1806
;
1832
;
1807
;--------------------------------------------------------------
1833
;--------------------------------------------------------------
1808
@@:
1834
@@:
1809
	push	ERROR_ACCESS_DENIED
1835
        push    ERROR_ACCESS_DENIED
1810
fs_RamdiskWrite.ret0:
1836
fs_RamdiskWrite.ret0:
1811
	pop	eax
1837
        pop     eax
1812
	xor	ebx, ebx
1838
        xor     ebx, ebx
1813
	ret
1839
        ret
Line 1814... Line 1840...
1814
 
1840
 
1815
fs_RamdiskWrite:
1841
fs_RamdiskWrite:
1816
	cmp	byte [esi], 0
1842
        cmp     byte [esi], 0
1817
	jz	@b
1843
        jz      @b
1818
	pushad
1844
        pushad
1819
	call	rd_find_lfn
1845
        call    rd_find_lfn
1820
	jnc	.found
1846
        jnc     .found
1821
	popad
1847
        popad
1822
	push	ERROR_FILE_NOT_FOUND
1848
        push    ERROR_FILE_NOT_FOUND
1823
	jmp	.ret0
1849
        jmp     .ret0
1824
.found:
1850
.found:
1825
; must not be directory
1851
; must not be directory
1826
	test	byte [edi+11], 10h
1852
        test    byte [edi+11], 10h
1827
	jz	@f
1853
        jz      @f
1828
	popad
1854
        popad
1829
	push	ERROR_ACCESS_DENIED
1855
        push    ERROR_ACCESS_DENIED
1830
	jmp	.ret0
1856
        jmp     .ret0
1831
@@:
1857
@@:
1832
; FAT does not support files larger than 4GB
1858
; FAT does not support files larger than 4GB
1833
	test	ebx, ebx
1859
        test    ebx, ebx
1834
	jz	.l1
1860
        jz      .l1
1835
	cmp	dword [ebx+4], 0
1861
        cmp     dword [ebx+4], 0
1836
	jz	@f
1862
        jz      @f
1837
.eof:
1863
.eof:
1838
	popad
1864
        popad
1839
	push	ERROR_END_OF_FILE
1865
        push    ERROR_END_OF_FILE
1840
	jmp	.ret0
1866
        jmp     .ret0
1841
@@:
1867
@@:
1842
	mov	ebx, [ebx]
1868
        mov     ebx, [ebx]
1843
.l1:
1869
.l1:
1844
; now edi points to direntry, ebx=start byte to write,
1870
; now edi points to direntry, ebx=start byte to write,
1845
; ecx=number of bytes to write, edx=data pointer
1871
; ecx=number of bytes to write, edx=data pointer
Line 1846... Line 1872...
1846
	call	fat_update_datetime
1872
        call    fat_update_datetime
1847
 
1873
 
1848
; extend file if needed
1874
; extend file if needed
1849
	add	ecx, ebx
1875
        add     ecx, ebx
1850
	jc	.eof	; FAT does not support files larger than 4GB
1876
        jc      .eof    ; FAT does not support files larger than 4GB
1851
	push	0	; return value=0
1877
        push    0       ; return value=0
1852
	cmp	ecx, [edi+28]
1878
        cmp     ecx, [edi+28]
1853
	jbe	.length_ok
1879
        jbe     .length_ok
1854
	cmp	ecx, ebx
1880
        cmp     ecx, ebx
1855
	jz	.length_ok
1881
        jz      .length_ok
1856
	call	ramdisk_extend_file
1882
        call    ramdisk_extend_file
1857
	jnc	.length_ok
1883
        jnc     .length_ok
1858
; ramdisk_extend_file can return two error codes: FAT table error or disk full.
1884
; ramdisk_extend_file can return two error codes: FAT table error or disk full.
1859
; First case is fatal error, in second case we may write some data
1885
; First case is fatal error, in second case we may write some data
1860
	mov	[esp], eax
1886
        mov     [esp], eax
1861
	cmp	al, ERROR_DISK_FULL
1887
        cmp     al, ERROR_DISK_FULL
1862
	jz	.disk_full
1888
        jz      .disk_full
1863
	pop	eax
1889
        pop     eax
1864
	mov	[esp+28], eax
1890
        mov     [esp+28], eax
1865
	popad
1891
        popad
1866
	xor	ebx, ebx
1892
        xor     ebx, ebx
1867
	ret
1893
        ret
1868
.disk_full:
1894
.disk_full:
1869
; correct number of bytes to write
1895
; correct number of bytes to write
1870
	mov	ecx, [edi+28]
1896
        mov     ecx, [edi+28]
1871
	cmp	ecx, ebx
1897
        cmp     ecx, ebx
1872
	ja	.length_ok
1898
        ja      .length_ok
1873
.ret:
1899
.ret:
1874
	pop	eax
1900
        pop     eax
1875
	mov	[esp+28], eax	; eax=return value
1901
        mov     [esp+28], eax   ; eax=return value
1876
	sub	edx, [esp+20]
1902
        sub     edx, [esp+20]
1877
	mov	[esp+16], edx	; ebx=number of written bytes
1903
        mov     [esp+16], edx   ; ebx=number of written bytes
1878
	popad
1904
        popad
1879
	ret
1905
        ret
1880
.length_ok:
1906
.length_ok:
1881
; now ebx=start pos, ecx=end pos, both lie inside file
1907
; now ebx=start pos, ecx=end pos, both lie inside file
1882
	sub	ecx, ebx
1908
        sub     ecx, ebx
1883
	jz	.ret
1909
        jz      .ret
1884
	movzx	edi, word [edi+26]	; starting cluster
1910
        movzx   edi, word [edi+26]      ; starting cluster
1885
.write_loop:
1911
.write_loop:
1886
	sub	ebx, 0x200
1912
        sub     ebx, 0x200
1887
	jae	.next_cluster
1913
        jae     .next_cluster
1888
	push	ecx
1914
        push    ecx
1889
	neg	ebx
1915
        neg     ebx
1890
	cmp	ecx, ebx
1916
        cmp     ecx, ebx
1891
	jbe	@f
1917
        jbe     @f
1892
	mov	ecx, ebx
1918
        mov     ecx, ebx
1893
@@:
1919
@@:
1894
	mov	eax, edi
1920
        mov     eax, edi
1895
	shl	eax, 9
1921
        shl     eax, 9
1896
	add	eax, RAMDISK+31*512+0x200
1922
        add     eax, RAMDISK+31*512+0x200
1897
	sub	eax, ebx
1923
        sub     eax, ebx
1898
	mov	ebx, eax
1924
        mov     ebx, eax
1899
	mov	eax, edx
1925
        mov     eax, edx
1900
	call	memmove
1926
        call    memmove
1901
	xor	ebx, ebx
1927
        xor     ebx, ebx
1902
	add	edx, ecx
1928
        add     edx, ecx
1903
	sub	[esp], ecx
1929
        sub     [esp], ecx
1904
	pop	ecx
1930
        pop     ecx
1905
	jz	.ret
1931
        jz      .ret
1906
.next_cluster:
1932
.next_cluster:
Line 1907... Line 1933...
1907
	movzx	edi, word [edi*2+RAMDISK_FAT]
1933
        movzx   edi, word [edi*2+RAMDISK_FAT]
1908
	jmp	.write_loop
1934
        jmp     .write_loop
1909
 
1935
 
Line 1910... Line 1936...
1910
ramdisk_extend_file.zero_size:
1936
ramdisk_extend_file.zero_size:
1911
	xor	eax, eax
1937
        xor     eax, eax
1912
	jmp	ramdisk_extend_file.start_extend
1938
        jmp     ramdisk_extend_file.start_extend
1913
 
1939
 
1914
; extends file on ramdisk to given size, new data area is filled by 0
1940
; extends file on ramdisk to given size, new data area is filled by 0
1915
; in: edi->direntry, ecx=new size
1941
; in: edi->direntry, ecx=new size
1916
; out: CF=0 => OK, eax=0
1942
; out: CF=0 => OK, eax=0
1917
;      CF=1 => error, eax=code (ERROR_FAT_TABLE or ERROR_DISK_FULL)
1943
;      CF=1 => error, eax=code (ERROR_FAT_TABLE or ERROR_DISK_FULL)
1918
ramdisk_extend_file:
1944
ramdisk_extend_file:
1919
	push	ecx
1945
        push    ecx
1920
; find the last cluster of file
1946
; find the last cluster of file
1921
	movzx	eax, word [edi+26]	; first cluster
1947
        movzx   eax, word [edi+26]      ; first cluster
1922
	mov	ecx, [edi+28]
1948
        mov     ecx, [edi+28]
1923
	jecxz	.zero_size
1949
        jecxz   .zero_size
1924
@@:
1950
@@:
1925
	sub	ecx, 0x200
1951
        sub     ecx, 0x200
1926
	jbe	@f
1952
        jbe     @f
1927
	mov	eax, [eax*2+RAMDISK_FAT]
1953
        mov     eax, [eax*2+RAMDISK_FAT]
1928
	and	eax, 0xFFF
1954
        and     eax, 0xFFF
1929
	jz	.fat_err
1955
        jz      .fat_err
1930
	cmp	eax, 0xFF8
1956
        cmp     eax, 0xFF8
1931
	jb	@b
1957
        jb      @b
1932
.fat_err:
1958
.fat_err:
1933
	pop	ecx
1959
        pop     ecx
1934
	push	ERROR_FAT_TABLE
1960
        push    ERROR_FAT_TABLE
1935
	pop	eax
1961
        pop     eax
1936
	stc
1962
        stc
1937
	ret
1963
        ret
1938
@@:
1964
@@:
1939
	push	eax
1965
        push    eax
1940
	mov	eax, [eax*2+RAMDISK_FAT]
1966
        mov     eax, [eax*2+RAMDISK_FAT]
1941
	and	eax, 0xFFF
1967
        and     eax, 0xFFF
1942
	cmp	eax, 0xFF8
1968
        cmp     eax, 0xFF8
1943
	pop	eax
1969
        pop     eax
1944
	jb	.fat_err
1970
        jb      .fat_err
1945
; set length to full number of sectors and make sure that last sector is zero-padded
1971
; set length to full number of sectors and make sure that last sector is zero-padded
1946
	sub	[edi+28], ecx
1972
        sub     [edi+28], ecx
1947
	push	eax edi
1973
        push    eax edi
1948
	mov	edi, eax
1974
        mov     edi, eax
1949
	shl	edi, 9
1975
        shl     edi, 9
1950
	lea	edi, [edi+RAMDISK+31*512+0x200+ecx]
1976
        lea     edi, [edi+RAMDISK+31*512+0x200+ecx]
1951
	neg	ecx
1977
        neg     ecx
1952
	xor	eax, eax
1978
        xor     eax, eax
1953
	rep	stosb
1979
        rep stosb
1954
	pop	edi eax
1980
        pop     edi eax
1955
.start_extend:
1981
.start_extend:
1956
	pop	ecx
1982
        pop     ecx
1957
; now do extend
1983
; now do extend
1958
	push	edx esi
1984
        push    edx esi
1959
	mov	esi, RAMDISK_FAT+2*2	   ; start scan from cluster 2
1985
        mov     esi, RAMDISK_FAT+2*2       ; start scan from cluster 2
1960
	mov	edx, 2847		; number of clusters to scan
1986
        mov     edx, 2847               ; number of clusters to scan
1961
.extend_loop:
1987
.extend_loop:
1962
	cmp	[edi+28], ecx
1988
        cmp     [edi+28], ecx
1963
	jae	.extend_done
1989
        jae     .extend_done
1964
; add new sector
1990
; add new sector
1965
	push	ecx
1991
        push    ecx
1966
	mov	ecx, edx
1992
        mov     ecx, edx
1967
	push	edi
1993
        push    edi
1968
	mov	edi, esi
1994
        mov     edi, esi
1969
	jecxz	.disk_full
1995
        jecxz   .disk_full
1970
	push	eax
1996
        push    eax
1971
	xor	eax, eax
1997
        xor     eax, eax
1972
	repnz	scasw
1998
        repnz scasw
1973
	pop	eax
1999
        pop     eax
1974
	jnz	.disk_full
2000
        jnz     .disk_full
1975
	mov	word [edi-2], 0xFFF
2001
        mov     word [edi-2], 0xFFF
1976
	mov	esi, edi
2002
        mov     esi, edi
1977
	mov	edx, ecx
2003
        mov     edx, ecx
1978
	sub	edi, RAMDISK_FAT
2004
        sub     edi, RAMDISK_FAT
1979
	shr	edi, 1
2005
        shr     edi, 1
1980
	dec	edi	; now edi=new cluster
2006
        dec     edi     ; now edi=new cluster
1981
	test	eax, eax
2007
        test    eax, eax
1982
	jz	.first_cluster
2008
        jz      .first_cluster
1983
	mov	[RAMDISK_FAT+eax*2], di
2009
        mov     [RAMDISK_FAT+eax*2], di
1984
	jmp	@f
2010
        jmp     @f
1985
.first_cluster:
2011
.first_cluster:
1986
	pop	eax	; eax->direntry
2012
        pop     eax     ; eax->direntry
1987
	push	eax
2013
        push    eax
1988
	mov	[eax+26], di
2014
        mov     [eax+26], di
1989
@@:
2015
@@:
1990
	push	edi
2016
        push    edi
1991
	shl	edi, 9
2017
        shl     edi, 9
1992
	add	edi, RAMDISK+31*512
2018
        add     edi, RAMDISK+31*512
1993
	xor	eax, eax
2019
        xor     eax, eax
1994
	mov	ecx, 512/4
2020
        mov     ecx, 512/4
1995
	rep	stosd
2021
        rep stosd
1996
	pop	eax	; eax=new cluster
2022
        pop     eax     ; eax=new cluster
1997
	pop	edi	; edi->direntry
2023
        pop     edi     ; edi->direntry
1998
	pop	ecx	; ecx=required size
2024
        pop     ecx     ; ecx=required size
1999
	add	dword [edi+28], 0x200
2025
        add     dword [edi+28], 0x200
2000
	jmp	.extend_loop
2026
        jmp     .extend_loop
2001
.extend_done:
2027
.extend_done:
2002
	mov	[edi+28], ecx
2028
        mov     [edi+28], ecx
2003
	pop	esi edx
2029
        pop     esi edx
2004
	xor	eax, eax	; CF=0
2030
        xor     eax, eax        ; CF=0
2005
	ret
2031
        ret
2006
.disk_full:
2032
.disk_full:
2007
	pop	edi ecx
2033
        pop     edi ecx
2008
	pop	esi edx
2034
        pop     esi edx
Line 2009... Line 2035...
2009
	stc
2035
        stc
2010
	push	ERROR_DISK_FULL
2036
        push    ERROR_DISK_FULL
2011
	pop	eax
2037
        pop     eax
2012
	ret
2038
        ret
2013
 
2039
 
2014
fat_update_datetime:
2040
fat_update_datetime:
2015
	call	get_time_for_file
2041
        call    get_time_for_file
Line 2016... Line 2042...
2016
	mov	[edi+22], ax		; last write time
2042
        mov     [edi+22], ax            ; last write time
2017
	call	get_date_for_file
2043
        call    get_date_for_file
2018
	mov	[edi+24], ax		; last write date
2044
        mov     [edi+24], ax            ; last write date
2019
	mov	[edi+18], ax		; last access date
2045
        mov     [edi+18], ax            ; last access date
Line 2030... Line 2056...
2030
;
2056
;
2031
;  ret eax = 0 ok or other = errormsg
2057
;  ret eax = 0 ok or other = errormsg
2032
;
2058
;
2033
;--------------------------------------------------------------
2059
;--------------------------------------------------------------
2034
fs_RamdiskSetFileEnd:
2060
fs_RamdiskSetFileEnd:
2035
	cmp	byte [esi], 0
2061
        cmp     byte [esi], 0
2036
	jnz	@f
2062
        jnz     @f
2037
.access_denied:
2063
.access_denied:
2038
	push	ERROR_ACCESS_DENIED
2064
        push    ERROR_ACCESS_DENIED
2039
	jmp	.ret
2065
        jmp     .ret
2040
@@:
2066
@@:
2041
	push	edi
2067
        push    edi
2042
	call	rd_find_lfn
2068
        call    rd_find_lfn
2043
	jnc	@f
2069
        jnc     @f
2044
	pop	edi
2070
        pop     edi
2045
	push	ERROR_FILE_NOT_FOUND
2071
        push    ERROR_FILE_NOT_FOUND
2046
.ret:
2072
.ret:
2047
	pop	eax
2073
        pop     eax
2048
	ret
2074
        ret
2049
@@:
2075
@@:
2050
; must not be directory
2076
; must not be directory
2051
	test	byte [edi+11], 10h
2077
        test    byte [edi+11], 10h
2052
	jz	@f
2078
        jz      @f
2053
	pop	edi
2079
        pop     edi
2054
	jmp	.access_denied
2080
        jmp     .access_denied
2055
@@:
2081
@@:
2056
; file size must not exceed 4Gb
2082
; file size must not exceed 4Gb
2057
	cmp	dword [ebx+4], 0
2083
        cmp     dword [ebx+4], 0
2058
	jz	@f
2084
        jz      @f
2059
	pop	edi
2085
        pop     edi
2060
	push	ERROR_END_OF_FILE
2086
        push    ERROR_END_OF_FILE
2061
	jmp	.ret
2087
        jmp     .ret
2062
@@:
2088
@@:
2063
; set file modification date/time to current
2089
; set file modification date/time to current
2064
	call	fat_update_datetime
2090
        call    fat_update_datetime
2065
	mov	eax, [ebx]
2091
        mov     eax, [ebx]
2066
	cmp	eax, [edi+28]
2092
        cmp     eax, [edi+28]
2067
	jb	.truncate
2093
        jb      .truncate
2068
	ja	.expand
2094
        ja      .expand
2069
	pop	edi
2095
        pop     edi
2070
	xor	eax, eax
2096
        xor     eax, eax
2071
	ret
2097
        ret
2072
.expand:
2098
.expand:
2073
	push	ecx
2099
        push    ecx
2074
	mov	ecx, eax
2100
        mov     ecx, eax
2075
	call	ramdisk_extend_file
2101
        call    ramdisk_extend_file
2076
	pop	ecx
2102
        pop     ecx
2077
	pop	edi
2103
        pop     edi
2078
	ret
2104
        ret
2079
.truncate:
2105
.truncate:
2080
	mov	[edi+28], eax
2106
        mov     [edi+28], eax
2081
	push	ecx
2107
        push    ecx
2082
	movzx	ecx, word [edi+26]
2108
        movzx   ecx, word [edi+26]
2083
	test	eax, eax
2109
        test    eax, eax
2084
	jz	.zero_size
2110
        jz      .zero_size
2085
; find new last sector
2111
; find new last sector
2086
@@:
2112
@@:
2087
	sub	eax, 0x200
2113
        sub     eax, 0x200
2088
	jbe	@f
2114
        jbe     @f
2089
	movzx	ecx, word [RAMDISK_FAT+ecx*2]
2115
        movzx   ecx, word [RAMDISK_FAT+ecx*2]
2090
	jmp	@b
2116
        jmp     @b
2091
@@:
2117
@@:
2092
; zero data at the end of last sector
2118
; zero data at the end of last sector
2093
	push	ecx
2119
        push    ecx
2094
	mov	edi, ecx
2120
        mov     edi, ecx
2095
	shl	edi, 9
2121
        shl     edi, 9
2096
	lea	edi, [edi+RAMDISK+31*512+eax+0x200]
2122
        lea     edi, [edi+RAMDISK+31*512+eax+0x200]
2097
	mov	ecx, eax
2123
        mov     ecx, eax
2098
	neg	ecx
2124
        neg     ecx
2099
	xor	eax, eax
2125
        xor     eax, eax
2100
	rep	stosb
2126
        rep stosb
2101
	pop	ecx
2127
        pop     ecx
2102
; terminate FAT chain
2128
; terminate FAT chain
2103
	lea	ecx, [RAMDISK_FAT+ecx+ecx]
2129
        lea     ecx, [RAMDISK_FAT+ecx+ecx]
2104
	push	dword [ecx]
2130
        push    dword [ecx]
2105
	mov	word [ecx], 0xFFF
2131
        mov     word [ecx], 0xFFF
2106
	pop	ecx
2132
        pop     ecx
2107
	and	ecx, 0xFFF
2133
        and     ecx, 0xFFF
2108
	jmp	.delete
2134
        jmp     .delete
2109
.zero_size:
2135
.zero_size:
2110
	and	word [edi+26], 0
2136
        and     word [edi+26], 0
2111
.delete:
2137
.delete:
2112
; delete FAT chain starting with ecx
2138
; delete FAT chain starting with ecx
2113
; mark all clusters as free
2139
; mark all clusters as free
2114
	cmp	ecx, 0xFF8
2140
        cmp     ecx, 0xFF8
2115
	jae	.deleted
2141
        jae     .deleted
2116
	lea	ecx, [RAMDISK_FAT+ecx+ecx]
2142
        lea     ecx, [RAMDISK_FAT+ecx+ecx]
2117
	push	dword [ecx]
2143
        push    dword [ecx]
2118
	and	word [ecx], 0
2144
        and     word [ecx], 0
2119
	pop	ecx
2145
        pop     ecx
2120
	and	ecx, 0xFFF
2146
        and     ecx, 0xFFF
2121
	jmp	.delete
2147
        jmp     .delete
2122
.deleted:
2148
.deleted:
2123
	pop	ecx
2149
        pop     ecx
2124
	pop	edi
2150
        pop     edi
2125
	xor	eax, eax
2151
        xor     eax, eax
2126
	ret
2152
        ret
Line 2127... Line 2153...
2127
 
2153
 
2128
fs_RamdiskGetFileInfo:
2154
fs_RamdiskGetFileInfo:
2129
	cmp	byte [esi], 0
2155
        cmp     byte [esi], 0
2130
	jnz	@f
2156
        jnz     @f
2131
	mov	eax, 2	; unsupported
2157
        mov     eax, 2  ; unsupported
2132
	ret
2158
        ret
2133
@@:
2159
@@:
2134
	push	edi
2160
        push    edi
2135
	call	rd_find_lfn
2161
        call    rd_find_lfn
2136
fs_GetFileInfo_finish:
2162
fs_GetFileInfo_finish:
2137
	jnc	@f
2163
        jnc     @f
2138
	pop	edi
2164
        pop     edi
2139
	mov	eax, ERROR_FILE_NOT_FOUND
2165
        mov     eax, ERROR_FILE_NOT_FOUND
2140
	ret
2166
        ret
2141
@@:
2167
@@:
2142
	push	esi ebp
2168
        push    esi ebp
2143
	xor	ebp, ebp
2169
        xor     ebp, ebp
2144
	mov	esi, edx
2170
        mov     esi, edx
2145
	and	dword [esi+4], 0
2171
        and     dword [esi+4], 0
2146
	call	fat_entry_to_bdfe2
2172
        call    fat_entry_to_bdfe2
2147
	pop	ebp esi
2173
        pop     ebp esi
2148
	pop	edi
2174
        pop     edi
2149
	xor	eax, eax
2175
        xor     eax, eax
Line 2150... Line 2176...
2150
	ret
2176
        ret
2151
 
2177
 
2152
fs_RamdiskSetFileInfo:
2178
fs_RamdiskSetFileInfo:
2153
	cmp	byte [esi], 0
2179
        cmp     byte [esi], 0
2154
	jnz	@f
2180
        jnz     @f
2155
	mov	eax, 2	; unsupported
2181
        mov     eax, 2  ; unsupported
2156
	ret
2182
        ret
2157
@@:
2183
@@:
2158
	push	edi
2184
        push    edi
2159
	call	rd_find_lfn
2185
        call    rd_find_lfn
2160
	jnc	@f
2186
        jnc     @f
2161
	pop	edi
2187
        pop     edi
2162
	mov	eax, ERROR_FILE_NOT_FOUND
2188
        mov     eax, ERROR_FILE_NOT_FOUND
2163
	ret
2189
        ret
2164
@@:
2190
@@:
2165
	call	bdfe_to_fat_entry
2191
        call    bdfe_to_fat_entry
2166
	pop	edi
2192
        pop     edi
Line 2167... Line 2193...
2167
	xor	eax, eax
2193
        xor     eax, eax
2168
	ret
2194
        ret
2169
 
2195
 
2170
;----------------------------------------------------------------
2196
;----------------------------------------------------------------
Line 2175... Line 2201...
2175
;
2201
;
2176
;  ret  eax = 0 ok or other = errormsg
2202
;  ret  eax = 0 ok or other = errormsg
2177
;
2203
;
2178
;--------------------------------------------------------------
2204
;--------------------------------------------------------------
2179
fs_RamdiskDelete:
2205
fs_RamdiskDelete:
2180
	cmp	byte [esi], 0
2206
        cmp     byte [esi], 0
2181
	jnz	@f
2207
        jnz     @f
2182
; cannot delete root!
2208
; cannot delete root!
2183
.access_denied:
2209
.access_denied:
2184
	push	ERROR_ACCESS_DENIED
2210
        push    ERROR_ACCESS_DENIED
2185
.pop_ret:
2211
.pop_ret:
2186
	pop	eax
2212
        pop     eax
2187
	ret
2213
        ret
2188
@@:
2214
@@:
2189
	and	[rd_prev_sector], 0
2215
        and     [rd_prev_sector], 0
2190
	and	[rd_prev_prev_sector], 0
2216
        and     [rd_prev_prev_sector], 0
2191
	push	edi
2217
        push    edi
2192
	call	rd_find_lfn
2218
        call    rd_find_lfn
2193
	jnc	.found
2219
        jnc     .found
2194
	pop	edi
2220
        pop     edi
2195
	push	ERROR_FILE_NOT_FOUND
2221
        push    ERROR_FILE_NOT_FOUND
2196
	jmp	.pop_ret
2222
        jmp     .pop_ret
2197
.found:
2223
.found:
2198
	cmp	dword [edi], '.   '
2224
        cmp     dword [edi], '.   '
2199
	jz	.access_denied2
2225
        jz      .access_denied2
2200
	cmp	dword [edi], '..  '
2226
        cmp     dword [edi], '..  '
2201
	jz	.access_denied2
2227
        jz      .access_denied2
2202
	test	byte [edi+11], 10h
2228
        test    byte [edi+11], 10h
2203
	jz	.dodel
2229
        jz      .dodel
2204
; we can delete only empty folders!
2230
; we can delete only empty folders!
2205
	movzx	eax, word [edi+26]
2231
        movzx   eax, word [edi+26]
2206
	push	ebx
2232
        push    ebx
2207
	mov	ebx, eax
2233
        mov     ebx, eax
2208
	shl	ebx, 9
2234
        shl     ebx, 9
2209
	add	ebx, RAMDISK + 31*0x200 + 2*0x20
2235
        add     ebx, RAMDISK + 31*0x200 + 2*0x20
2210
.checkempty:
2236
.checkempty:
2211
	cmp	byte [ebx], 0
2237
        cmp     byte [ebx], 0
2212
	jz	.empty
2238
        jz      .empty
2213
	cmp	byte [ebx], 0xE5
2239
        cmp     byte [ebx], 0xE5
2214
	jnz	.notempty
2240
        jnz     .notempty
2215
	add	ebx, 0x20
2241
        add     ebx, 0x20
2216
	test	ebx, 0x1FF
2242
        test    ebx, 0x1FF
2217
	jnz	.checkempty
2243
        jnz     .checkempty
2218
	movzx	eax, word [RAMDISK_FAT + eax*2]
2244
        movzx   eax, word [RAMDISK_FAT + eax*2]
2219
	test	eax, eax
2245
        test    eax, eax
2220
	jz	.empty
2246
        jz      .empty
2221
	mov	ebx, eax
2247
        mov     ebx, eax
2222
	shl	ebx, 9
2248
        shl     ebx, 9
2223
	add	ebx, RAMDISK + 31*0x200
2249
        add     ebx, RAMDISK + 31*0x200
2224
	jmp	.checkempty
2250
        jmp     .checkempty
2225
.notempty:
2251
.notempty:
2226
	pop	ebx
2252
        pop     ebx
2227
.access_denied2:
2253
.access_denied2:
2228
	pop	edi
2254
        pop     edi
2229
	jmp	.access_denied
2255
        jmp     .access_denied
2230
.empty:
2256
.empty:
2231
	pop	ebx
2257
        pop     ebx
2232
.dodel:
2258
.dodel:
2233
	movzx	eax, word [edi+26]
2259
        movzx   eax, word [edi+26]
2234
; delete folder entry
2260
; delete folder entry
2235
	mov	byte [edi], 0xE5
2261
        mov     byte [edi], 0xE5
2236
; delete LFN (if present)
2262
; delete LFN (if present)
2237
.lfndel:
2263
.lfndel:
2238
	test	edi, 0x1FF
2264
        test    edi, 0x1FF
2239
	jnz	@f
2265
        jnz     @f
2240
	cmp	[rd_prev_sector], 0
2266
        cmp     [rd_prev_sector], 0
2241
	jz	@f
2267
        jz      @f
2242
	cmp	[rd_prev_sector], -1
2268
        cmp     [rd_prev_sector], -1
2243
	jz	.lfndone
2269
        jz      .lfndone
2244
	mov	edi, [rd_prev_sector]
2270
        mov     edi, [rd_prev_sector]
2245
	push	[rd_prev_prev_sector]
2271
        push    [rd_prev_prev_sector]
2246
	pop	[rd_prev_sector]
2272
        pop     [rd_prev_sector]
2247
	or	[rd_prev_prev_sector], -1
2273
        or      [rd_prev_prev_sector], -1
2248
	shl	edi, 9
2274
        shl     edi, 9
2249
	add	edi, RAMDISK + 31*0x200 + 0x200
2275
        add     edi, RAMDISK + 31*0x200 + 0x200
2250
@@:
2276
@@:
2251
	sub	edi, 0x20
2277
        sub     edi, 0x20
2252
	cmp	byte [edi], 0xE5
2278
        cmp     byte [edi], 0xE5
2253
	jz	.lfndone
2279
        jz      .lfndone
2254
	cmp	byte [edi+11], 0xF
2280
        cmp     byte [edi+11], 0xF
2255
	jnz	.lfndone
2281
        jnz     .lfndone
2256
	mov	byte [edi], 0xE5
2282
        mov     byte [edi], 0xE5
2257
	jmp	.lfndel
2283
        jmp     .lfndel
2258
.lfndone:
2284
.lfndone:
2259
; delete FAT chain
2285
; delete FAT chain
2260
        cmp     eax, 2
2286
        cmp     eax, 2
2261
        jb      .done
2287
        jb      .done
2262
        cmp     eax, 0xFF8
2288
        cmp     eax, 0xFF8
2263
        jae     .done
2289
        jae     .done
2264
	lea	eax, [RAMDISK_FAT + eax*2]
2290
        lea     eax, [RAMDISK_FAT + eax*2]
2265
	push	dword [eax]
2291
        push    dword [eax]
2266
	and	word [eax], 0
2292
        and     word [eax], 0
2267
	pop	eax
2293
        pop     eax
2268
	and	eax, 0xFFF
2294
        and     eax, 0xFFF
2269
	jmp	.lfndone
2295
        jmp     .lfndone
2270
.done:
2296
.done:
2271
	pop	edi
2297
        pop     edi
2272
	xor	eax, eax
2298
        xor     eax, eax
2273
	ret
2299
        ret
Line 2274... Line 2300...
2274
 
2300