Subversion Repositories Kolibri OS

Rev

Rev 845 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
717 mikedld 1
;;================================================================================================;;
2
;;//// libio.asm //// (c) mike.dld, 2006-2008 ////////////////////////////////////////////////////;;
3
;;================================================================================================;;
4
;;                                                                                                ;;
5
;; This file is part of Common development libraries (Libs-Dev).                                  ;;
6
;;                                                                                                ;;
7
;; Libs-Dev is free software: you can redistribute it and/or modify it under the terms of the GNU ;;
8
;; General Public License as published by the Free Software Foundation, either version 3 of the   ;;
9
;; License, or (at your option) any later version.                                                ;;
10
;;                                                                                                ;;
11
;; Libs-Dev is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without  ;;
12
;; even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU  ;;
13
;; General Public License for more details.                                                       ;;
14
;;                                                                                                ;;
15
;; You should have received a copy of the GNU General Public License along with Libs-Dev. If not, ;;
16
;; see .                                                            ;;
17
;;                                                                                                ;;
18
;;================================================================================================;;
19
;;                                                                                                ;;
20
;; 2007-12-10 (mike.dld)                                                                          ;;
21
;;   changes:                                                                                     ;;
22
;;     - almost fully incompatible with previous version since return values were changed.        ;;
23
;;       now they are more C-like                                                                 ;;
24
;;   notes:                                                                                       ;;
25
;;     - `file.err` is not yet available                                                          ;;
26
;; 2007-09-26 (mike.dld)                                                                          ;;
27
;;   changes:                                                                                     ;;
28
;;     - modified `file.size` a bit (according to changes in FileInfo struct)                     ;;
29
;;     - added `file.find_first`, `file.find_next`, `file.find_close`                             ;;
30
;;   notes:                                                                                       ;;
31
;;     - `file.aux.match_wildcard` is exported only for testing purposes, don't                   ;;
32
;;       use it since it may be removed or renamed in next versions                               ;;
33
;;                                                                                                ;;
34
;;================================================================================================;;
35
 
36
 
37
format MS COFF
38
 
39
public @EXPORT as 'EXPORTS'
40
 
41
include '../../../../proc32.inc'
42
include '../../../../macros.inc'
43
purge section;mov,add,sub
44
 
45
include 'libio.inc'
46
include 'libio_p.inc'
47
 
48
section '.flat' code readable align 16
49
 
50
mem.alloc   dd ?
51
mem.free    dd ?
52
mem.realloc dd ?
53
dll.load    dd ?
54
 
55
;;================================================================================================;;
56
proc lib_init ;///////////////////////////////////////////////////////////////////////////////////;;
57
;;------------------------------------------------------------------------------------------------;;
58
;? Library entry point (called after library load)                                                ;;
59
;;------------------------------------------------------------------------------------------------;;
60
;> eax = pointer to memory allocation routine                                                     ;;
61
;> ebx = pointer to memory freeing routine                                                        ;;
62
;> ecx = pointer to memory reallocation routine                                                   ;;
63
;> edx = pointer to library loading routine                                                       ;;
64
;;------------------------------------------------------------------------------------------------;;
65
;< eax = 1 (fail) / 0 (ok) (library initialization result)                                        ;;
66
;;================================================================================================;;
67
	mov	[mem.alloc], eax
68
	mov	[mem.free], ebx
69
	mov	[mem.realloc], ecx
70
	mov	[dll.load], edx
71
	xor	eax, eax
72
	ret
73
endp
74
 
75
;;================================================================================================;;
76
proc file.aux.match_wildcard _str, _wcard ;///////////////////////////////////////////////////////;;
77
;;------------------------------------------------------------------------------------------------;;
78
;? Match string against wildcard                                                                  ;;
79
;? Based on http://user.cs.tu-berlin.de/~schintke/references/wildcards/                           ;;
80
;? 1997-2001 (c) Florian Schintke                                                                 ;;
81
;;------------------------------------------------------------------------------------------------;;
82
;> _str = pointer to string (filename in most cases)                                              ;;
83
;> _wcard = pointer to string (mask expressed using wilcards (?, *, [..]))                        ;;
84
;;------------------------------------------------------------------------------------------------;;
85
;< eax = false / true (match result)                                                              ;;
86
;;================================================================================================;;
87
	push	ecx edx esi edi
