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 34static const char* __attribute__((used)) verstag = "\0$VER: " VSTRING; 35 36 37struct ExpatBase { 38 struct Library libNode; 39 uint16 pad; 40 BPTR SegList; 41}; 42 43 44struct ExpatBase * libInit(struct ExpatBase *libBase, BPTR seglist, struct ExecIFace *ISys); 45uint32 libObtain (struct LibraryManagerInterface *Self); 46uint32 libRelease (struct LibraryManagerInterface *Self); 47struct ExpatBase *libOpen (struct LibraryManagerInterface *Self, uint32 version); 48BPTR libClose (struct LibraryManagerInterface *Self); 49BPTR libExpunge (struct LibraryManagerInterface *Self); 50 51 52static 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 65static 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 73extern void *main_vectors[]; 74 75static 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 83static APTR libInterfaces[] = { 84 lib_managerTags, 85 lib_mainTags, 86 NULL 87}; 88 89 90static 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 98static 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 112struct Library *DOSLib = 0; 113struct Library *UtilityBase = 0; 114 115struct ExecIFace *IExec = 0; 116struct DOSIFace *IDOS = 0; 117struct UtilityIFace *IUtility = 0; 118 119 120void _start() 121{ 122} 123 124 125struct 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 162uint32 libObtain( struct LibraryManagerInterface *Self ) 163{ 164 ++Self->Data.RefCount; 165 return Self->Data.RefCount; 166} 167 168 169uint32 libRelease( struct LibraryManagerInterface *Self ) 170{ 171 --Self->Data.RefCount; 172 return Self->Data.RefCount; 173} 174 175 176struct 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 189BPTR 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 209BPTR 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