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 | |
| 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 'command_line/CmdLine')
| -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) {  | 