88
	mov	dl, 1 ; fit
89
	mov	esi, [_wcard]
90
	mov	edi, [_str]
91
  .loop_wildcard:
92
	mov	al, [esi]
93
	or	al, al
94
	jz	.loop_wildcard_exit
95
	or	dl, dl
96
	jz	.loop_wildcard_exit
97
	cmp	byte[edi], 0
98
	je	.loop_wildcard_exit
99
 
100
	cmp	al, '['
101
	je	.process_set
102
	cmp	al, '?'
103
	je	.process_question
104
	cmp	al, '*'
105
	je	.process_asterisk
106
 
107
	xor	dl, dl
108
	cmp	[edi], al
109
	jne	@f
110
	inc	dl
111
    @@: inc	edi
112
 
113
  .loop_wildcard_next:
114
	inc	esi
115
	jmp	.loop_wildcard
116
 
117
 
118
  .process_set:
119
	inc	esi
120
	xor	dl, dl ; fit
121
	xor	dh, dh ; negation
122
	mov	cl, 1  ; at_beginning
123
	cmp	byte[esi], '^'
124
	jne	.loop_set_wildcard
125
	inc	dh
126
	inc	esi
127
 
128
    .loop_set_wildcard:
129
	mov	al, [esi]
130
	cmp	al, ']'
131
	jne	@f
132
	or	cl, cl
133
	jz	.loop_set_wildcard_exit
134
    @@: or	dl, dl
135
	jnz	.loop_set_wildcard_fit
136
	cmp	al, '-'
137
	jne	.loop_set_wildcard_not_range
138
	mov	ch, [esi - 1]
139
	cmp	[esi + 1], ch
140
	jbe	.loop_set_wildcard_not_range
141
	cmp	byte[esi + 1], ']'
142
	je	.loop_set_wildcard_not_range
143
	or	cl, cl
144
	jnz	.loop_set_wildcard_not_range
145
	cmp	[edi], ch
146
	jb	.loop_set_wildcard_fit
147
	mov	ch, [esi + 1]
148
	cmp	[edi], ch
149
	ja	.loop_set_wildcard_fit
150
	mov	dl, 1
151
	inc	esi
152
	jmp	.loop_set_wildcard_fit
153
 
154
    .loop_set_wildcard_not_range:
155
	cmp	[edi], al
156
	jne	.loop_set_wildcard_fit
157
	mov	dl, 1
158
 
159
    .loop_set_wildcard_fit:
160
	inc	esi
161
	xor	cl, cl
162
	jmp	.loop_set_wildcard
163
 
164
    .loop_set_wildcard_exit:
165
	or	dh, dh
166
	jz	@f
167
	xor	dl, 1
168
    @@: or	dl, dl
169
	jz	@f
170
	inc	edi
171
    @@:
172
	jmp	.loop_wildcard_next
173
 
174
  .process_question:
175
	inc	edi
176
	jmp	.loop_wildcard_next
177
 
178
  .process_asterisk:
179
	mov	dl, 1
180
	inc	esi
181
 
182
    .loop_asterisk_del_shit:
183
	lodsb
184
	cmp	byte[edi], 0
185
	je	.loop_asterisk_del_shit_exit
186
	cmp	al, '?'
187
	jne	@f
188
	inc	edi
189
	jmp	.loop_asterisk_del_shit
190
    @@: cmp	al, '*'
191
	je	.loop_asterisk_del_shit
192
 
193
    .loop_asterisk_del_shit_exit:
194
 
195
    @@: cmp	al, '*'
196
	jne	@f
197
	lodsb
198
	jmp	@b
199
    @@:
200
	dec	esi
201
	cmp	byte[edi], 0
202
	jne	.process_asterisk_skip_exit
203
	xor	dl, dl
204
	or	al, al
205
	jnz	@f
