Subversion Repositories Kolibri OS

Rev

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

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