dos.library: Reverted 49008, mixing buffered and unbuffered reads causes wrong data...
[AROS.git] / rom / dos / internalloadseg.c
blob36380ae4eea53bf6a96945c7aa045c72d9bf11b9
1 /*
2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: DOS function InternalLoadSeg()
6 Lang: english
7 */
9 #include <dos/dos.h>
10 #include <dos/dosextens.h>
11 #include <proto/dos.h>
12 #include <aros/debug.h>
13 #include "dos_intern.h"
14 #include "internalloadseg.h"
16 /*****************************************************************************
18 NAME */
19 #include <proto/dos.h>
21 AROS_LH4(BPTR, InternalLoadSeg,
23 /* SYNOPSIS */
24 AROS_LHA(BPTR , fh , D0),
25 AROS_LHA(BPTR , table , A0),
26 AROS_LHA(LONG_FUNC *, funcarray , A1),
27 AROS_LHA(LONG * , stack , A2),
29 /* LOCATION */
30 struct DosLibrary *, DOSBase, 126, Dos)
32 /* FUNCTION
33 Loads from fh.
34 Functionarray is a pointer to an array of functions. See below.
36 This function really only tries to load the different file
37 formats aos, elf and aout.
39 INPUTS
40 fh : Filehandle to load from
41 table : ignored
42 funcarray : array of functions to be used for read, seek, alloc and free
43 FuncTable[0] -> bytes = ReadFunc(readhandle, buffer, length), DOSBase
44 D0 D1 A0 D0 A6
45 FuncTable[1] -> Memory = AllocFunc(size,flags), ExecBase
46 D0 D0 D1 A6
47 FuncTable[2] -> FreeFunc(memory, size), ExecBase
48 A1 D0 A6
49 FuncTable[3] -> pos = SeekFunc(readhandle, pos, mode), DOSBase
50 D0 D0 D1 D2
51 stack : pointer to storage (LONG) for stacksize.
52 (currently ignored)
54 RESULT
55 seglist - pointer to loaded Seglist or NULL in case of failure.
57 NOTES
58 FuncTable[3] is not used for Amiga HUNK format files, but is required
59 for ELF.
61 EXAMPLE
63 BUGS
64 Use of table and stack are not implemented, yet!
66 SEE ALSO
67 UnLoadSeg()
69 INTERNALS
71 *****************************************************************************/
73 AROS_LIBFUNC_INIT
75 typedef struct _segfunc_t
77 ULONG id;
78 BPTR (*func)(BPTR, BPTR, SIPTR *, LONG *, struct DosLibrary *);
79 D(CONST_STRPTR format;)
80 } segfunc_t;
82 #define SEGFUNC(id, format) {id, InternalLoadSeg_##format D(, (STRPTR)#format)}
84 static const segfunc_t funcs[] =
86 SEGFUNC(0x7f454c46, ELF),
87 SEGFUNC(0x000003f3, AOS)
90 BPTR segs = 0;
92 if (fh)
94 UBYTE i;
95 const UBYTE num_funcs = sizeof(funcs) / sizeof(funcs[0]);
96 ULONG id;
97 LONG len;
99 len = ilsRead(fh, &id, sizeof(id));
100 if (len == sizeof(id)) {
101 id = AROS_BE2LONG(id);
102 for (i = 0; i < num_funcs; i++) {
103 if (funcs[i].id == id) {
104 segs = (*funcs[i].func)(fh, BNULL, (SIPTR *)funcarray,
105 stack, DOSBase);
106 D(bug("[InternalLoadSeg] %s loading %p as an %s object.\n",
107 segs ? "Succeeded" : "FAILED", fh, funcs[i].format));
108 return segs;
114 /* This routine can be called from partition.library, when
115 * DOSBase is NULL, from HDToolbox, on m68k, when adding
116 * a new device to HDToolbox.
118 * Luckily, we're not trying to read ELF, which has a
119 * mess of SetIoErr() calls in it.
121 if (DOSBase != NULL)
122 SetIoErr(ERROR_NOT_EXECUTABLE);
124 return BNULL;
126 AROS_LIBFUNC_EXIT
127 } /* InternalLoadSeg */
129 int read_block(BPTR file, APTR buffer, ULONG size, SIPTR * funcarray, struct DosLibrary * DOSBase)
131 LONG subsize;
132 UBYTE *buf=(UBYTE *)buffer;
134 while(size)
136 subsize = ilsRead(file, buf, size);
137 if(subsize==0)
139 if (DOSBase) {
140 struct Process *me = (struct Process *)FindTask(NULL);
141 ASSERT_VALID_PROCESS(me);
142 me->pr_Result2=ERROR_BAD_HUNK;
144 return 1;
147 if(subsize<0)
148 return 1;
149 buf +=subsize;
150 size -=subsize;
152 return 0;
155 APTR _ilsAllocVec(SIPTR *funcarray, ULONG size, ULONG req)
157 UBYTE *p = ilsAllocMem(size, req);
159 D(bug("allocmem %p %d\n", p, size));
160 if (!p)
161 return NULL;
163 /* Note that the result is ULONG-aligned even on 64 bits! */
164 *((ULONG*)p) = (ULONG)size;
165 return p + sizeof(ULONG);
168 void _ilsFreeVec(SIPTR *funcarray, void *buf)
170 UBYTE *p = (UBYTE*)buf;
171 ULONG size;
172 if (!buf)
173 return;
174 p -= sizeof(ULONG);
175 size = ((ULONG*)p)[0];
176 D(bug("freemem %p %d\n", p, size));
177 if (!size)
178 return;
180 ilsFreeMem(p, size);