206
	inc	dl
207
    @@: dec	esi
208
	jmp	.loop_wildcard_next
209
 
210
    .process_asterisk_skip_exit:
211
	stdcall file.aux.match_wildcard, edi, esi
212
	or	eax, eax
213
	jnz	.process_asterisk_not_match
214
 
215
    .loop_asterisk_match:
216
	inc	edi
217
 
218
    .loop_asterisk_char_match:
219
	mov	al, [esi]
220
	cmp	[edi], al
221
	je	.loop_asterisk_char_match_exit
222
	cmp	byte[esi], '['
223
	je	.loop_asterisk_char_match_exit
224
	cmp	byte[edi], 0
225
	je	.loop_asterisk_char_match_exit
226
	inc	edi
227
	jmp	.loop_asterisk_char_match
228
 
229
    .loop_asterisk_char_match_exit:
230
	cmp	byte[edi], 0
231
	je	@f
232
	stdcall file.aux.match_wildcard, edi, esi
233
	or	eax, eax
234
	jnz	.loop_asterisk_match_exit
235
	jmp	.loop_asterisk_match
236
    @@:
237
	xor	dl, dl
238
 
239
    .loop_asterisk_match_exit:
240
 
241
    .process_asterisk_not_match:
242
	cmp	byte[esi], 0
243
	jne	@f
244
	cmp	byte[edi], 0
245
	jne	@f
246
	mov	dl, 1
247
    @@:
248
	dec	esi
249
	jmp	.loop_wildcard_next
250
 
251
  .loop_wildcard_exit:
252
	or	dl, dl
253
	jz	.exit
254
    @@: cmp	byte[esi], '*'
255
	jne	.exit
256
	inc	esi
257
	jmp	@b
258
 
259
  .exit:
260
	cmp	byte[esi], 0
261
	je	@f
262
	xor	dl, dl
263
    @@: cmp	byte[edi], 0
264
	je	@f
265
	xor	dl, dl
266
    @@:
267
	movzx	eax, dl
268
 
269
	pop	edi esi edx ecx
270
	ret
271
endp
272
 
273
;;================================================================================================;;
274
proc file.aux.find_matching_file _ffb ;///////////////////////////////////////////////////////////;;
275
;;------------------------------------------------------------------------------------------------;;
276
;? Find file with matching attributes (`FindFileBlock.Options.Attributes`) and mask               ;;
277
;? (`FindFileBlock.Options.Mask`) starting from Nth (`FindFileBlock.InfoBlock.Position`) file in  ;;
278
;? directory (`FindFileBlock.InfoBlock.FileName`)                                                 ;;
279
;;------------------------------------------------------------------------------------------------;;
280
;> _ffb = pointer to FindFileBlock                                                                ;;
281
;;------------------------------------------------------------------------------------------------;;
282
;< eax = 0 (error) / pointer to `FileInfo` with matched file data                                 ;;
283
;;================================================================================================;;
284
	push	ebx edx
285
	mov	edx, [_ffb]
286
  .loop_find:
287
	lea	ebx, [edx + FindFileBlock.InfoBlock]
288
	mcall	70
289
	or	eax, eax
290
	jnz	.loop_find_error
291
	mov	eax, [edx + FindFileBlock.Info.Attributes]
292
	and	eax, [edx + FindFileBlock.Options.Attributes]
293
	jz	.loop_find_next
294
	lea	eax, [edx + FindFileBlock.Info.FileName]
295
	stdcall file.aux.match_wildcard, eax, [edx + FindFileBlock.Options.Mask]
296
	or	eax, eax
297
	jnz	.loop_find_exit
298
 
299
  .loop_find_next:
300
	inc	[edx + FindFileBlock.InfoBlock.Position]
301
	jmp	.loop_find
302
 
303
  .loop_find_error:
304
	xor	eax, eax
305
	pop	edx ebx
306
	ret
307
 
308
  .loop_find_exit:
309
	lea	eax, [edx + FindFileBlock.Info]
310
	pop	edx ebx
311
	ret
312
endp
313
 
