Subversion Repositories Kolibri OS

Rev

Rev 717 | Rev 1001 | Go to most recent revision | Details | Compare with Previous | 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
;;                                                                                                ;;
845 mikedld 20
;; 2008-08-06 (mike.dld)                                                                          ;;
21
;;   changes:                                                                                     ;;
22
;;     - split private procs into libio_p.asm, added comments                                     ;;
717 mikedld 23
;; 2007-12-10 (mike.dld)                                                                          ;;
24
;;   changes:                                                                                     ;;
25
;;     - almost fully incompatible with previous version since return values were changed.        ;;
26
;;       now they are more C-like                                                                 ;;
27
;;   notes:                                                                                       ;;
28
;;     - `file.err` is not yet available                                                          ;;
29
;; 2007-09-26 (mike.dld)                                                                          ;;
30
;;   changes:                                                                                     ;;
31
;;     - modified `file.size` a bit (according to changes in FileInfo struct)                     ;;
32
;;     - added `file.find_first`, `file.find_next`, `file.find_close`                             ;;
33
;;   notes:                                                                                       ;;
34
;;     - `file.aux.match_wildcard` is exported only for testing purposes, don't                   ;;
35
;;       use it since it may be removed or renamed in next versions                               ;;
36
;;                                                                                                ;;
37
;;================================================================================================;;
38
 
39
 
40
format MS COFF
41
 
42
public @EXPORT as 'EXPORTS'
43
 
44
include '../../../../proc32.inc'
45
include '../../../../macros.inc'
46
purge section;mov,add,sub
47
 
48
include 'libio.inc'
49
include 'libio_p.inc'
50
 
51
section '.flat' code readable align 16
52
 
845 mikedld 53
include 'libio_p.asm'
717 mikedld 54
 
55
;;================================================================================================;;
56
proc file.find_first _dir, _mask, _attr ;/////////////////////////////////////////////////////////;;
57
;;------------------------------------------------------------------------------------------------;;
58
;? Find first file with matching attributes and mask in specified directory                       ;;
59
;;------------------------------------------------------------------------------------------------;;
845 mikedld 60
;> _dir = directory path to search in                                                     ;;
61
;> _mask = file mask, with use of wildcards                                               ;;
62
;> _attr = file attributes mask (combination of FA_* constants)                            ;;
717 mikedld 63
;;------------------------------------------------------------------------------------------------;;
845 mikedld 64
;< eax = 0 (error) / matched file data pointer (acts as find descriptor)               ;;
717 mikedld 65
;;================================================================================================;;
66
	push	ebx edx
67
 
68
	invoke	mem.alloc, sizeof.FindFileBlock
69
	or	eax, eax
70
	jz	.exit.error
71
	mov	edx, eax
72
	mov	ebx, [_attr]
73
	mov	[edx + FindFileBlock.Options.Attributes], ebx
74
	mov	ebx, [_mask]
75
	mov	[edx + FindFileBlock.Options.Mask], ebx
76
 
77
	lea	ebx, [edx + FindFileBlock.InfoBlock]
78
	mov	[ebx + FileInfoBlock.Function], F70_READ_D
79
	mov	[ebx + FileInfoBlock.Count], 1
80
	lea	eax, [edx + FindFileBlock.Header]
81
	mov	[ebx + FileInfoBlock.Buffer], eax
82
	mov	eax, [_dir]
83
	mov	[ebx + FileInfoBlock.FileName], eax
84
 
845 mikedld 85
	stdcall libio._.find_matching_file, edx
717 mikedld 86
	pop	edx ebx
87
	ret
88
 
89
  .exit.error:
90
	xor	eax, eax
91
	pop	edx ebx
92
	ret
93
endp
94
 
