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 120 void _start() 121 { 122 } 123 124 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 162 uint32 libObtain( struct LibraryManagerInterface *Self ) 163 { 164 ++Self->Data.RefCount; 165 return Self->Data.RefCount; 166 } 167 168 169 uint32 libRelease( struct LibraryManagerInterface *Self ) 170 { 171 --Self->Data.RefCount; 172 return Self->Data.RefCount; 173 } 174 175 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 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 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