314
;;================================================================================================;;
315
proc file.find_first _dir, _mask, _attr ;/////////////////////////////////////////////////////////;;
316
;;------------------------------------------------------------------------------------------------;;
317
;? Find first file with matching attributes and mask in specified directory                       ;;
318
;;------------------------------------------------------------------------------------------------;;
319
;> _dir = pointer to string (directory path to search in)                                         ;;
320
;> _mask = pointer to string (file mask, with use of wildcards)                                   ;;
321
;> _attr = file attributes mask (combination of FA_* constants)                                   ;;
322
;;------------------------------------------------------------------------------------------------;;
323
;< eax = 0 (error) / pointer to `FileInfo` with matched file data (acts as find descriptor)       ;;
324
;;================================================================================================;;
325
	push	ebx edx
326
 
327
	invoke	mem.alloc, sizeof.FindFileBlock
328
	or	eax, eax
329
	jz	.exit.error
330
	mov	edx, eax
331
	mov	ebx, [_attr]
332
	mov	[edx + FindFileBlock.Options.Attributes], ebx
333
	mov	ebx, [_mask]
334
	mov	[edx + FindFileBlock.Options.Mask], ebx
335
 
336
	lea	ebx, [edx + FindFileBlock.InfoBlock]
337
	mov	[ebx + FileInfoBlock.Function], F70_READ_D
338
	mov	[ebx + FileInfoBlock.Count], 1
339
	lea	eax, [edx + FindFileBlock.Header]
340
	mov	[ebx + FileInfoBlock.Buffer], eax
341
	mov	eax, [_dir]
342
	mov	[ebx + FileInfoBlock.FileName], eax
343
 
344
	stdcall file.aux.find_matching_file, edx
345
	pop	edx ebx
346
	ret
347
 
348
  .exit.error:
349
	xor	eax, eax
350
	pop	edx ebx
351
	ret
352
endp
353
 
354
;;================================================================================================;;
355
proc file.find_next _findd ;//////////////////////////////////////////////////////////////////////;;
356
;;------------------------------------------------------------------------------------------------;;
357
;? Find next file matching criteria                                                               ;;
358
;;------------------------------------------------------------------------------------------------;;
359
;> _findd = find descriptor (see `file.find_first`)                                               ;;
360
;;------------------------------------------------------------------------------------------------;;
361
;< eax = 0 (error) / pointer to `FileInfo` with matched file data (acts as find descriptor)       ;;
362
;;================================================================================================;;
363
	mov	eax, [_findd]
364
	add	eax, -sizeof.FileInfoHeader
365
	inc	[eax + FindFileBlock.InfoBlock.Position]
366
	stdcall file.aux.find_matching_file, eax
367
	ret
368
endp
369
 
370
;;================================================================================================;;
371
proc file.find_close _findd ;/////////////////////////////////////////////////////////////////////;;
372
;;------------------------------------------------------------------------------------------------;;
373
;? Close find descriptor and free memory                                                          ;;
374
;;------------------------------------------------------------------------------------------------;;
375
;> _findd = find descriptor (see `file.find_first`)                                               ;;
376
;;------------------------------------------------------------------------------------------------;;
377
;< eax = result of memory freeing routine                                                         ;;
378
;;================================================================================================;;
379
	mov	eax, [_findd]
380
	add	eax, -sizeof.FileInfoHeader
381
	invoke	mem.free, eax
382
	ret
383
endp
384
 
385
;;================================================================================================;;
386
proc file.size _name ;////////////////////////////////////////////////////////////////////////////;;
387
;;------------------------------------------------------------------------------------------------;;
388
;? Get file size                                                                                  ;;
389
;;------------------------------------------------------------------------------------------------;;
390
;> _name = path to file (full or relative)                                                        ;;
391
;;------------------------------------------------------------------------------------------------;;
392
;< eax = -1 (error) / file size (in bytes, up to 2G)                                              ;;
393
;;------------------------------------------------------------------------------------------------;;
394
;# call `file.err` to obtain extended error information                                           ;;
395
;;================================================================================================;;
396
locals
397
  loc_info FileInfoBlock