95
;;================================================================================================;;
96
proc file.find_next _findd ;//////////////////////////////////////////////////////////////////////;;
97
;;------------------------------------------------------------------------------------------------;;
98
;? Find next file matching criteria                                                               ;;
99
;;------------------------------------------------------------------------------------------------;;
845 mikedld 100
;> _findd = find descriptor (see `file.find_first`)                                    ;;
717 mikedld 101
;;------------------------------------------------------------------------------------------------;;
845 mikedld 102
;< eax = 0 (error) / matched file data pointer (acts as find descriptor)               ;;
717 mikedld 103
;;================================================================================================;;
104
	mov	eax, [_findd]
105
	add	eax, -sizeof.FileInfoHeader
106
	inc	[eax + FindFileBlock.InfoBlock.Position]
845 mikedld 107
	stdcall libio._.find_matching_file, eax
717 mikedld 108
	ret
109
endp
110
 
111
;;================================================================================================;;
112
proc file.find_close _findd ;/////////////////////////////////////////////////////////////////////;;
113
;;------------------------------------------------------------------------------------------------;;
114
;? Close find descriptor and free memory                                                          ;;
115
;;------------------------------------------------------------------------------------------------;;
845 mikedld 116
;> _findd = find descriptor (see `file.find_first`)                                    ;;
717 mikedld 117
;;------------------------------------------------------------------------------------------------;;
118
;< eax = result of memory freeing routine                                                         ;;
119
;;================================================================================================;;
120
	mov	eax, [_findd]
121
	add	eax, -sizeof.FileInfoHeader
122
	invoke	mem.free, eax
123
	ret
124
endp
125
 
126
;;================================================================================================;;
127
proc file.size _name ;////////////////////////////////////////////////////////////////////////////;;
128
;;------------------------------------------------------------------------------------------------;;
129
;? Get file size                                                                                  ;;
130
;;------------------------------------------------------------------------------------------------;;
845 mikedld 131
;> _name = path to file (full or relative)                                                ;;
717 mikedld 132
;;------------------------------------------------------------------------------------------------;;
845 mikedld 133
;< eax = -1 (error) / file size (in bytes, up to 2G)                                       ;;
717 mikedld 134
;;------------------------------------------------------------------------------------------------;;
135
;# call `file.err` to obtain extended error information                                           ;;
136
;;================================================================================================;;
137
locals
138
  loc_info FileInfoBlock
139
endl
140
 
141
	lea	ebx, [loc_info]
142
	invoke	mem.alloc, 40
143
	push	eax
144
	mov	[ebx + FileInfoBlock.Function], F70_GETATTR_FD
145
	mov	[ebx + FileInfoBlock.Buffer], eax
146
	mov	byte[ebx + FileInfoBlock.FileName - 1], 0
147
	mov	eax, [_name]
148
	mov	[ebx + FileInfoBlock.FileName], eax
149
	mcall	70
150
	pop	ebx
151
	push	eax
152
	mov	eax, ebx
153
	mov	ebx, [ebx + FileInfo.FileSizeLow]
154
	invoke	mem.free, eax
155
	pop	eax
156
	ret
157
endp
158
 
159
;;================================================================================================;;
160
proc file.open _name, _mode ;/////////////////////////////////////////////////////////////////////;;
161
;;------------------------------------------------------------------------------------------------;;
162
;? Open file                                                                                      ;;
163
;;------------------------------------------------------------------------------------------------;;
845 mikedld 164
;> _name = path to file (full or relative)                                                ;;
165
;> _mode = mode to open file in (combination of O_* constants)                             ;;
166
;>   O_BINARY - don't change read/written data in any way (default)                               ;;
167
;>   O_READ - open file for reading                                                               ;;
168
;>   O_WRITE - open file for writing                                                              ;;
169
;>   O_CREATE - create file if it doesn't exist, open otherwise                                   ;;
170
;>   O_SHARE - allow simultaneous access by using different file descriptors (not implemented)    ;;
171
;>   O_TEXT - replace newline chars with LF (overrides O_BINARY, not implemented)                 ;;
717 mikedld 172
;;------------------------------------------------------------------------------------------------;;
845 mikedld 173
;< eax = 0 (error) / file descriptor                                           ;;
717 mikedld 174
;;------------------------------------------------------------------------------------------------;;
175
;# call `file.err` to obtain extended error information                                           ;;
176
;;================================================================================================;;
177
locals
178
  loc_info FileInfoBlock
