diff options
author | Ash Wolf <ninji@wuffs.org> | 2022-10-11 18:54:59 +0100 |
---|---|---|
committer | Ash Wolf <ninji@wuffs.org> | 2022-10-11 18:54:59 +0100 |
commit | 4c9d73d7243c82ca3f55d2d8a388328968303b3f (patch) | |
tree | 99b087cb9bc6d68c41aa3e075420ac8606995880 /command_line/CmdLine/Src/MacEmul | |
parent | 26b57fbea1a969ef6405365ff78391e9d3605621 (diff) | |
download | MWCC-4c9d73d7243c82ca3f55d2d8a388328968303b3f.tar.gz MWCC-4c9d73d7243c82ca3f55d2d8a388328968303b3f.zip |
almost finished Resources.c, two small issues in ReadResourceFork and FSpOpenResFile
Diffstat (limited to '')
-rw-r--r-- | command_line/CmdLine/Src/MacEmul/Resources.c | 765 |
1 files changed, 603 insertions, 162 deletions
diff --git a/command_line/CmdLine/Src/MacEmul/Resources.c b/command_line/CmdLine/Src/MacEmul/Resources.c index 7c2bea8..fcbed0b 100644 --- a/command_line/CmdLine/Src/MacEmul/Resources.c +++ b/command_line/CmdLine/Src/MacEmul/Resources.c @@ -1,23 +1,27 @@ #include "mwcc_decomp.h" -// base is 0,51, ptr is 0,54 -typedef struct MemRefList { - UInt16 id; - OSType type; - StringPtr name; - unsigned char attr; - Handle hand; - struct MemRefList *next; -} MemRefList; - -// base is 0,50, ptr is 0,55 -typedef struct MemRsrcTypeList { - OSType type; - MemRefList *ref_list; - struct MemRsrcTypeList *next; -} MemRsrcTypeList; - -// base is 0,56 +#define OPTION_ASSERT(cond) do { if (!(cond)) { printf("%s:%u: failed assertion\n", __FILE__, __LINE__); abort(); } } while(0) + +// Fork Attributes +enum { + mapReadOnly = 0x80, + mapCompact = 0x40, + mapChanged = 0x20 +}; + +// Resources +enum { + resSysHeap = 0x40, + resPurgeable = 0x20, + resLocked = 0x10, + resProtected = 8, + resPreload = 4, + resChanged = 2 +}; + +#ifdef __MWERKS__ +#pragma options align=mac68k +#endif typedef struct { char sysdata[66]; char type[4]; @@ -26,48 +30,65 @@ typedef struct { char appdata[128]; } MemRsrcSysData; // assumed name -// base is 0,49, ptr is 0,62, ptrptr is 0,63 -typedef struct MemRsrcMap { - SInt16 refnum; - UInt16 fork_attr; - MemRsrcTypeList *type_list; - MemRsrcSysData sys_data; - struct MemRsrcMap *prev; -} MemRsrcMap; - -typedef struct { +typedef struct { // Resource Header UInt32 data_offs; UInt32 map_offs; UInt32 data_len; UInt32 map_len; } Ty70; -typedef struct { +typedef struct { // Resource Map Ty70 mem_hdr; - Handle mem_next_map_handle; + Handle mem_next_map_handle; // fixme for 64-bit probably SInt16 mem_refnum; - UInt16 fork_addr; + UInt16 fork_attr; UInt16 typelist_offs; UInt16 namelist_offs; UInt16 types_idx; } Ty73; -typedef struct { +typedef struct { // Resource Type List Item OSType type; UInt16 rsrc_idx; UInt16 ref_list_offs; } Ty75; -typedef struct { +typedef struct { // Reference List Item UInt16 id; UInt16 name_offs; unsigned char attr; unsigned char data_offs[3]; Handle mem_rsrc_handle; } Ty77; -typedef struct { +typedef struct { // Name List Item unsigned char len; } Ty80; -typedef struct { +typedef struct { // Resource UInt32 len; } Ty82; +#ifdef __MWERKS__ +#pragma options align=reset +#endif + +typedef struct MemRefList { + UInt16 id; + OSType type; + StringPtr name; + unsigned char attr; + Handle hand; + struct MemRefList *next; +} MemRefList; + +typedef struct MemRsrcTypeList { + OSType type; + MemRefList *ref_list; + struct MemRsrcTypeList *next; +} MemRsrcTypeList; + +typedef struct MemRsrcMap { + SInt16 refnum; + UInt16 fork_attr; + MemRsrcTypeList *type_list; + MemRsrcSysData sys_data; + struct MemRsrcMap *prev; +} MemRsrcMap; typedef struct ResRef { OSSpec spec; @@ -95,6 +116,7 @@ void OS_UseMacResourceForkInfo(Boolean which) { } OSErr SystemInitResources(OSSpec *spec) { + FSSpec prog; void *file_data; SInt32 file_len; @@ -107,7 +129,6 @@ OSErr SystemInitResources(OSSpec *spec) { resError = noErr; return noErr; } else { - FSSpec prog; if (!OS_OSSpec_To_FSSpec(spec, &prog) && !FSpOpenResFile(&prog, 1)) { resError = noErr; return noErr; @@ -118,9 +139,9 @@ OSErr SystemInitResources(OSSpec *spec) { } } -static MemRsrcMap *NewResourceMap(SInt16 ref, UInt16 attr, MemRsrcTypeList *list) { - MemRsrcMap *nw; +static MemRsrcMap *NewResourceMap(SInt16 ref, UInt16 attr, MemRsrcTypeList *list, void *unk) { MemRsrcMap **scan; + MemRsrcMap *nw; scan = &maplist; nw = malloc(sizeof(MemRsrcMap)); @@ -158,9 +179,9 @@ static MemRsrcTypeList *NewTypeListEntry(MemRsrcTypeList **scan, OSType type, Me } static MemRefList *NewRefListEntry(MemRefList **scan, UInt16 id, OSType type, StringPtr name, unsigned char attr, Handle hand) { - char mname[256]; MemRefList *prev; MemRefList *nw; + char mname[256]; prev = 0; if (name) @@ -252,35 +273,154 @@ static void DeleteResources(SInt16 refNum) { } } +#define RF_READ(buf, offset, count, failBranch) \ +do { \ +SInt32 __offs = (offset); \ +if (!file_data) { \ +if ((resError = SetFPos(ref, fsFromStart, __offs)) != noErr) goto failBranch; \ +if ((resError = FSRead(ref, (SInt32 *) &(count), buf)) != noErr) goto failBranch; \ +} else { \ +if ((__offs + (count)) > file_size) goto failBranch; \ +memcpy(buf, ((unsigned char *) file_data) + __offs, (count)); \ +} \ +} while(0) + static void ReadResourceFork(SInt16 ref, SInt8 permission, void *file_data, SInt32 file_size) { - unsigned char *nameptr; - unsigned char *name; - Handle hand; - SInt32 offs; - SInt32 esize; - Ty82 tent; - MemRsrcTypeList *mtyp; - int rcnt; - SInt32 ref_offs; - SInt32 cnt; - SInt32 msize; - void *buffer; - Ty80 *dnam; - Ty77 *drle; - Ty75 *dtyp; - Ty73 *dmap; - MemRsrcSysData *dsys; - MemRsrcSysData tsys; - Ty70 *dhdr; - Ty70 thdr; MemRsrcMap *rm; + Ty70 thdr; + Ty70 *dhdr; + MemRsrcSysData tsys; + MemRsrcSysData *dsys; + Ty73 *dmap; + Ty75 *dtyp; + Ty77 *drle; + Ty80 *dnam; + void *buffer; + SInt32 msize; + SInt32 cnt; + SInt32 ref_offs; + int rcnt; + MemRsrcTypeList *mtyp; + Ty82 tent; + SInt32 esize; + SInt32 offs; + Handle hand; + unsigned char *name; + unsigned char *nameptr; + + if (!file_data) { + if ((resError = GetEOF(ref, &file_size)) != noErr) + goto mapFail; + } + + if (file_size < 90) + goto mapFail; + + cnt = sizeof(Ty70); + RF_READ(&thdr, 0, cnt, mapFail); + + ref_offs = cnt; + cnt = ((thdr.map_offs < thdr.data_offs) ? thdr.map_offs : thdr.data_offs) - sizeof(Ty70); + if (cnt > sizeof(MemRsrcSysData)) + cnt = sizeof(MemRsrcSysData); + RF_READ(&tsys, ref_offs, cnt, mapFail); + + msize = thdr.map_len; + buffer = malloc(msize); + if (!buffer) + goto memFail; + + ref_offs = thdr.map_offs; + RF_READ(buffer, ref_offs, msize, mapFail); + + if ( + (thdr.map_offs > file_size) + || ((thdr.map_offs + thdr.map_len) > file_size) + || (thdr.data_offs > file_size) + || ((thdr.data_offs + thdr.data_len) > file_size) + || ((thdr.map_offs < thdr.data_offs) ? ((thdr.map_offs + thdr.map_len) != thdr.data_offs) : ((thdr.data_offs + thdr.data_len) != thdr.map_offs)) + ) + goto mapFail; + + rm = NewResourceMap(ref, ((permission == 1) ? mapReadOnly : 0) | mapCompact, 0, 0); + if (!rm) + goto memFail; + + rm->sys_data = tsys; + + dmap = (Ty73 *) buffer; + if ((dmap->typelist_offs + thdr.map_offs) > file_size) + goto freeAndMapFail; + dtyp = (Ty75 *) (((unsigned char *) buffer) + dmap->typelist_offs + 2); + if ((dmap->namelist_offs + thdr.map_offs) > file_size) + goto freeAndMapFail; + dnam = (Ty80 *) (((unsigned char *) buffer) + dmap->namelist_offs); + if (dmap->types_idx != 0xFFFF) { + for (cnt = 0; cnt <= dmap->types_idx; cnt++) { + mtyp = NewTypeListEntry(&rm->type_list, dtyp[cnt].type, 0, 0); + if (!mtyp) + goto freeAndReturn; + + if ((thdr.map_offs + dmap->typelist_offs + dtyp[cnt].ref_list_offs) > file_size) + goto freeAndMapFail; + + drle = (Ty77 *) (((unsigned char *) dtyp) + dtyp[cnt].ref_list_offs - 2); + if (dtyp[cnt].rsrc_idx != 0xFFFF) { + for (rcnt = 0; rcnt <= dtyp[cnt].rsrc_idx; rcnt++) { + ref_offs = (drle[rcnt].data_offs[0] << 16) | (drle[rcnt].data_offs[1] << 8) | drle[rcnt].data_offs[2]; + offs = thdr.data_offs + ref_offs; + if (offs > file_size) + goto freeAndMapFail; + esize = 4; + RF_READ(&tent, offs, esize, freeAndMapFail); + + offs += esize; + if ((thdr.data_offs + ref_offs + tent.len) > file_size) + goto freeAndMapFail; + + hand = NewHandle(tent.len); + if (!hand) + goto freeAndMapFail; + + HLock(hand); + RF_READ(*hand, offs, tent.len, freeAndMapFail); + HUnlock(hand); + + if (drle[rcnt].name_offs != 0xFFFF) { + nameptr = (StringPtr) (dnam + drle[rcnt].name_offs); + name = malloc(nameptr[0] + 1); + memcpy(name, nameptr, nameptr[0] + 1); + } else { + name = 0; + } + + if (!NewRefListEntry(&mtyp->ref_list, drle[rcnt].id, dtyp[cnt].type, name, drle[rcnt].attr, hand)) + goto freeAndReturn; + } + } + } + } - // Not Right Now Folk's + free(buffer); + resError = noErr; + return; +freeAndMapFail: + resError = mapReadErr; +freeAndReturn: + DeleteResources(ref); + if (buffer) + free(buffer); + return; +memFail: + resError = memFullErr; + return; +mapFail: + resError = mapReadErr; } static void GetResourceSizes(MemRsrcMap *rm, SInt32 *data_size, SInt32 *name_size, SInt32 *reflist_size, SInt32 *typelist_size) { - MemRefList *mrle; MemRsrcTypeList *mtyp; + MemRefList *mrle; *data_size = *name_size = *reflist_size = *typelist_size = 0; @@ -299,8 +439,8 @@ static void GetResourceSizes(MemRsrcMap *rm, SInt32 *data_size, SInt32 *name_siz } static SInt32 GetResourceTypesCount(MemRsrcMap *dm) { - MemRsrcTypeList *mtyp; SInt32 tmp; + MemRsrcTypeList *mtyp; tmp = 0; mtyp = dm->type_list; @@ -313,8 +453,8 @@ static SInt32 GetResourceTypesCount(MemRsrcMap *dm) { } static SInt32 GetResourceEntriesCount(MemRsrcTypeList *mtyp) { - MemRefList *mrle; SInt32 tmp; + MemRefList *mrle; tmp = 0; mrle = mtyp->ref_list; @@ -326,52 +466,207 @@ static SInt32 GetResourceEntriesCount(MemRsrcTypeList *mtyp) { return tmp; } +#define RF_HANDLE_INSERT(hand, what, offset, size) \ +do { \ +SInt32 __offs = (offset); \ +SInt32 __len = (size); \ +if ((SInt32) (__offs + __len) > GetHandleSize(hand)) { \ +resError = mapReadErr; \ +return; \ +} else { \ +memcpy(*hand + __offs, (what), __len); \ +} \ +} \ +while (0) + static void WriteResourceFork(SInt16 ref) { - // some weird shit going on with locals here - // there's probably a bunch of macros - // may be able to refer to the Windows binary for assert values - SInt32 sz; - SInt32 __len; - SInt32 __offs; - SInt32 __offs_2; - SInt32 __len_2; - SInt32 __offs_3; - SInt32 __offs_4; - Ty82 tent; - Ty82 dent; - Ty77 trle; - Ty77 drle; - SInt32 __offs_5; - MemRefList *mrle; - Ty75 ttyp; - Ty75 dtyp; - MemRsrcTypeList *mtyp; - SInt32 __offs_6; - SInt32 data_offs; - SInt32 name_offs; - SInt32 typelist_offs; - SInt32 reflist_offs; - SInt32 data_size; - SInt32 name_size; - SInt32 typelist_size; - SInt32 reflist_size; - Handle hand_ref; - Ty73 tmap; - Ty73 dmap; - MemRsrcSysData tsys; - Ty70 thdr; - Ty70 dhdr; MemRsrcMap *rm; + Ty70 dhdr; + Ty70 thdr; + MemRsrcSysData tsys; + Ty73 dmap; + Ty73 tmap; + Handle hand_ref; + SInt32 reflist_size, typelist_size; + SInt32 name_size, data_size; + SInt32 reflist_offs, typelist_offs; + SInt32 name_offs, data_offs; + MemRsrcTypeList *mtyp; + Ty75 dtyp; + Ty75 ttyp; + MemRefList *mrle; + Ty77 drle; + Ty77 trle; + Ty82 dent; + Ty82 tent; + SInt32 sz; + + rm = FindResourceMap(ref); + if (!rm) { + resError = resFNotFound; + return; + } + + if (rm->refnum == -1) { + resError = resFNotFound; + return; + } + + if (rm->fork_attr & mapReadOnly) { + resError = resAttrErr; + return; + } + + if (!(rm->fork_attr & mapChanged)) { + return; + } + + GetResourceSizes(rm, &data_size, &name_size, &reflist_size, &typelist_size); + dhdr.data_offs = sizeof(dhdr) + sizeof(tsys); + dhdr.data_len = data_size; + dhdr.map_offs = sizeof(dhdr) + sizeof(tsys) + data_size; + dhdr.map_len = name_size + reflist_size + typelist_size + sizeof(dmap); + + hand_ref = NewHandle(dhdr.map_offs + dhdr.map_len); + if (!hand_ref) { + resError = MemError(); + return; + } + + HLock(hand_ref); + memset(*hand_ref, 0, dhdr.map_offs + dhdr.map_len); + thdr = dhdr; + // This is where it would be endian-swapped i guess + RF_HANDLE_INSERT(hand_ref, &thdr, 0, sizeof(thdr)); + + tsys = rm->sys_data; + RF_HANDLE_INSERT(hand_ref, &tsys, sizeof(thdr), sizeof(tsys)); + + dmap.mem_hdr = thdr; + dmap.mem_next_map_handle = 0; + dmap.mem_refnum = 0; + dmap.fork_attr = rm->fork_attr & ~resChanged; // bug! should be mapChanged + dmap.typelist_offs = sizeof(dmap) - 2; + dmap.namelist_offs = typelist_size + reflist_size + sizeof(dmap); + dmap.types_idx = GetResourceTypesCount(rm) - 1; + tmap = dmap; + RF_HANDLE_INSERT(hand_ref, &tmap, dhdr.map_offs, sizeof(tmap)); + + // Now write the actual shit + name_offs = 0; + data_offs = 0; + reflist_offs = 0; + typelist_offs = 0; + mtyp = rm->type_list; + while (mtyp) { + dtyp.type = mtyp->type; + dtyp.rsrc_idx = GetResourceEntriesCount(mtyp) - 1; + dtyp.ref_list_offs = typelist_size + reflist_offs + 2; + ttyp = dtyp; + RF_HANDLE_INSERT(hand_ref, &ttyp, (dhdr.map_offs + dmap.typelist_offs + 2) + typelist_offs, sizeof(ttyp)); + + mrle = mtyp->ref_list; + while (mrle) { +#line 943 + OPTION_ASSERT(reflist_offs < dmap.namelist_offs); + + drle.id = mrle->id; + drle.name_offs = (mrle->name) ? name_offs : -1; + drle.attr = mrle->attr & ~resChanged; + drle.data_offs[0] = (data_offs & 0xFF0000) >> 16; + drle.data_offs[1] = (data_offs & 0x00FF00) >> 8; + drle.data_offs[2] = (data_offs & 0x0000FF); + drle.mem_rsrc_handle = 0; + trle = drle; + RF_HANDLE_INSERT(hand_ref, &trle, (dhdr.map_offs + dmap.typelist_offs + 2) + typelist_size + reflist_offs, sizeof(trle)); + + reflist_offs += sizeof(trle); + if (mrle->name) { +#line 962 + if (dhdr.map_offs < dhdr.data_offs) + OPTION_ASSERT(name_offs + dmap.namelist_offs + dhdr.map_offs < dhdr.data_offs); + RF_HANDLE_INSERT(hand_ref, mrle->name, dhdr.map_offs + dmap.namelist_offs + drle.name_offs, mrle->name[0] + 1); + name_offs += mrle->name[0] + 1; + } + +#line 970 + OPTION_ASSERT(data_offs < dhdr.data_len); + OPTION_ASSERT(mrle->hand!=NULL); + if (dhdr.map_offs > dhdr.data_offs) + OPTION_ASSERT(data_offs + dhdr.data_offs < dhdr.map_offs); + + HLock(mrle->hand); + dent.len = GetHandleSize(mrle->hand); + tent = dent; + RF_HANDLE_INSERT(hand_ref, &tent, dhdr.data_offs + data_offs, sizeof(tent)); + data_offs += sizeof(tent); + RF_HANDLE_INSERT(hand_ref, *mrle->hand, dhdr.data_offs + data_offs, dent.len); + data_offs += dent.len; + HUnlock(mrle->hand); + + mrle = mrle->next; + } + + mtyp = mtyp->next; + typelist_offs += sizeof(ttyp); + } + + sz = GetHandleSize(hand_ref); + if ((resError = SetFPos(ref, fsFromStart, 0)) != noErr) + return; + if ((resError = SetEOF(ref, sz)) != noErr) + return; + if ((resError = FSWrite(ref, &sz, *hand_ref)) != noErr) + return; + HUnlock(hand_ref); + DisposeHandle(hand_ref); } static void WriteEmptyResourceFork(SInt16 ref) { - SInt32 sz; - Handle hand_ref; - Ty73 dmap; - MemRsrcSysData dsys; Ty70 dhdr; + MemRsrcSysData dsys; + Ty73 dmap; + Handle hand_ref; + SInt32 sz; + + dhdr.map_offs = sizeof(dhdr) + sizeof(dsys); + dhdr.map_len = sizeof(dmap); + dhdr.data_offs = sizeof(dhdr) + sizeof(dsys) + sizeof(dmap); + dhdr.data_len = 0; + + memset(&dsys, 0, sizeof(dsys)); + memset(&dsys.creator, 0, sizeof(dsys.creator)); + memset(&dsys.type, 0, sizeof(dsys.type)); + + dmap.mem_hdr = dhdr; + dmap.mem_next_map_handle = 0; + dmap.mem_refnum = 0; + dmap.fork_attr = 0; + dmap.typelist_offs = sizeof(dmap) - 2; + dmap.namelist_offs = sizeof(dmap) - 2; + dmap.types_idx = 0xFFFF; + + hand_ref = NewHandle(sizeof(dhdr) + sizeof(dsys) + sizeof(dmap)); + if (!hand_ref) { + resError = MemError(); + return; + } - // i'll do this one later lol + HLock(hand_ref); + memset(*hand_ref, 0, sizeof(dhdr) + sizeof(dsys) + sizeof(dmap)); + RF_HANDLE_INSERT(hand_ref, &dhdr, 0, sizeof(dhdr)); + RF_HANDLE_INSERT(hand_ref, &dsys, sizeof(dhdr), sizeof(dsys)); + RF_HANDLE_INSERT(hand_ref, &dmap, sizeof(dhdr) + sizeof(dsys), sizeof(dmap)); + + sz = GetHandleSize(hand_ref); + if ((resError = SetFPos(ref, fsFromStart, 0)) != noErr) + return; + if ((resError = SetEOF(ref, sz)) != noErr) + return; + if ((resError = FSWrite(ref, &sz, *hand_ref)) != noErr) + return; + HUnlock(hand_ref); + DisposeHandle(hand_ref); } static MemRsrcTypeList *FindResourceType1(MemRsrcMap *rm, OSType theType) { @@ -416,8 +711,8 @@ static SInt32 CountResourceType(OSType theType) { } static MemRefList *FindIndResource1(MemRsrcMap *rm, OSType theType, SInt16 index) { - MemRefList *mrle; MemRsrcTypeList *mtyp; + MemRefList *mrle; mtyp = rm->type_list; while (mtyp) { @@ -435,8 +730,8 @@ static MemRefList *FindIndResource1(MemRsrcMap *rm, OSType theType, SInt16 index } static MemRefList *FindIndResource(OSType theType, SInt16 index) { - MemRefList *mrle; MemRsrcMap *rm = FindResourceMap(cur_res_file); + MemRefList *mrle; while (rm) { mrle = FindIndResource1(rm, theType, index); @@ -449,8 +744,8 @@ static MemRefList *FindIndResource(OSType theType, SInt16 index) { } static MemRefList *FindResourceTypeAndID1(MemRsrcMap *rm, OSType theType, SInt16 theID) { - MemRefList *mref; MemRsrcTypeList *mtyp = FindResourceType1(rm, theType); + MemRefList *mref; if (mtyp) { mref = mtyp->ref_list; @@ -465,8 +760,8 @@ static MemRefList *FindResourceTypeAndID1(MemRsrcMap *rm, OSType theType, SInt16 } static MemRefList *FindResourceTypeAndID(OSType theType, SInt16 theID) { - MemRefList *mref; MemRsrcMap *rm = FindResourceMap(cur_res_file); + MemRefList *mref; while (rm) { mref = FindResourceTypeAndID1(rm, theType, theID); @@ -479,8 +774,8 @@ static MemRefList *FindResourceTypeAndID(OSType theType, SInt16 theID) { } static MemRefList *FindResourceTypeAndName1(MemRsrcMap *rm, OSType theType, ConstStringPtr theName) { - MemRefList *mref; MemRsrcTypeList *mtyp; + MemRefList *mref; mtyp = FindResourceType1(rm, theType); if (mtyp) { @@ -496,8 +791,8 @@ static MemRefList *FindResourceTypeAndName1(MemRsrcMap *rm, OSType theType, Cons } static MemRefList *FindResourceTypeAndName(OSType theType, ConstStringPtr theName) { - MemRefList *mref; MemRsrcMap *rm = FindResourceMap(cur_res_file); + MemRefList *mref; while (rm) { mref = FindResourceTypeAndName1(rm, theType, theName); @@ -510,8 +805,8 @@ static MemRefList *FindResourceTypeAndName(OSType theType, ConstStringPtr theNam } static MemRefList *FindResourceHandle1(MemRsrcMap *rm, Handle theResource) { - MemRefList *mrle; MemRsrcTypeList *mtyp; + MemRefList *mrle; for (mtyp = rm->type_list; mtyp; mtyp = mtyp->next) { for (mrle = mtyp->ref_list; mrle; mrle = mrle->next) { @@ -524,8 +819,8 @@ static MemRefList *FindResourceHandle1(MemRsrcMap *rm, Handle theResource) { } static MemRefList *FindResourceHandle(Handle theResource) { - MemRefList *mrle; MemRsrcMap *rm; + MemRefList *mrle; for (rm = FindResourceMap(cur_res_file); rm; rm = rm->prev) { mrle = FindResourceHandle1(rm, theResource); @@ -537,8 +832,8 @@ static MemRefList *FindResourceHandle(Handle theResource) { } static int RemoveResourceHandle1(MemRsrcMap *rm, Handle theResource) { - MemRefList *mrle, *pmrle; MemRsrcTypeList *mtyp, *pmtyp; + MemRefList *mrle, *pmrle; mtyp = rm->type_list; pmtyp = 0; @@ -586,37 +881,102 @@ static int RemoveResourceHandle(Handle theResource) { } static SInt16 FindResourceHandleFile1(MemRsrcMap *rm, Handle theResource) { - MemRefList *mrle; MemRsrcTypeList *mtyp; + MemRefList *mrle; + + for (mtyp = rm->type_list; mtyp; mtyp = mtyp->next) { + for (mrle = mtyp->ref_list; mrle; mrle = mrle->next) { + if (mrle->hand == theResource) + return rm->refnum; + } + } + + return -1; } static SInt16 FindResourceHandleFile(Handle theResource) { - MemRefList *mrle; MemRsrcMap *rm; + MemRefList *mrle; + + for (rm = FindResourceMap(cur_res_file); rm; rm = rm->prev) { + mrle = FindResourceHandle1(rm, theResource); + if (mrle) + return rm->refnum; + } + + return -1; } void OS_AddMacResourceForkRef(int ref, const OSSpec *spec) { ResRef *nw; + + nw = malloc(sizeof(ResRef)); + if (nw) { + nw->spec = *spec; + nw->ref = ref; + nw->next = 0; + if (resForkLast) + resForkLast->next = nw; + else + resForkList = nw; + resForkLast = nw; + } } void OS_RemoveMacResourceForkRef(int ref) { - ResRef *prev; ResRef *lst; + ResRef *prev; + + lst = resForkList; + prev = 0; + while (lst && lst->ref != ref) { + prev = lst; + lst = lst->next; + } + + if (lst) { + if (prev) { + prev->next = lst->next; + if (!prev->next) + resForkLast = prev; + } else { + resForkList = lst->next; + if (!resForkList) + resForkLast = 0; + } + free(lst); + } } OSSpec *OS_GetMacResourceForkFromRef(int ref) { ResRef *lst; + + for (lst = resForkList; lst; lst = lst->next) { + if (lst->ref == ref) + return &lst->spec; + } + + return 0; } Boolean OS_SearchMacResourceForkList(const OSSpec *rspec, int *ref) { ResRef *lst; + + for (lst = resForkList; lst; lst = lst->next) { + if (OS_EqualSpec(&lst->spec, rspec)) { + *ref = lst->ref; + return 1; + } + } + + return 0; } int OS_SetMacResourceForkCreatorAndType(int ref, OSType creator, OSType type) { - MemRsrcMap *rm; - UInt32 sz; - UInt32 buf[2]; int err; + UInt32 buf[2]; + UInt32 sz; + MemRsrcMap *rm; if (!OS_GetMacResourceForkFromRef(ref)) { sz = 8; @@ -633,7 +993,7 @@ int OS_SetMacResourceForkCreatorAndType(int ref, OSType creator, OSType type) { rm = FindResourceMap(OS_RefToMac(ref)); if (!rm) { err = 2; - } else if (rm->fork_attr & 0x80) { + } else if (rm->fork_attr & mapReadOnly) { err = 13; } else { rm->sys_data.creator[0] = (creator & 0xFF000000) >> 24; @@ -644,7 +1004,7 @@ int OS_SetMacResourceForkCreatorAndType(int ref, OSType creator, OSType type) { rm->sys_data.type[1] = (type & 0x00FF0000) >> 16; rm->sys_data.type[2] = (type & 0x0000FF00) >> 8; rm->sys_data.type[3] = (type & 0x000000FF); - rm->fork_attr |= 0x20; + rm->fork_attr |= mapChanged; err = 0; } } @@ -653,10 +1013,10 @@ int OS_SetMacResourceForkCreatorAndType(int ref, OSType creator, OSType type) { } int OS_GetMacResourceForkCreatorAndType(int ref, OSType *creator, OSType *type) { - MemRsrcMap *rm; - UInt32 sz; - UInt32 buf[2]; int err; + UInt32 buf[2]; + UInt32 sz; + MemRsrcMap *rm; if (!OS_GetMacResourceForkFromRef(ref)) { sz = 8; @@ -688,28 +1048,109 @@ void OS_CleanupMacResourceForkDir(const OSPathSpec *dir) { } OSErr OS_MacDumpResourceFork(SInt16 ref, Boolean dumpContents) { - int spaces; - char safe[16]; - SInt32 size; - SInt32 idx; - StringPtr ptr; - char name[256]; - MemRefList *rl; - MemRsrcTypeList *tl; MemRsrcMap *rm; + MemRsrcTypeList *tl; + MemRefList *rl; + char name[256]; + unsigned char *ptr; + SInt32 idx; + SInt32 size; + char safe[16]; + int spaces; + + rm = FindResourceMap(ref); + if (!rm) { + fprintf(stderr, "Could not find resource fork for ref = %d\n", ref); + return fnfErr; + } + + printf("Fork attributes = %04X\n", rm->fork_attr); + printf("Creator = '%4.4s'; Type = '%4.4s'\n", rm->sys_data.creator, rm->sys_data.type); + printf("Types:\n"); + + for (tl = rm->type_list; tl; tl = tl->next) { + printf("'%c%c%c%c':\n", + (tl->type & 0xFF000000) >> 24, + (tl->type & 0x00FF0000) >> 16, + (tl->type & 0x0000FF00) >> 8, + (tl->type & 0x000000FF) + ); + for (rl = tl->ref_list; rl; rl = rl->next) { + if (rl->type != tl->type) + printf("!!! RefList type '%c%c%c%c' does not match TypeList type !!!\n", + (rl->type & 0xFF000000) >> 24, + (rl->type & 0x00FF0000) >> 16, + (rl->type & 0x0000FF00) >> 8, + (rl->type & 0x000000FF) + ); + + if (rl->name) + p2cstrcpy(name, rl->name); + else + strcpy(name, "<none>"); + + printf("\tID = %d '%s'\n", rl->id, name); + printf("\tAttributes: "); + if (rl->attr & resSysHeap) + printf("SysHeap "); + if (rl->attr & resPurgeable) + printf("Purgeable "); + if (rl->attr & resLocked) + printf("Locked "); + if (rl->attr & resProtected) + printf("Protected "); + if (rl->attr & resPreload) + printf("Preload "); + if (rl->attr & resChanged) + printf("Changed "); + printf("\n"); + + if (dumpContents) { + size = GetHandleSize(rl->hand); + HLock(rl->hand); + ptr = (unsigned char *) *rl->hand; + idx = 0; + printf("Contents:"); + + while (idx < size) { + if ((idx % 16) == 0) { + printf("\n%08X: ", idx); + memset(safe, ' ', 16); + } + printf("%02X ", ptr[idx]); + if (isprint(ptr[idx])) + safe[idx & 15] = ptr[idx]; + else + safe[idx & 15] = '.'; + + if (((idx % 16) == 15) || (idx + 1) == size) { + spaces = (((idx & 15) + 15) & ~15) - (idx & 15); + while (spaces--) + printf(" "); + printf(" %16.16s", safe); + } + + ++idx; + } + + printf("\n"); + } + } + } - // Debug shit + printf("\n"); + CloseResFile(ref); + return noErr; } OSErr FSpOpenRF(const FSSpec *fss, SInt8 permission, SInt16 *refNum) { - Boolean create; - OSSpec rspec; - OSSpec spec; - FSSpec rfss; - int oserr; OSErr err; + int oserr; + FSSpec rfss; + OSSpec spec, rspec; + Boolean create; - create = (permission == 1) | (permission > 1); + create = (permission != fsRdPerm); oserr = OS_FSSpec_To_OSSpec(fss, &spec); if (oserr) return OS_MacError(oserr); @@ -733,8 +1174,8 @@ OSErr FSpOpenRF(const FSSpec *fss, SInt8 permission, SInt16 *refNum) { } OSErr HOpenRF(SInt16 vRefNum, SInt32 dirID, ConstStringPtr fileName, SInt8 permission, SInt16 *refNum) { - OSErr __err; FSSpec fss; + OSErr __err; __err = FSMakeFSSpec(vRefNum, dirID, fileName, &fss); if (__err != noErr && __err != fnfErr) { @@ -764,9 +1205,9 @@ OSErr ResError() { } void FSpCreateResFile(const FSSpec *fss, OSType creator, OSType fileType, ScriptCode scriptTag) { - SInt16 ref; - OSSpec spec, rspec; int oserr; + OSSpec spec, rspec; + SInt16 ref; FSpCreate(fss, creator, fileType, scriptTag); oserr = OS_FSSpec_To_OSSpec(fss, &spec); @@ -800,8 +1241,8 @@ void FSpCreateResFile(const FSSpec *fss, OSType creator, OSType fileType, Script } void HCreateResFile(SInt16 vRefNum, SInt32 dirID, ConstStringPtr fileName) { - OSErr __err; FSSpec fss; + OSErr __err; __err = FSMakeFSSpec(vRefNum, dirID, fileName, &fss); if (__err != noErr && __err != fnfErr) { @@ -812,16 +1253,16 @@ void HCreateResFile(SInt16 vRefNum, SInt32 dirID, ConstStringPtr fileName) { } OSErr FSpOpenResFile(const FSSpec *fss, SInt8 permission) { - SInt32 size; SInt16 ref; + SInt32 size; - if (permission != 1) + if (permission != fsRdPerm) FSpCreate(fss, 'CWIE', 'TEXT', -1); - resError = FSpOpenRF(fss, (permission != 2) ? permission : 3, &ref); + resError = FSpOpenRF(fss, (permission == fsWrPerm) ? fsRdWrPerm : permission, &ref); if (!resError) { GetEOF(ref, &size); - if (size == 0 && permission != 1) + if (size == 0 && permission != fsRdPerm) WriteEmptyResourceFork(ref); ReadResourceFork(ref, permission, 0, 0); if (resError) { @@ -838,8 +1279,8 @@ OSErr FSpOpenResFile(const FSSpec *fss, SInt8 permission) { } OSErr HOpenResFile(SInt16 vRefNum, SInt32 dirID, ConstStringPtr fileName, SInt8 permission) { - OSErr __err; FSSpec fss; + OSErr __err; __err = FSMakeFSSpec(vRefNum, dirID, fileName, &fss); if (__err != noErr && __err != fnfErr) @@ -885,8 +1326,8 @@ Handle GetResource(OSType theType, SInt16 theID) { } Handle Get1Resource(OSType theType, SInt16 theID) { - MemRefList *mref; MemRsrcMap *rm; + MemRefList *mref; rm = FindResourceMap(cur_res_file); if (!rm) { @@ -918,8 +1359,8 @@ Handle GetNamedResource(OSType theType, ConstStringPtr theName) { } Handle Get1NamedResource(OSType theType, ConstStringPtr theName) { - MemRefList *mref; MemRsrcMap *rm; + MemRefList *mref; rm = FindResourceMap(cur_res_file); if (!rm) { @@ -971,7 +1412,7 @@ void SetResInfo(Handle theResource, SInt16 theID, ConstStringPtr name) { if (mrle->name) free(mrle->name); mrle->name = malloc(name[0] + 1); - mrle->attr |= 2; + mrle->attr |= resChanged; if (mrle->name) _pstrcpy(mrle->name, name); else @@ -1007,18 +1448,18 @@ void SetResAttrs(Handle theResource, SInt16 attrs) { } void ChangedResource(Handle theResource) { - MemRefList *mrle; MemRsrcMap *rm; + MemRefList *mrle; rm = FindResourceMap(cur_res_file); mrle = FindResourceHandle(theResource); if (mrle) { - if (rm && (rm->fork_attr & 0x80)) { + if (rm && (rm->fork_attr & mapReadOnly)) { resError = resAttrErr; } else { resError = noErr; - mrle->attr |= 2; - rm->fork_attr |= 0x20; + mrle->attr |= resChanged; + rm->fork_attr |= mapChanged; } } else { resError = resNotFound; @@ -1033,7 +1474,7 @@ void AddResource(Handle theData, OSType theType, SInt16 theID, ConstStringPtr na rm = FindResourceMap(cur_res_file); if (rm) { - if (rm->fork_attr & 0x80) { + if (rm->fork_attr & mapReadOnly) { resError = resAttrErr; return; } @@ -1046,7 +1487,7 @@ void AddResource(Handle theData, OSType theType, SInt16 theID, ConstStringPtr na resError = memFullErr; return; } - rm->fork_attr |= 0x20; + rm->fork_attr |= mapChanged; } if (!theData || FindResourceHandle(theData)) { resError = addResFailed; @@ -1066,7 +1507,7 @@ void AddResource(Handle theData, OSType theType, SInt16 theID, ConstStringPtr na return; } - rm->fork_attr |= 0x20; + rm->fork_attr |= mapChanged; } else { resError = resFNotFound; } @@ -1109,8 +1550,8 @@ Handle GetIndResource(OSType theType, SInt16 index) { } Handle Get1IndResource(OSType theType, SInt16 index) { - MemRefList *mrle; MemRsrcMap *rm; + MemRefList *mrle; rm = FindResourceMap(cur_res_file); if (rm) { @@ -1129,9 +1570,9 @@ Handle Get1IndResource(OSType theType, SInt16 index) { } SInt16 Count1Types() { - SInt16 count; - MemRsrcTypeList *rtl; MemRsrcMap *rm; + MemRsrcTypeList *rtl; + SInt16 count; count = 0; rm = FindResourceMap(cur_res_file); @@ -1149,9 +1590,9 @@ SInt16 Count1Types() { } void Get1IndType(OSType *theType, SInt16 index) { - SInt16 count; - MemRsrcTypeList *rtl; MemRsrcMap *rm; + MemRsrcTypeList *rtl; + SInt16 count; count = 1; rm = FindResourceMap(cur_res_file); @@ -1175,8 +1616,8 @@ void ReleaseResource(Handle theResource) { } void DetachResource(Handle theResource) { - SInt32 ns; MemRefList *mrle; + SInt32 ns; mrle = FindResourceHandle(theResource); if (mrle) { |