398
endl
399
 
400
	lea	ebx, [loc_info]
401
	invoke	mem.alloc, 40
402
	push	eax
403
	mov	[ebx + FileInfoBlock.Function], F70_GETATTR_FD
404
	mov	[ebx + FileInfoBlock.Buffer], eax
405
	mov	byte[ebx + FileInfoBlock.FileName - 1], 0
406
	mov	eax, [_name]
407
	mov	[ebx + FileInfoBlock.FileName], eax
408
	mcall	70
409
	pop	ebx
410
	push	eax
411
	mov	eax, ebx
412
	mov	ebx, [ebx + FileInfo.FileSizeLow]
413
	invoke	mem.free, eax
414
	pop	eax
415
	ret
416
endp
417
 
418
;;================================================================================================;;
419
proc file.open _name, _mode ;/////////////////////////////////////////////////////////////////////;;
420
;;------------------------------------------------------------------------------------------------;;
421
;? Open file                                                                                      ;;
422
;;------------------------------------------------------------------------------------------------;;
423
;> _name = path to file (full or relative)                                                        ;;
424
;> _mode = mode to open file in (combination of O_* constants)                                    ;;
425
;;------------------------------------------------------------------------------------------------;;
426
;< eax = 0 (error) / file descriptor                                                              ;;
427
;;------------------------------------------------------------------------------------------------;;
428
;# call `file.err` to obtain extended error information                                           ;;
429
;;================================================================================================;;
430
locals
431
  loc_info FileInfoBlock
432
  loc_buf  rb 40
433
endl
434
 
435
	push	ebx esi edi
436
 
437
	xor	ebx, ebx
438
	invoke	mem.alloc, sizeof.InternalFileInfo
439
	or	eax, eax
440
	jz	.exit_error
441
	mov	ebx, eax
442
	push	[_mode]
443
	pop	[ebx + InternalFileInfo.Mode]
444
	mov	[ebx + InternalFileInfo.Position], 0
445
	lea	edi, [ebx + InternalFileInfo.FileName]
446
	mov	esi, [_name]
447
	mov	ecx, 260 / 4
448
	cld
449
	rep	movsd
450
 
451
  .get_info:
452
	push	ebx
453
	mov	[loc_info.Function], F70_GETATTR_FD
454
	lea	eax, [loc_buf]
455
	mov	[loc_info.Buffer], eax
456
	mov	byte[loc_info.FileName - 1], 0
457
	mov	eax, [_name]
458
	mov	[loc_info.FileName], eax
459
	lea	ebx, [loc_info]
460
	mcall	70
461
	pop	ebx
462
	or	eax, eax
463
	jz	@f
464
	cmp	eax, 6
465
	jne	.exit_error.ex
466
    @@:
467
	mov	eax, ebx
468
	pop	edi esi ebx
469
	ret
470
 
471
  .exit_error.ex:
472
	test	[_mode], O_CREATE
473
	jz	.exit_error
474
	push	ebx
475
	mov	[loc_info.Function], F70_CREATE_F
476
	xor	eax, eax
477
	mov	[loc_info.Position], eax
478
	mov	[loc_info.Flags], eax
479
	mov	[loc_info.Count], eax
480
	lea	ebx, [loc_info]
481
	mcall	70
482
	pop	ebx
483
	or	eax, eax
484
	jz	.get_info
485
 
486
  .exit_error:
487
	invoke	mem.free, ebx
488
	xor	eax, eax
489
	pop	edi esi ebx
490
	ret
491
endp
492
 
493
;;================================================================================================;;
494
proc file.read _filed, _buf, _buflen ;////////////////////////////////////////////////////////////;;
495
;;------------------------------------------------------------------------------------------------;;
496
;? Read data from file                                                                            ;;
497
;;------------------------------------------------------------------------------------------------;;
498
;> _filed = file descriptor (see `file.open`)                                                     ;;
499
;> _buf = pointer to buffer to put read data to                                                   ;;
500
;> _buflen = buffer size (number of bytes to be read from file)                                   ;;
501
;;------------------------------------------------------------------------------------------------;;
502
;< eax = -1 (error) / number of bytes read                                                        ;;
503
;;------------------------------------------------------------------------------------------------;;
504
;# call `file.err` to obtain extended error information                                           ;;
505
;;================================================================================================;;
506
locals
507
  loc_info FileInfoBlock
