Subversion Repositories Kolibri OS

Rev

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

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