179
  loc_buf  rb 40
180
endl
181
 
182
	push	ebx esi edi
183
 
184
	xor	ebx, ebx
185
	invoke	mem.alloc, sizeof.InternalFileInfo
186
	or	eax, eax
187
	jz	.exit_error
188
	mov	ebx, eax
189
	push	[_mode]
190
	pop	[ebx + InternalFileInfo.Mode]
191
	mov	[ebx + InternalFileInfo.Position], 0
192
	lea	edi, [ebx + InternalFileInfo.FileName]
193
	mov	esi, [_name]
194
	mov	ecx, 260 / 4
195
	cld
196
	rep	movsd
197
 
198
  .get_info:
199
	push	ebx
200
	mov	[loc_info.Function], F70_GETATTR_FD
201
	lea	eax, [loc_buf]
202
	mov	[loc_info.Buffer], eax
203
	mov	byte[loc_info.FileName - 1], 0
204
	mov	eax, [_name]
205
	mov	[loc_info.FileName], eax
206
	lea	ebx, [loc_info]
207
	mcall	70
208
	pop	ebx
209
	or	eax, eax
210
	jz	@f
211
	cmp	eax, 6
212
	jne	.exit_error.ex
213
    @@:
214
	mov	eax, ebx
215
	pop	edi esi ebx
216
	ret
217
 
218
  .exit_error.ex:
219
	test	[_mode], O_CREATE
220
	jz	.exit_error
221
	push	ebx
222
	mov	[loc_info.Function], F70_CREATE_F
223
	xor	eax, eax
224
	mov	[loc_info.Position], eax
225
	mov	[loc_info.Flags], eax
226
	mov	[loc_info.Count], eax
227
	lea	ebx, [loc_info]
228
	mcall	70
229
	pop	ebx
230
	or	eax, eax
231
	jz	.get_info
232
 
233
  .exit_error:
234
	invoke	mem.free, ebx
235
	xor	eax, eax
236
	pop	edi esi ebx
237
	ret
238
endp
239
 
240
;;================================================================================================;;
241
proc file.read _filed, _buf, _buflen ;////////////////////////////////////////////////////////////;;
242
;;------------------------------------------------------------------------------------------------;;
243
;? Read data from file                                                                            ;;
244
;;------------------------------------------------------------------------------------------------;;
845 mikedld 245
;> _filed = file descriptor (see `file.open`)                                  ;;
246
;> _buf = buffer to put read data to                                                       ;;
247
;> _buflen = buffer size (number of bytes to be read from file)                            ;;
717 mikedld 248
;;------------------------------------------------------------------------------------------------;;
845 mikedld 249
;< eax = -1 (error) / number of bytes read                                                 ;;
717 mikedld 250
;;------------------------------------------------------------------------------------------------;;
251
;# call `file.err` to obtain extended error information                                           ;;
252
;;================================================================================================;;
253
locals
254
  loc_info FileInfoBlock
255
endl
256
 
257
	push	ebx esi edi
258
 
259
	mov	ebx, [_filed]
260
	test	[ebx + InternalFileInfo.Mode], O_READ
261
	jz	.exit_error
262
 
263
	xor	eax, eax
264
	mov	[loc_info.Function], F70_READ_F
265
	mov	[loc_info.Flags], eax
266
	mov	byte[loc_info.FileName - 1], al
267
	push	[ebx+InternalFileInfo.Position] [_buflen] [_buf]
268
	pop	[loc_info.Buffer] [loc_info.Count] [loc_info.Position]