508
endl
509
 
510
	push	ebx esi edi
511
 
512
	mov	ebx, [_filed]
513
	test	[ebx + InternalFileInfo.Mode], O_READ
514
	jz	.exit_error
515
 
516
	xor	eax, eax
517
	mov	[loc_info.Function], F70_READ_F
518
	mov	[loc_info.Flags], eax
519
	mov	byte[loc_info.FileName - 1], al
520
	push	[ebx+InternalFileInfo.Position] [_buflen] [_buf]
521
	pop	[loc_info.Buffer] [loc_info.Count] [loc_info.Position]
522
	lea	eax, [ebx + InternalFileInfo.FileName]
523
	mov	[loc_info.FileName], eax
524
	lea	ebx, [loc_info]
525
	mcall	70
526
	or	eax, eax
527
	jz	@f
528
	cmp	eax, 6
529
	jne	.exit_error
530
    @@:
531
	mov	eax, ebx
532
	mov	ebx, [_filed]
533
	add	[ebx + InternalFileInfo.Position], eax
534
	pop	edi esi ebx
535
	ret
536
 
537
  .exit_error:
538
	or	eax, -1
539
	pop	edi esi ebx
540
	ret
541
endp
542
 
543
;;================================================================================================;;
544
proc file.write _filed, _buf, _buflen ;///////////////////////////////////////////////////////////;;
545
;;------------------------------------------------------------------------------------------------;;
546
;? Write data to file                                                                             ;;
547
;;------------------------------------------------------------------------------------------------;;
548
;> _filed = file descriptor (see `file.open`)                                                     ;;
549
;> _buf = pointer to buffer to get write data from                                                ;;
550
;> _buflen = buffer size (number of bytes to be written to file)                                  ;;
551
;;------------------------------------------------------------------------------------------------;;
552
;< eax = -1 (error) / number of bytes written                                                     ;;
553
;;------------------------------------------------------------------------------------------------;;
554
;# call `file.err` to obtain extended error information                                           ;;
555
;;================================================================================================;;
556
locals
557
  loc_info FileInfoBlock
558
endl
559
 
560
	push	ebx esi edi
561
 
562
	mov	ebx, [_filed]
563
	test	[ebx + InternalFileInfo.Mode], O_WRITE
564
	jz	.exit_error
565
 
566
	stdcall file.eof?, [_filed]
567
	or	eax, eax
568
	js	.exit_error
569
	jz	@f
570
	stdcall file.truncate, [_filed]
571
    @@:
572
	mov	[loc_info.Function], F70_WRITE_F
573
	xor	eax, eax
574
	mov	[loc_info.Flags], eax
575
	mov	byte[loc_info.FileName - 1], al
576
	push	[ebx + InternalFileInfo.Position] [_buflen] [_buf]
577
	pop	[loc_info.Buffer] [loc_info.Count] [loc_info.Position]
578
	lea	eax, [ebx + InternalFileInfo.FileName]
579
	mov	[loc_info.FileName], eax
580
	lea	ebx, [loc_info]
581
	mcall	70
582
	or	eax, eax
583
	jnz	.exit_error
584
    @@:
585
	mov	eax, ebx
586
	mov	ebx, [_filed]
587
	add	[ebx + InternalFileInfo.Position],eax
588
	pop	edi esi ebx
589
	ret
590
 
591
  .exit_error:
592
	or	eax, -1
593
	pop	edi esi ebx
594
	ret
595
endp
596
 
