• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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