1 /*
2 ** Copyright (c) 2001-2007 Expat maintainers.
3 **
4 ** Permission is hereby granted, free of charge, to any person obtaining
5 ** a copy of this software and associated documentation files (the
6 ** "Software"), to deal in the Software without restriction, including
7 ** without limitation the rights to use, copy, modify, merge, publish,
8 ** distribute, sublicense, and/or sell copies of the Software, and to
9 ** permit persons to whom the Software is furnished to do so, subject to
10 ** the following conditions:
11 **
12 ** The above copyright notice and this permission notice shall be included
13 ** in all copies or substantial portions of the Software.
14 **
15 ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 ** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 ** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 ** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 ** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 ** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 ** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23
24 #include <dos/dos.h>
25 #include <proto/exec.h>
26
27 #define LIBNAME "expat.library"
28 #define LIBPRI 0
29 #define VERSION 4
30 #define REVISION 2
31 #define VSTRING "expat.library 4.2 (2.6.2007)" /* dd.mm.yyyy */
32
33
34 static const char* __attribute__((used)) verstag = "\0$VER: " VSTRING;
35
36
37 struct ExpatBase {
38 struct Library libNode;
39 uint16 pad;
40 BPTR SegList;
41 };
42
43
44 struct ExpatBase * libInit(struct ExpatBase *libBase, BPTR seglist, struct ExecIFace *ISys);
45 uint32 libObtain (struct LibraryManagerInterface *Self);
46 uint32 libRelease (struct LibraryManagerInterface *Self);
47 struct ExpatBase *libOpen (struct LibraryManagerInterface *Self, uint32 version);
48 BPTR libClose (struct LibraryManagerInterface *Self);
49 BPTR libExpunge (struct LibraryManagerInterface *Self);
50
51
52 static APTR lib_manager_vectors[] = {
53 libObtain,
54 libRelease,
55 NULL,
56 NULL,
57 libOpen,
58 libClose,
59 libExpunge,
60 NULL,
61 (APTR)-1,
62 };
63
64
65 static struct TagItem lib_managerTags[] = {
66 { MIT_Name, (uint32)"__library" },
67 { MIT_VectorTable, (uint32)lib_manager_vectors },
68 { MIT_Version, 1 },
69 { TAG_END, 0 }
70 };
71
72
73 extern void *main_vectors[];
74
75 static struct TagItem lib_mainTags[] = {
76 { MIT_Name, (uint32)"main" },
77 { MIT_VectorTable, (uint32)main_vectors },
78 { MIT_Version, 1 },
79 { TAG_END, 0 }
80 };
81
82
83 static APTR libInterfaces[] = {
84 lib_managerTags,
85 lib_mainTags,
86 NULL
87 };
88
89
90 static struct TagItem libCreateTags[] = {
91 { CLT_DataSize, sizeof(struct ExpatBase) },
92 { CLT_InitFunc, (uint32)libInit },
93 { CLT_Interfaces, (uint32)libInterfaces },
94 { TAG_END, 0 }
95 };
96
97
98 static struct Resident __attribute__((used)) lib_res = {
99 RTC_MATCHWORD, // rt_MatchWord
100 &lib_res, // rt_MatchTag
101 &lib_res+1, // rt_EndSkip
102 RTF_NATIVE | RTF_AUTOINIT, // rt_Flags
103 VERSION, // rt_Version
104 NT_LIBRARY, // rt_Type
105 LIBPRI, // rt_Pri
106 LIBNAME, // rt_Name
107 VSTRING, // rt_IdString
108 libCreateTags // rt_Init
109 };
110
111
112 struct Library *DOSLib = 0;
113 struct Library *UtilityBase = 0;
114
115 struct ExecIFace *IExec = 0;
116 struct DOSIFace *IDOS = 0;
117 struct UtilityIFace *IUtility = 0;
118
119
_start()120 void _start()
121 {
122 }
123
124
libInit(struct ExpatBase * libBase,BPTR seglist,struct ExecIFace * ISys)125 struct ExpatBase *libInit(struct ExpatBase *libBase, BPTR seglist, struct ExecIFace *ISys)
126 {
127 libBase->libNode.lib_Node.ln_Type = NT_LIBRARY;
128 libBase->libNode.lib_Node.ln_Pri = LIBPRI;
129 libBase->libNode.lib_Node.ln_Name = LIBNAME;
130 libBase->libNode.lib_Flags = LIBF_SUMUSED|LIBF_CHANGED;
131 libBase->libNode.lib_Version = VERSION;
132 libBase->libNode.lib_Revision = REVISION;
133 libBase->libNode.lib_IdString = VSTRING;
134 libBase->SegList = seglist;
135
136 IExec = ISys;
137
138 DOSLib = OpenLibrary("dos.library", 51);
139 if ( DOSLib != 0 ) {
140 IDOS = (struct DOSIFace *)GetInterface(DOSLib, "main", 1, NULL);
141 if ( IDOS != 0 ) {
142 UtilityBase = OpenLibrary("utility.library", 51);
143 if ( UtilityBase != 0 ) {
144 IUtility = (struct UtilityIFace*)GetInterface(UtilityBase, "main", 1, NULL);
145 if ( IUtility != 0 ) {
146 return libBase;
147 }
148
149 CloseLibrary(UtilityBase);
150 }
151
152 DropInterface((struct Interface *)IDOS);
153 }
154
155 CloseLibrary(DOSLib);
156 }
157
158 return NULL;
159 }
160
161
libObtain(struct LibraryManagerInterface * Self)162 uint32 libObtain( struct LibraryManagerInterface *Self )
163 {
164 ++Self->Data.RefCount;
165 return Self->Data.RefCount;
166 }
167
168
libRelease(struct LibraryManagerInterface * Self)169 uint32 libRelease( struct LibraryManagerInterface *Self )
170 {
171 --Self->Data.RefCount;
172 return Self->Data.RefCount;
173 }
174
175
libOpen(struct LibraryManagerInterface * Self,uint32 version)176 struct ExpatBase *libOpen( struct LibraryManagerInterface *Self, uint32 version )
177 {
178 struct ExpatBase *libBase;
179
180 libBase = (struct ExpatBase *)Self->Data.LibBase;
181
182 ++libBase->libNode.lib_OpenCnt;
183 libBase->libNode.lib_Flags &= ~LIBF_DELEXP;
184
185 return libBase;
186 }
187
188
libClose(struct LibraryManagerInterface * Self)189 BPTR libClose( struct LibraryManagerInterface *Self )
190 {
191 struct ExpatBase *libBase;
192
193 libBase = (struct ExpatBase *)Self->Data.LibBase;
194
195 --libBase->libNode.lib_OpenCnt;
196 if ( libBase->libNode.lib_OpenCnt ) {
197 return 0;
198 }
199
200 if ( libBase->libNode.lib_Flags & LIBF_DELEXP ) {
201 return (BPTR)Self->LibExpunge();
202 }
203 else {
204 return 0;
205 }
206 }
207
208
libExpunge(struct LibraryManagerInterface * Self)209 BPTR libExpunge( struct LibraryManagerInterface *Self )
210 {
211 struct ExpatBase *libBase;
212 BPTR result = 0;
213
214 libBase = (struct ExpatBase *)Self->Data.LibBase;
215
216 if (libBase->libNode.lib_OpenCnt == 0) {
217 Remove(&libBase->libNode.lib_Node);
218
219 result = libBase->SegList;
220
221 DropInterface((struct Interface *)IUtility);
222 CloseLibrary(UtilityBase);
223 DropInterface((struct Interface *)IDOS);
224 CloseLibrary(DOSLib);
225
226 DeleteLibrary(&libBase->libNode);
227 }
228 else {
229 libBase->libNode.lib_Flags |= LIBF_DELEXP;
230 }
231
232 return result;
233 }
234