269
	lea	eax, [ebx + InternalFileInfo.FileName]
270
	mov	[loc_info.FileName], eax
271
	lea	ebx, [loc_info]
272
	mcall	70
273
	or	eax, eax
274
	jz	@f
275
	cmp	eax, 6
276
	jne	.exit_error
277
    @@:
278
	mov	eax, ebx
279
	mov	ebx, [_filed]
280
	add	[ebx + InternalFileInfo.Position], eax
281
	pop	edi esi ebx
282
	ret
283
 
284
  .exit_error:
285
	or	eax, -1
286
	pop	edi esi ebx
287
	ret
288
endp
289
 
290
;;================================================================================================;;
291
proc file.write _filed, _buf, _buflen ;///////////////////////////////////////////////////////////;;
292
;;------------------------------------------------------------------------------------------------;;
293
;? Write data to file                                                                             ;;
294
;;------------------------------------------------------------------------------------------------;;
845 mikedld 295
;> _filed = file descriptor (see `file.open`)                                  ;;
296
;> _buf = buffer to get write data from                                                    ;;
297
;> _buflen = buffer size (number of bytes to be written to file)                           ;;
717 mikedld 298
;;------------------------------------------------------------------------------------------------;;
845 mikedld 299
;< eax = -1 (error) / number of bytes written                                              ;;
717 mikedld 300
;;------------------------------------------------------------------------------------------------;;
301
;# call `file.err` to obtain extended error information                                           ;;
302
;;================================================================================================;;
303
locals
304
  loc_info FileInfoBlock
305
endl
306
 
307
	push	ebx esi edi
308
 
309
	mov	ebx, [_filed]
310
	test	[ebx + InternalFileInfo.Mode], O_WRITE
311
	jz	.exit_error
312
 
313
	stdcall file.eof?, [_filed]
314
	or	eax, eax
315
	js	.exit_error
316
	jz	@f
317
	stdcall file.truncate, [_filed]
318
    @@:
319
	mov	[loc_info.Function], F70_WRITE_F
320
	xor	eax, eax
321
	mov	[loc_info.Flags], eax
322
	mov	byte[loc_info.FileName - 1], al
323
	push	[ebx + InternalFileInfo.Position] [_buflen] [_buf]
324
	pop	[loc_info.Buffer] [loc_info.Count] [loc_info.Position]
325
	lea	eax, [ebx + InternalFileInfo.FileName]
326
	mov	[loc_info.FileName], eax
327
	lea	ebx, [loc_info]
328
	mcall	70
329
	or	eax, eax
330
	jnz	.exit_error
331
    @@:
332
	mov	eax, ebx
333
	mov	ebx, [_filed]
334
	add	[ebx + InternalFileInfo.Position],eax
335
	pop	edi esi ebx
336
	ret
337
 
338
  .exit_error:
339
	or	eax, -1
340
	pop	edi esi ebx
341
	ret
342
endp
343
 
344
;;================================================================================================;;
345
proc file.seek _filed, _where, _origin ;//////////////////////////////////////////////////////////;;
346
;;------------------------------------------------------------------------------------------------;;
347
;? Set file pointer position                                                                      ;;
348
;;------------------------------------------------------------------------------------------------;;
845 mikedld 349
;> _filed = file descriptor (see `file.open`)                                  ;;
350
;> _where = position in file (in bytes) counted from specified origin                      ;;
351
;> _origin = origin from where to set the position (one of SEEK_* constants)               ;;
717 mikedld 352
;>   SEEK_SET - from beginning of file                                                            ;;
353
;>   SEEK_CUR - from current pointer position                                                     ;;
354
;>   SEEK_END - from end of file                                                                  ;;
355
;;------------------------------------------------------------------------------------------------;;
845 mikedld 356
;< eax = -1 (error) / 0                                                                    ;;
717 mikedld 357
;;------------------------------------------------------------------------------------------------;;
358
;# call `file.err` to obtain extended error information                                           ;;
359
;;================================================================================================;;
360
	push	ebx ecx edx
