Subversion Repositories Kolibri OS

Rev

Rev 1102 | Rev 1574 | 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 ;;
1001 diamond 8
;; Lesser General Public License as published by the Free Software Foundation, either version 2.1 ;;
9
;; of the License, or (at your option) any later version.                                         ;;
717 mikedld 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  ;;
1001 diamond 13
;; Lesser General Public License for more details.                                                ;;
717 mikedld 14
;;                                                                                                ;;
1001 diamond 15
;; You should have received a copy of the GNU Lesser General Public License along with Libs-Dev.  ;;
16
;; If not, see .                                                    ;;
717 mikedld 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
 
1573 IgorA 182
	push	ebx ecx esi edi
717 mikedld 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
1573 IgorA 215
	pop	edi esi ecx ebx
717 mikedld 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
1573 IgorA 236
	pop	edi esi ecx ebx
717 mikedld 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'	    , \
1102 diamond 537
	0x00040004	, '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_iseof'	    , \
548
	file.seteof	, 'file_seteof'     , \
549
	file.truncate	, 'file_truncate'   , \
550
	file.close	, 'file_close'