597
;;================================================================================================;;
598
proc file.seek _filed, _where, _origin ;//////////////////////////////////////////////////////////;;
599
;;------------------------------------------------------------------------------------------------;;
600
;? Set file pointer position                                                                      ;;
601
;;------------------------------------------------------------------------------------------------;;
602
;> _filed = file descriptor (see `file.open`)                                                     ;;
603
;> _where = position in file (in bytes) counted from specified origin                             ;;
604
;> _origin = origin from where to set the position (one of SEEK_* constants)                      ;;
605
;>   SEEK_SET - from beginning of file                                                            ;;
606
;>   SEEK_CUR - from current pointer position                                                     ;;
607
;>   SEEK_END - from end of file                                                                  ;;
608
;;------------------------------------------------------------------------------------------------;;
609
;< eax = -1 (error) / 0                                                                           ;;
610
;;------------------------------------------------------------------------------------------------;;
611
;# call `file.err` to obtain extended error information                                           ;;
612
;;================================================================================================;;
613
	push	ebx ecx edx
614
 
615
	mov	ecx, [_filed]
616
	lea	eax, [ecx + InternalFileInfo.FileName]
617
	stdcall file.size, eax
618
	or	eax, eax
619
	jnz	.exit_error
620
	mov	edx, [_where]
621
	cmp	[_origin], SEEK_SET
622
	jne	.n_set
623
	mov	[ecx + InternalFileInfo.Position], edx
624
	jmp	.exit_ok
625
 
626
  .n_set:
627
	cmp	[_origin], SEEK_CUR
628
	jne	.n_cur
629
	add	[ecx + InternalFileInfo.Position], edx
630
	jmp	.exit_ok
631
 
632
  .n_cur:
633
	cmp	[_origin], SEEK_END
634
	jne	.exit_error
635
	neg	edx
636
	add	edx, ebx
637
	mov	[ecx + InternalFileInfo.Position], edx
638
 
639
  .exit_ok:
640
 
641
	cmp	[ecx + InternalFileInfo.Position], 0
642
	jge	@f
643
	mov	[ecx + InternalFileInfo.Position], 0
644
    @@:
645
;       cmp     ebx, [ecx+InternalFileInfo.Position]
646
;       jae     @f
647
;       mov     [ecx + InternalFileInfo.Position], ebx
648
;   @@:
649
	xor	eax, eax
650
	pop	edx ecx ebx
651
	ret
652
 
653
  .exit_error:
654
	or	eax, -1
655
	pop	edx ecx ebx
656
	ret
657
endp
658
 
659
;;================================================================================================;;
660
proc file.eof? _filed ;///////////////////////////////////////////////////////////////////////////;;
661
;;------------------------------------------------------------------------------------------------;;
662
;? Determine if file pointer is at the end of file                                                ;;
663
;;------------------------------------------------------------------------------------------------;;
664
;> _filed = file descriptor (see `file.open`)                                                     ;;
665
;;------------------------------------------------------------------------------------------------;;
666
;< eax = false / true                                                                             ;;
667
;;------------------------------------------------------------------------------------------------;;
668
;# call `file.err` to obtain extended error information                                           ;;
669
;;================================================================================================;;
670
	push	ebx ecx
671
 
672
	mov	ecx, [_filed]
673
	lea	eax, [ecx + InternalFileInfo.FileName]
674
	stdcall file.size, eax
675
	or	eax, eax
676
	jnz	.exit_error
677
 
678
	xor	eax, eax
679
	cmp	[ecx + InternalFileInfo.Position], ebx
680
	jb	@f
681
	inc	eax
682
    @@: pop	ecx ebx
683
	ret
684
 
685
  .exit_error:
686
	or	eax, -1
687
	pop	ecx ebx
688
	ret
689
endp
690
 
691
;;================================================================================================;;
692
proc file.truncate _filed ;///////////////////////////////////////////////////////////////////////;;
693
;;------------------------------------------------------------------------------------------------;;
694
;? Truncate file size to current file pointer position                                            ;;
695
;;------------------------------------------------------------------------------------------------;;
696
;> _filed = file descriptor (see `file.open`)                                                     ;;
697
;;------------------------------------------------------------------------------------------------;;
698
;< eax = -1 (error) / 0                                                                           ;;
699
;;------------------------------------------------------------------------------------------------;;
700
;# call `file.err` to obtain extended error information                                           ;;
701
;;================================================================================================;;
702
locals
703
  loc_info FileInfoBlock