361
 
362
	mov	ecx, [_filed]
363
	lea	eax, [ecx + InternalFileInfo.FileName]
364
	stdcall file.size, eax
365
	or	eax, eax
366
	jnz	.exit_error
367
	mov	edx, [_where]
368
	cmp	[_origin], SEEK_SET
369
	jne	.n_set
370
	mov	[ecx + InternalFileInfo.Position], edx
371
	jmp	.exit_ok
372
 
373
  .n_set:
374
	cmp	[_origin], SEEK_CUR
375
	jne	.n_cur
376
	add	[ecx + InternalFileInfo.Position], edx
377
	jmp	.exit_ok
378
 
379
  .n_cur:
380
	cmp	[_origin], SEEK_END
381
	jne	.exit_error
382
	neg	edx
383
	add	edx, ebx
384
	mov	[ecx + InternalFileInfo.Position], edx
385
 
386
  .exit_ok:
387
 
388
	cmp	[ecx + InternalFileInfo.Position], 0
389
	jge	@f
390
	mov	[ecx + InternalFileInfo.Position], 0
391
    @@:
392
;       cmp     ebx, [ecx+InternalFileInfo.Position]
393
;       jae     @f
394
;       mov     [ecx + InternalFileInfo.Position], ebx
395
;   @@:
396
	xor	eax, eax
397
	pop	edx ecx ebx
398
	ret
399
 
400
  .exit_error:
401
	or	eax, -1
402
	pop	edx ecx ebx
403
	ret
404
endp
405
 
406
;;================================================================================================;;
407
proc file.eof? _filed ;///////////////////////////////////////////////////////////////////////////;;
408
;;------------------------------------------------------------------------------------------------;;
409
;? Determine if file pointer is at the end of file                                                ;;
410
;;------------------------------------------------------------------------------------------------;;
845 mikedld 411
;> _filed = file descriptor (see `file.open`)                                  ;;
717 mikedld 412
;;------------------------------------------------------------------------------------------------;;
845 mikedld 413
;< eax = false / true                                                                      ;;
717 mikedld 414
;;------------------------------------------------------------------------------------------------;;
415
;# call `file.err` to obtain extended error information                                           ;;
416
;;================================================================================================;;
417
	push	ebx ecx
418
 
419
	mov	ecx, [_filed]
420
	lea	eax, [ecx + InternalFileInfo.FileName]
421
	stdcall file.size, eax
422
	or	eax, eax
423
	jnz	.exit_error
424
 
425
	xor	eax, eax
426
	cmp	[ecx + InternalFileInfo.Position], ebx
427
	jb	@f
428
	inc	eax
429
    @@: pop	ecx ebx
430
	ret
431
 
432
  .exit_error:
433
	or	eax, -1
434
	pop	ecx ebx
435
	ret
436
endp
437
 
438
;;================================================================================================;;
439
proc file.truncate _filed ;///////////////////////////////////////////////////////////////////////;;
440
;;------------------------------------------------------------------------------------------------;;
441
;? Truncate file size to current file pointer position                                            ;;
442
;;------------------------------------------------------------------------------------------------;;
845 mikedld 443
;> _filed = file descriptor (see `file.open`)                                  ;;
717 mikedld 444
;;------------------------------------------------------------------------------------------------;;
845 mikedld 445
;< eax = -1 (error) / 0                                                                    ;;
717 mikedld 446
;;------------------------------------------------------------------------------------------------;;
447
;# call `file.err` to obtain extended error information                                           ;;
448
;;================================================================================================;;
449
locals
450
  loc_info FileInfoBlock
451
endl
452
 
453
	push	ebx esi edi
454
 
455
	mov	ebx, [_filed]
456
	test	[ebx + InternalFileInfo.Mode], O_WRITE
457
	jz	.exit_error
458
 
459
	mov	[loc_info.Function], F70_SETSIZE_F
460
	mov	eax, [ebx + InternalFileInfo.Position]
461
	mov	[loc_info.Position], eax
462
	xor	eax, eax
463
	mov	[loc_info.Flags], eax
464
	mov	[loc_info.Count], eax
465
	mov	[loc_info.Buffer], eax
466
	mov	byte[loc_info.FileName - 1], al
467
	lea	eax, [ebx + InternalFileInfo.FileName]
468
	mov	[loc_info.FileName], eax
469
	lea	ebx, [loc_info]
470
	mcall	70
471
	cmp	eax, 2
472
	je	.exit_error
473
	cmp	eax, 8
474
	je	.exit_error
475
    @@: xor	eax, eax
476
	pop	edi esi ebx
477
	ret
478
 
479
  .exit_error:
480
	or	eax, -1
481
	pop	edi esi ebx
482
	ret
483
endp
484
 
485
file.seteof equ file.truncate
486
 
487
;;================================================================================================;;
488
proc file.tell _filed ;///////////////////////////////////////////////////////////////////////////;;
489
;;------------------------------------------------------------------------------------------------;;
490
;? Get current file pointer position                                                              ;;
491
;;------------------------------------------------------------------------------------------------;;
845 mikedld 492
;> _filed = file descriptor (see `file.open`)                                  ;;
717 mikedld 493
;;------------------------------------------------------------------------------------------------;;
845 mikedld 494
;< eax = -1 (error) / file pointer position                                                ;;
717 mikedld 495
;;------------------------------------------------------------------------------------------------;;
496
;# call `file.err` to obtain extended error information                                           ;;
497
;;================================================================================================;;
498
	mov	eax, [_filed]
499
	mov	eax, [eax + InternalFileInfo.Position]
500
	ret
501
endp
502
 
503
;;================================================================================================;;
504
proc file.close _filed ;//////////////////////////////////////////////////////////////////////////;;
505
;;------------------------------------------------------------------------------------------------;;
506
;? Close file                                                                                     ;;
507
;;------------------------------------------------------------------------------------------------;;
845 mikedld 508
;> _filed = file descriptor (see `file.open`)                                  ;;
717 mikedld 509
;;------------------------------------------------------------------------------------------------;;
845 mikedld 510
;< eax = -1 (error) / file pointer position                                                ;;
717 mikedld 511
;;------------------------------------------------------------------------------------------------;;
512
;# call `file.err` to obtain extended error information                                           ;;
513
;;================================================================================================;;
514
	mov	eax, [_filed]
515
	mov	[eax + InternalFileInfo.Mode], 0
516
	mov	[eax + InternalFileInfo.FileName], 0
517
	invoke	mem.free, eax
518
	xor	eax, eax
519
	ret
520
endp
521
 
522
 
523
;;================================================================================================;;
524
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
525
;;================================================================================================;;
526
;! Exported functions section                                                                     ;;
527
;;================================================================================================;;
528
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
529
;;================================================================================================;;
530
 
531
 
532
align 16
533
@EXPORT:
534
 
535
export					      \
845 mikedld 536
	libio._.init	, 'lib_init'	    , \
717 mikedld 537
	0x00030003	, 'version'	    , \
538
	file.find_first , 'file.find_first' , \
539
	file.find_next	, 'file.find_next'  , \
540
	file.find_close , 'file.find_close' , \
541
	file.size	, 'file.size'	    , \
542
	file.open	, 'file.open'	    , \
543
	file.read	, 'file.read'	    , \
544
	file.write	, 'file.write'	    , \
545
	file.seek	, 'file.seek'	    , \
546
	file.tell	, 'file.tell'	    , \
547
	file.eof?	, 'file.eof?'	    , \
548
	file.seteof	, 'file.seteof'     , \
549
	file.truncate	, 'file.truncate'   , \
550
	file.close	, 'file.close'