704
endl
705
 
706
	push	ebx esi edi
707
 
708
	mov	ebx, [_filed]
709
	test	[ebx + InternalFileInfo.Mode], O_WRITE
710
	jz	.exit_error
711
 
712
	mov	[loc_info.Function], F70_SETSIZE_F
713
	mov	eax, [ebx + InternalFileInfo.Position]
714
	mov	[loc_info.Position], eax
715
	xor	eax, eax
716
	mov	[loc_info.Flags], eax
717
	mov	[loc_info.Count], eax
718
	mov	[loc_info.Buffer], eax
719
	mov	byte[loc_info.FileName - 1], al
720
	lea	eax, [ebx + InternalFileInfo.FileName]
721
	mov	[loc_info.FileName], eax
722
	lea	ebx, [loc_info]
723
	mcall	70
724
	cmp	eax, 2
725
	je	.exit_error
726
	cmp	eax, 8
727
	je	.exit_error
728
    @@: xor	eax, eax
729
	pop	edi esi ebx
730
	ret
731
 
732
  .exit_error:
733
	or	eax, -1
734
	pop	edi esi ebx
735
	ret
736
endp
737
 
738
file.seteof equ file.truncate
739
 
740
;;================================================================================================;;
741
proc file.tell _filed ;///////////////////////////////////////////////////////////////////////////;;
742
;;------------------------------------------------------------------------------------------------;;
743
;? Get current file pointer position                                                              ;;
744
;;------------------------------------------------------------------------------------------------;;
745
;> _filed = file descriptor (see `file.open`)                                                     ;;
746
;;------------------------------------------------------------------------------------------------;;
747
;< eax = -1 (error) / file pointer position                                                       ;;
748
;;------------------------------------------------------------------------------------------------;;
749
;# call `file.err` to obtain extended error information                                           ;;
750
;;================================================================================================;;
751
	mov	eax, [_filed]
752
	mov	eax, [eax + InternalFileInfo.Position]
753
	ret
754
endp
755
 
756
;;================================================================================================;;
757
proc file.close _filed ;//////////////////////////////////////////////////////////////////////////;;
758
;;------------------------------------------------------------------------------------------------;;
759
;? Close file                                                                                     ;;
760
;;------------------------------------------------------------------------------------------------;;
761
;> _filed = file descriptor (see `file.open`)                                                     ;;
762
;;------------------------------------------------------------------------------------------------;;
763
;< eax = -1 (error) / file pointer position                                                       ;;
764
;;------------------------------------------------------------------------------------------------;;
765
;# call `file.err` to obtain extended error information                                           ;;
766
;;================================================================================================;;
767
	mov	eax, [_filed]
768
	mov	[eax + InternalFileInfo.Mode], 0
769
	mov	[eax + InternalFileInfo.FileName], 0
770
	invoke	mem.free, eax
771
	xor	eax, eax
772
	ret
773
endp
774
 
775
 
776
;;================================================================================================;;
777
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
778
;;================================================================================================;;
779
;! Exported functions section                                                                     ;;
780
;;================================================================================================;;
781
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
782
;;================================================================================================;;
783
 
784
 
785
align 16
786
@EXPORT:
787
 
788
export					      \
789
	lib_init	, 'lib_init'	    , \
790
	0x00030003	, 'version'	    , \
791
	file.find_first , 'file.find_first' , \
792
	file.find_next	, 'file.find_next'  , \
793
	file.find_close , 'file.find_close' , \
794
	file.size	, 'file.size'	    , \
795
	file.open	, 'file.open'	    , \
796
	file.read	, 'file.read'	    , \
797
	file.write	, 'file.write'	    , \
798
	file.seek	, 'file.seek'	    , \
799
	file.tell	, 'file.tell'	    , \
800
	file.eof?	, 'file.eof?'	    , \
801
	file.seteof	, 'file.seteof'     , \
802
	file.truncate	, 'file.truncate'   , \
803
	file.close	, 'file.close'