mirror of https://git.wuffs.org/MWCC
1231 lines
27 KiB
C
1231 lines
27 KiB
C
#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
|
|
typedef struct {
|
|
char sysdata[66];
|
|
char type[4];
|
|
char creator[4];
|
|
char sysdata2[38];
|
|
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 {
|
|
UInt32 data_offs;
|
|
UInt32 map_offs;
|
|
UInt32 data_len;
|
|
UInt32 map_len;
|
|
} Ty70;
|
|
typedef struct {
|
|
Ty70 mem_hdr;
|
|
Handle mem_next_map_handle;
|
|
SInt16 mem_refnum;
|
|
UInt16 fork_addr;
|
|
UInt16 typelist_offs;
|
|
UInt16 namelist_offs;
|
|
UInt16 types_idx;
|
|
} Ty73;
|
|
typedef struct {
|
|
OSType type;
|
|
UInt16 rsrc_idx;
|
|
UInt16 ref_list_offs;
|
|
} Ty75;
|
|
typedef struct {
|
|
UInt16 id;
|
|
UInt16 name_offs;
|
|
unsigned char attr;
|
|
unsigned char data_offs[3];
|
|
Handle mem_rsrc_handle;
|
|
} Ty77;
|
|
typedef struct {
|
|
unsigned char len;
|
|
} Ty80;
|
|
typedef struct {
|
|
UInt32 len;
|
|
} Ty82;
|
|
|
|
typedef struct ResRef {
|
|
OSSpec spec;
|
|
int ref;
|
|
struct ResRef *next;
|
|
} ResRef;
|
|
|
|
static OSErr resError;
|
|
static SInt16 cur_res_file;
|
|
Boolean ResLoad;
|
|
static MemRsrcMap *maplist;
|
|
static ResRef *resForkList;
|
|
static ResRef *resForkLast;
|
|
static Boolean UseResourceForkInfo;
|
|
|
|
// Forward declarations
|
|
static void ReadResourceFork(SInt16 ref, SInt8 permission, void *file_data, SInt32 file_size);
|
|
|
|
Boolean OS_UsingMacResourceForkInfo() {
|
|
return UseResourceForkInfo;
|
|
}
|
|
|
|
void OS_UseMacResourceForkInfo(Boolean which) {
|
|
UseResourceForkInfo = which;
|
|
}
|
|
|
|
OSErr SystemInitResources(OSSpec *spec) {
|
|
void *file_data;
|
|
SInt32 file_len;
|
|
|
|
maplist = 0;
|
|
cur_res_file = 0;
|
|
|
|
if (!OS_LoadMacResourceFork(spec, &file_data, &file_len)) {
|
|
ReadResourceFork(-1, 1, file_data, file_len);
|
|
cur_res_file = -1;
|
|
resError = noErr;
|
|
return noErr;
|
|
} else {
|
|
FSSpec prog;
|
|
if (!OS_OSSpec_To_FSSpec(spec, &prog) && !FSpOpenResFile(&prog, 1)) {
|
|
resError = noErr;
|
|
return noErr;
|
|
} else {
|
|
resError = fnfErr;
|
|
return fnfErr;
|
|
}
|
|
}
|
|
}
|
|
|
|
static MemRsrcMap *NewResourceMap(SInt16 ref, UInt16 attr, MemRsrcTypeList *list) {
|
|
MemRsrcMap *nw;
|
|
MemRsrcMap **scan;
|
|
|
|
scan = &maplist;
|
|
nw = malloc(sizeof(MemRsrcMap));
|
|
|
|
if (!nw) {
|
|
resError = memFullErr;
|
|
return 0;
|
|
}
|
|
|
|
nw->refnum = ref;
|
|
nw->fork_attr = attr;
|
|
nw->type_list = list;
|
|
nw->prev = *scan;
|
|
*scan = nw;
|
|
return nw;
|
|
}
|
|
|
|
static MemRsrcTypeList *NewTypeListEntry(MemRsrcTypeList **scan, OSType type, MemRefList *list, MemRsrcTypeList *next) {
|
|
MemRsrcTypeList *nw;
|
|
|
|
while (*scan)
|
|
scan = &(*scan)->next;
|
|
|
|
nw = malloc(sizeof(MemRsrcTypeList));
|
|
if (!nw) {
|
|
resError = memFullErr;
|
|
return 0;
|
|
}
|
|
|
|
nw->type = type;
|
|
nw->ref_list = list;
|
|
nw->next = next;
|
|
*scan = nw;
|
|
return nw;
|
|
}
|
|
|
|
static MemRefList *NewRefListEntry(MemRefList **scan, UInt16 id, OSType type, StringPtr name, unsigned char attr, Handle hand) {
|
|
char mname[256];
|
|
MemRefList *prev;
|
|
MemRefList *nw;
|
|
|
|
prev = 0;
|
|
if (name)
|
|
p2cstrcpy(mname, name);
|
|
else
|
|
strcpy(mname, "(none)");
|
|
|
|
while (*scan && (*scan)->id != id) {
|
|
prev = *scan;
|
|
scan = &(*scan)->next;
|
|
}
|
|
|
|
nw = malloc(sizeof(MemRefList));
|
|
if (!nw) {
|
|
resError = memFullErr;
|
|
return 0;
|
|
}
|
|
|
|
nw->id = id;
|
|
nw->type = type;
|
|
nw->name = name;
|
|
nw->attr = attr;
|
|
nw->hand = hand;
|
|
if (prev) {
|
|
nw->next = prev->next;
|
|
prev->next = nw;
|
|
} else {
|
|
nw->next = 0;
|
|
}
|
|
*scan = nw;
|
|
return nw;
|
|
}
|
|
|
|
static MemRsrcMap *FindResourceMap(SInt16 ref) {
|
|
MemRsrcMap *list = maplist;
|
|
|
|
while (list) {
|
|
if (list->refnum == ref)
|
|
return list;
|
|
list = list->prev;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static MemRsrcMap *FindResourceMap2(SInt16 ref, MemRsrcMap **next) {
|
|
MemRsrcMap *list = maplist;
|
|
|
|
*next = 0;
|
|
while (list) {
|
|
if (list->refnum == ref)
|
|
return list;
|
|
*next = list;
|
|
list = list->prev;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void DeleteResources(SInt16 refNum) {
|
|
MemRsrcMap *rm, *rmnext;
|
|
MemRsrcTypeList *mtyptmp, *mtyp;
|
|
MemRefList *mrletmp, *mrle;
|
|
|
|
rm = FindResourceMap2(refNum, &rmnext);
|
|
if (rm) {
|
|
mtyp = rm->type_list;
|
|
while (mtyp) {
|
|
mrle = mtyp->ref_list;
|
|
while (mrle) {
|
|
if (mrle->hand)
|
|
DisposeHandle(mrle->hand);
|
|
if (mrle->name)
|
|
free(mrle->name);
|
|
mrletmp = mrle;
|
|
mrle = mrle->next;
|
|
free(mrletmp);
|
|
}
|
|
mtyptmp = mtyp;
|
|
mtyp = mtyp->next;
|
|
free(mtyptmp);
|
|
}
|
|
|
|
if (rmnext)
|
|
rmnext->prev = rm->prev;
|
|
else
|
|
maplist = rm->prev;
|
|
free(rm);
|
|
}
|
|
}
|
|
|
|
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;
|
|
|
|
// Not Right Now Folk's
|
|
}
|
|
|
|
static void GetResourceSizes(MemRsrcMap *rm, SInt32 *data_size, SInt32 *name_size, SInt32 *reflist_size, SInt32 *typelist_size) {
|
|
MemRefList *mrle;
|
|
MemRsrcTypeList *mtyp;
|
|
|
|
*data_size = *name_size = *reflist_size = *typelist_size = 0;
|
|
|
|
mtyp = rm->type_list;
|
|
while (mtyp) {
|
|
mrle = mtyp->ref_list;
|
|
while (mrle) {
|
|
*name_size += !mrle->name ? 0 : (mrle->name[0] + 1);
|
|
*data_size += (!mrle->hand ? 0 : GetHandleSize(mrle->hand)) + 4;
|
|
*reflist_size += 12;
|
|
mrle = mrle->next;
|
|
}
|
|
*typelist_size += 8;
|
|
mtyp = mtyp->next;
|
|
}
|
|
}
|
|
|
|
static SInt32 GetResourceTypesCount(MemRsrcMap *dm) {
|
|
MemRsrcTypeList *mtyp;
|
|
SInt32 tmp;
|
|
|
|
tmp = 0;
|
|
mtyp = dm->type_list;
|
|
while (mtyp) {
|
|
mtyp = mtyp->next;
|
|
++tmp;
|
|
}
|
|
|
|
return tmp;
|
|
}
|
|
|
|
static SInt32 GetResourceEntriesCount(MemRsrcTypeList *mtyp) {
|
|
MemRefList *mrle;
|
|
SInt32 tmp;
|
|
|
|
tmp = 0;
|
|
mrle = mtyp->ref_list;
|
|
while (mrle) {
|
|
mrle = mrle->next;
|
|
++tmp;
|
|
}
|
|
|
|
return tmp;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
static void WriteEmptyResourceFork(SInt16 ref) {
|
|
SInt32 sz;
|
|
Handle hand_ref;
|
|
Ty73 dmap;
|
|
MemRsrcSysData dsys;
|
|
Ty70 dhdr;
|
|
|
|
// i'll do this one later lol
|
|
}
|
|
|
|
static MemRsrcTypeList *FindResourceType1(MemRsrcMap *rm, OSType theType) {
|
|
MemRsrcTypeList *mtyp;
|
|
|
|
mtyp = rm->type_list;
|
|
while (mtyp) {
|
|
if (mtyp->type == theType)
|
|
return mtyp;
|
|
mtyp = mtyp->next;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static SInt32 CountResourceType1(MemRsrcMap *rm, OSType theType) {
|
|
MemRsrcTypeList *mtyp;
|
|
|
|
mtyp = rm->type_list;
|
|
while (mtyp) {
|
|
if (mtyp->type == theType)
|
|
return GetResourceEntriesCount(mtyp);
|
|
mtyp = mtyp->next;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static SInt32 CountResourceType(OSType theType) {
|
|
MemRsrcMap *rm;
|
|
SInt32 total;
|
|
|
|
total = 0;
|
|
rm = FindResourceMap(cur_res_file);
|
|
|
|
while (rm) {
|
|
total += CountResourceType1(rm, theType);
|
|
rm = rm->prev;
|
|
}
|
|
|
|
return total;
|
|
}
|
|
|
|
static MemRefList *FindIndResource1(MemRsrcMap *rm, OSType theType, SInt16 index) {
|
|
MemRefList *mrle;
|
|
MemRsrcTypeList *mtyp;
|
|
|
|
mtyp = rm->type_list;
|
|
while (mtyp) {
|
|
if (mtyp->type == theType) {
|
|
mrle = mtyp->ref_list;
|
|
while (mrle && --index > 0) {
|
|
mrle = mrle->next;
|
|
}
|
|
return mrle;
|
|
}
|
|
mtyp = mtyp->next;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static MemRefList *FindIndResource(OSType theType, SInt16 index) {
|
|
MemRefList *mrle;
|
|
MemRsrcMap *rm = FindResourceMap(cur_res_file);
|
|
|
|
while (rm) {
|
|
mrle = FindIndResource1(rm, theType, index);
|
|
if (mrle)
|
|
return mrle;
|
|
rm = rm->prev;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static MemRefList *FindResourceTypeAndID1(MemRsrcMap *rm, OSType theType, SInt16 theID) {
|
|
MemRefList *mref;
|
|
MemRsrcTypeList *mtyp = FindResourceType1(rm, theType);
|
|
|
|
if (mtyp) {
|
|
mref = mtyp->ref_list;
|
|
while (mref) {
|
|
if (mref->id == theID)
|
|
return mref;
|
|
mref = mref->next;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static MemRefList *FindResourceTypeAndID(OSType theType, SInt16 theID) {
|
|
MemRefList *mref;
|
|
MemRsrcMap *rm = FindResourceMap(cur_res_file);
|
|
|
|
while (rm) {
|
|
mref = FindResourceTypeAndID1(rm, theType, theID);
|
|
if (mref)
|
|
return mref;
|
|
rm = rm->prev;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static MemRefList *FindResourceTypeAndName1(MemRsrcMap *rm, OSType theType, ConstStringPtr theName) {
|
|
MemRefList *mref;
|
|
MemRsrcTypeList *mtyp;
|
|
|
|
mtyp = FindResourceType1(rm, theType);
|
|
if (mtyp) {
|
|
mref = mtyp->ref_list;
|
|
while (mref) {
|
|
if (mref->name && EqualString(mref->name, theName, 0, 0))
|
|
return mref;
|
|
mref = mref->next;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static MemRefList *FindResourceTypeAndName(OSType theType, ConstStringPtr theName) {
|
|
MemRefList *mref;
|
|
MemRsrcMap *rm = FindResourceMap(cur_res_file);
|
|
|
|
while (rm) {
|
|
mref = FindResourceTypeAndName1(rm, theType, theName);
|
|
if (mref)
|
|
return mref;
|
|
rm = rm->prev;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static MemRefList *FindResourceHandle1(MemRsrcMap *rm, Handle theResource) {
|
|
MemRefList *mrle;
|
|
MemRsrcTypeList *mtyp;
|
|
|
|
for (mtyp = rm->type_list; mtyp; mtyp = mtyp->next) {
|
|
for (mrle = mtyp->ref_list; mrle; mrle = mrle->next) {
|
|
if (mrle->hand == theResource)
|
|
return mrle;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static MemRefList *FindResourceHandle(Handle theResource) {
|
|
MemRefList *mrle;
|
|
MemRsrcMap *rm;
|
|
|
|
for (rm = FindResourceMap(cur_res_file); rm; rm = rm->prev) {
|
|
mrle = FindResourceHandle1(rm, theResource);
|
|
if (mrle)
|
|
return mrle;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int RemoveResourceHandle1(MemRsrcMap *rm, Handle theResource) {
|
|
MemRefList *mrle, *pmrle;
|
|
MemRsrcTypeList *mtyp, *pmtyp;
|
|
|
|
mtyp = rm->type_list;
|
|
pmtyp = 0;
|
|
while (mtyp) {
|
|
mrle = mtyp->ref_list;
|
|
pmrle = 0;
|
|
while (mrle) {
|
|
if (mrle->hand == theResource) {
|
|
if (pmrle)
|
|
pmrle->next = mrle->next;
|
|
else
|
|
mtyp->ref_list = mrle->next;
|
|
free(mrle);
|
|
|
|
if (!mtyp->ref_list) {
|
|
if (pmtyp)
|
|
pmtyp->next = mtyp->next;
|
|
else
|
|
rm->type_list = mtyp->next;
|
|
free(mtyp);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
pmrle = mrle;
|
|
mrle = mrle->next;
|
|
}
|
|
pmtyp = mtyp;
|
|
mtyp = mtyp->next;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int RemoveResourceHandle(Handle theResource) {
|
|
MemRsrcMap *rm;
|
|
|
|
for (rm = FindResourceMap(cur_res_file); rm; rm = rm->prev) {
|
|
if (RemoveResourceHandle1(rm, theResource))
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static SInt16 FindResourceHandleFile1(MemRsrcMap *rm, Handle theResource) {
|
|
MemRefList *mrle;
|
|
MemRsrcTypeList *mtyp;
|
|
}
|
|
|
|
static SInt16 FindResourceHandleFile(Handle theResource) {
|
|
MemRefList *mrle;
|
|
MemRsrcMap *rm;
|
|
}
|
|
|
|
void OS_AddMacResourceForkRef(int ref, const OSSpec *spec) {
|
|
ResRef *nw;
|
|
}
|
|
|
|
void OS_RemoveMacResourceForkRef(int ref) {
|
|
ResRef *prev;
|
|
ResRef *lst;
|
|
}
|
|
|
|
OSSpec *OS_GetMacResourceForkFromRef(int ref) {
|
|
ResRef *lst;
|
|
}
|
|
|
|
Boolean OS_SearchMacResourceForkList(const OSSpec *rspec, int *ref) {
|
|
ResRef *lst;
|
|
}
|
|
|
|
int OS_SetMacResourceForkCreatorAndType(int ref, OSType creator, OSType type) {
|
|
MemRsrcMap *rm;
|
|
UInt32 sz;
|
|
UInt32 buf[2];
|
|
int err;
|
|
|
|
if (!OS_GetMacResourceForkFromRef(ref)) {
|
|
sz = 8;
|
|
buf[0] = type;
|
|
buf[1] = creator;
|
|
err = OS_Seek(ref, OSSeekAbs, 0x52);
|
|
if (!err) {
|
|
err = OS_Write(ref, buf, &sz);
|
|
if (!err && sz == 8) {
|
|
err = 0;
|
|
}
|
|
}
|
|
} else {
|
|
rm = FindResourceMap(OS_RefToMac(ref));
|
|
if (!rm) {
|
|
err = 2;
|
|
} else if (rm->fork_attr & 0x80) {
|
|
err = 13;
|
|
} else {
|
|
rm->sys_data.creator[0] = (creator & 0xFF000000) >> 24;
|
|
rm->sys_data.creator[1] = (creator & 0x00FF0000) >> 16;
|
|
rm->sys_data.creator[2] = (creator & 0x0000FF00) >> 8;
|
|
rm->sys_data.creator[3] = (creator & 0x000000FF);
|
|
rm->sys_data.type[0] = (type & 0xFF000000) >> 24;
|
|
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;
|
|
err = 0;
|
|
}
|
|
}
|
|
|
|
return err;
|
|
}
|
|
|
|
int OS_GetMacResourceForkCreatorAndType(int ref, OSType *creator, OSType *type) {
|
|
MemRsrcMap *rm;
|
|
UInt32 sz;
|
|
UInt32 buf[2];
|
|
int err;
|
|
|
|
if (!OS_GetMacResourceForkFromRef(ref)) {
|
|
sz = 8;
|
|
err = OS_Seek(ref, OSSeekAbs, 0x52);
|
|
if (!err) {
|
|
err = OS_Read(ref, buf, &sz);
|
|
if (!err && sz == 8) {
|
|
err = 0;
|
|
*type = buf[0];
|
|
*creator = buf[1];
|
|
}
|
|
}
|
|
} else {
|
|
rm = FindResourceMap(OS_RefToMac(ref));
|
|
if (!rm) {
|
|
err = 2;
|
|
} else {
|
|
*creator = (rm->sys_data.creator[0] << 24) | (rm->sys_data.creator[1] << 16) | (rm->sys_data.creator[2] << 8) | rm->sys_data.creator[3];
|
|
*type = (rm->sys_data.type[0] << 24) | (rm->sys_data.type[1] << 16) | (rm->sys_data.type[2] << 8) | rm->sys_data.type[3];
|
|
err = 0;
|
|
}
|
|
}
|
|
|
|
return err;
|
|
}
|
|
|
|
void OS_CleanupMacResourceForkDir(const OSPathSpec *dir) {
|
|
OS_Rmdir(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;
|
|
|
|
// Debug shit
|
|
}
|
|
|
|
OSErr FSpOpenRF(const FSSpec *fss, SInt8 permission, SInt16 *refNum) {
|
|
Boolean create;
|
|
OSSpec rspec;
|
|
OSSpec spec;
|
|
FSSpec rfss;
|
|
int oserr;
|
|
OSErr err;
|
|
|
|
create = (permission == 1) | (permission > 1);
|
|
oserr = OS_FSSpec_To_OSSpec(fss, &spec);
|
|
if (oserr)
|
|
return OS_MacError(oserr);
|
|
|
|
oserr = OS_GetRsrcOSSpec(&spec, &rspec, create);
|
|
if (oserr)
|
|
return OS_MacError(oserr);
|
|
|
|
oserr = OS_OSSpec_To_FSSpec(&rspec, &rfss);
|
|
if (oserr)
|
|
return OS_MacError(oserr);
|
|
|
|
if (OS_Status(&rspec) && create)
|
|
HCreate(rfss.vRefNum, rfss.parID, rfss.name, 'CWIE', 'rsrc');
|
|
|
|
err = HOpen(rfss.vRefNum, rfss.parID, rfss.name, permission, refNum);
|
|
if (!err)
|
|
OS_AddMacResourceForkRef(OS_MacToRef(*refNum), &rspec);
|
|
|
|
return err;
|
|
}
|
|
|
|
OSErr HOpenRF(SInt16 vRefNum, SInt32 dirID, ConstStringPtr fileName, SInt8 permission, SInt16 *refNum) {
|
|
OSErr __err;
|
|
FSSpec fss;
|
|
|
|
__err = FSMakeFSSpec(vRefNum, dirID, fileName, &fss);
|
|
if (__err != noErr && __err != fnfErr) {
|
|
return __err;
|
|
} else {
|
|
return FSpOpenRF(&fss, permission, refNum);
|
|
}
|
|
}
|
|
|
|
OSErr InitResources() {
|
|
MemRsrcMap *map;
|
|
|
|
map = maplist;
|
|
cur_res_file = 0;
|
|
while (map) {
|
|
cur_res_file = map->refnum;
|
|
map = map->prev;
|
|
}
|
|
|
|
ResLoad = 1;
|
|
resError = noErr;
|
|
return 0;
|
|
}
|
|
|
|
OSErr ResError() {
|
|
return resError;
|
|
}
|
|
|
|
void FSpCreateResFile(const FSSpec *fss, OSType creator, OSType fileType, ScriptCode scriptTag) {
|
|
SInt16 ref;
|
|
OSSpec spec, rspec;
|
|
int oserr;
|
|
|
|
FSpCreate(fss, creator, fileType, scriptTag);
|
|
oserr = OS_FSSpec_To_OSSpec(fss, &spec);
|
|
if (oserr) {
|
|
resError = OS_MacError(oserr);
|
|
return;
|
|
}
|
|
|
|
oserr = OS_GetRsrcOSSpec(&spec, &rspec, 1);
|
|
if (oserr) {
|
|
resError = OS_MacError(oserr);
|
|
return;
|
|
}
|
|
|
|
if (OS_Status(&rspec)) {
|
|
oserr = OS_Create(&rspec, &OS_TEXTTYPE);
|
|
if (oserr) {
|
|
resError = OS_MacError(oserr);
|
|
return;
|
|
}
|
|
|
|
resError = FSpOpenRF(fss, 3, &ref);
|
|
if (!resError) {
|
|
WriteEmptyResourceFork(ref);
|
|
FSClose(ref);
|
|
}
|
|
} else {
|
|
resError = dupFNErr;
|
|
}
|
|
|
|
}
|
|
|
|
void HCreateResFile(SInt16 vRefNum, SInt32 dirID, ConstStringPtr fileName) {
|
|
OSErr __err;
|
|
FSSpec fss;
|
|
|
|
__err = FSMakeFSSpec(vRefNum, dirID, fileName, &fss);
|
|
if (__err != noErr && __err != fnfErr) {
|
|
resError = __err;
|
|
} else {
|
|
FSpCreateResFile(&fss, 'CWIE', kUnknownType, -1);
|
|
}
|
|
}
|
|
|
|
OSErr FSpOpenResFile(const FSSpec *fss, SInt8 permission) {
|
|
SInt32 size;
|
|
SInt16 ref;
|
|
|
|
if (permission != 1)
|
|
FSpCreate(fss, 'CWIE', 'TEXT', -1);
|
|
|
|
resError = FSpOpenRF(fss, (permission != 2) ? permission : 3, &ref);
|
|
if (!resError) {
|
|
GetEOF(ref, &size);
|
|
if (size == 0 && permission != 1)
|
|
WriteEmptyResourceFork(ref);
|
|
ReadResourceFork(ref, permission, 0, 0);
|
|
if (resError) {
|
|
FSClose(ref);
|
|
CloseResFile(ref);
|
|
ref = -1;
|
|
}
|
|
cur_res_file = ref;
|
|
} else {
|
|
ref = -1;
|
|
}
|
|
|
|
return ref;
|
|
}
|
|
|
|
OSErr HOpenResFile(SInt16 vRefNum, SInt32 dirID, ConstStringPtr fileName, SInt8 permission) {
|
|
OSErr __err;
|
|
FSSpec fss;
|
|
|
|
__err = FSMakeFSSpec(vRefNum, dirID, fileName, &fss);
|
|
if (__err != noErr && __err != fnfErr)
|
|
return __err;
|
|
return FSpOpenResFile(&fss, permission);
|
|
}
|
|
|
|
SInt16 CurResFile() {
|
|
return cur_res_file;
|
|
}
|
|
|
|
void UseResFile(SInt16 refNum) {
|
|
MemRsrcMap *map;
|
|
|
|
for (map = maplist; map; map = map->prev) {
|
|
if (map->refnum == refNum) {
|
|
cur_res_file = refNum;
|
|
resError = noErr;
|
|
return;
|
|
}
|
|
}
|
|
|
|
resError = resFNotFound;
|
|
}
|
|
|
|
SInt16 HomeResFile(Handle theResource) {
|
|
SInt16 refnum = FindResourceHandleFile(theResource);
|
|
resError = (refnum == -1) ? resNotFound : 0;
|
|
return refnum;
|
|
}
|
|
|
|
Handle GetResource(OSType theType, SInt16 theID) {
|
|
MemRefList *mref;
|
|
|
|
mref = FindResourceTypeAndID(theType, theID);
|
|
if (mref) {
|
|
resError = noErr;
|
|
return mref->hand;
|
|
} else {
|
|
resError = ResLoad ? resNotFound : noErr;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
Handle Get1Resource(OSType theType, SInt16 theID) {
|
|
MemRefList *mref;
|
|
MemRsrcMap *rm;
|
|
|
|
rm = FindResourceMap(cur_res_file);
|
|
if (!rm) {
|
|
resError = resFNotFound;
|
|
return 0;
|
|
}
|
|
|
|
mref = FindResourceTypeAndID1(rm, theType, theID);
|
|
if (mref) {
|
|
resError = noErr;
|
|
return mref->hand;
|
|
} else {
|
|
resError = ResLoad ? resNotFound : noErr;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
Handle GetNamedResource(OSType theType, ConstStringPtr theName) {
|
|
MemRefList *mref;
|
|
|
|
mref = FindResourceTypeAndName(theType, theName);
|
|
if (mref) {
|
|
resError = noErr;
|
|
return mref->hand;
|
|
} else {
|
|
resError = ResLoad ? resNotFound : noErr;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
Handle Get1NamedResource(OSType theType, ConstStringPtr theName) {
|
|
MemRefList *mref;
|
|
MemRsrcMap *rm;
|
|
|
|
rm = FindResourceMap(cur_res_file);
|
|
if (!rm) {
|
|
resError = resFNotFound;
|
|
return 0;
|
|
}
|
|
|
|
mref = FindResourceTypeAndName1(rm, theType, theName);
|
|
if (mref) {
|
|
resError = noErr;
|
|
return mref->hand;
|
|
} else {
|
|
resError = (ResLoad != 0) ? resNotFound : noErr;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void SetResLoad(Boolean load) {
|
|
ResLoad = load;
|
|
}
|
|
|
|
void MacEmul_LoadResource(Handle theResource) {
|
|
resError = (theResource == 0) ? nilHandleErr : 0;
|
|
}
|
|
|
|
void GetResInfo(Handle theResource, SInt16 *theID, OSType *theType, StringPtr name) {
|
|
MemRefList *mrle;
|
|
|
|
mrle = FindResourceHandle(theResource);
|
|
if (mrle) {
|
|
resError = noErr;
|
|
*theID = mrle->id;
|
|
*theType = mrle->type;
|
|
if (mrle->name)
|
|
_pstrcpy(name, mrle->name);
|
|
else
|
|
name[0] = 0;
|
|
} else {
|
|
resError = resNotFound;
|
|
}
|
|
}
|
|
|
|
void SetResInfo(Handle theResource, SInt16 theID, ConstStringPtr name) {
|
|
MemRefList *mrle;
|
|
|
|
mrle = FindResourceHandle(theResource);
|
|
if (mrle) {
|
|
resError = noErr;
|
|
if (mrle->name)
|
|
free(mrle->name);
|
|
mrle->name = malloc(name[0] + 1);
|
|
mrle->attr |= 2;
|
|
if (mrle->name)
|
|
_pstrcpy(mrle->name, name);
|
|
else
|
|
resError = memFullErr;
|
|
} else {
|
|
resError = resNotFound;
|
|
}
|
|
}
|
|
|
|
SInt16 GetResAttrs(Handle theResource) {
|
|
MemRefList *mrle;
|
|
|
|
mrle = FindResourceHandle(theResource);
|
|
if (mrle) {
|
|
resError = noErr;
|
|
return mrle->attr;
|
|
} else {
|
|
resError = resNotFound;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void SetResAttrs(Handle theResource, SInt16 attrs) {
|
|
MemRefList *mrle;
|
|
|
|
mrle = FindResourceHandle(theResource);
|
|
if (mrle) {
|
|
resError = noErr;
|
|
mrle->attr = attrs;
|
|
} else {
|
|
resError = resNotFound;
|
|
}
|
|
}
|
|
|
|
void ChangedResource(Handle theResource) {
|
|
MemRefList *mrle;
|
|
MemRsrcMap *rm;
|
|
|
|
rm = FindResourceMap(cur_res_file);
|
|
mrle = FindResourceHandle(theResource);
|
|
if (mrle) {
|
|
if (rm && (rm->fork_attr & 0x80)) {
|
|
resError = resAttrErr;
|
|
} else {
|
|
resError = noErr;
|
|
mrle->attr |= 2;
|
|
rm->fork_attr |= 0x20;
|
|
}
|
|
} else {
|
|
resError = resNotFound;
|
|
}
|
|
}
|
|
|
|
void AddResource(Handle theData, OSType theType, SInt16 theID, ConstStringPtr name) {
|
|
MemRsrcMap *rm;
|
|
MemRsrcTypeList *mtyp;
|
|
MemRefList *mrle;
|
|
StringPtr namecpy;
|
|
|
|
rm = FindResourceMap(cur_res_file);
|
|
if (rm) {
|
|
if (rm->fork_attr & 0x80) {
|
|
resError = resAttrErr;
|
|
return;
|
|
}
|
|
|
|
resError = noErr;
|
|
mtyp = FindResourceType1(rm, theType);
|
|
if (!mtyp) {
|
|
mtyp = NewTypeListEntry(&rm->type_list, theType, 0, 0);
|
|
if (!mtyp) {
|
|
resError = memFullErr;
|
|
return;
|
|
}
|
|
rm->fork_attr |= 0x20;
|
|
}
|
|
if (!theData || FindResourceHandle(theData)) {
|
|
resError = addResFailed;
|
|
return;
|
|
}
|
|
|
|
if (name && name[0]) {
|
|
namecpy = malloc(name[0] + 1);
|
|
_pstrcpy(namecpy, name);
|
|
} else {
|
|
namecpy = 0;
|
|
}
|
|
|
|
mrle = NewRefListEntry(&mtyp->ref_list, theID, theType, namecpy, 2, theData);
|
|
if (!mrle) {
|
|
resError = memFullErr;
|
|
return;
|
|
}
|
|
|
|
rm->fork_attr |= 0x20;
|
|
} else {
|
|
resError = resFNotFound;
|
|
}
|
|
}
|
|
|
|
void UpdateResFile(SInt16 refnum) {
|
|
WriteResourceFork(refnum);
|
|
}
|
|
|
|
void WriteResource(Handle theResource) {
|
|
resError = noErr;
|
|
}
|
|
|
|
void SetResPurge(Boolean install) {
|
|
}
|
|
|
|
SInt16 CountResources(OSType theType) {
|
|
return CountResourceType(theType);
|
|
}
|
|
|
|
SInt16 Count1Resources(OSType theType) {
|
|
MemRsrcMap *rm;
|
|
|
|
rm = FindResourceMap(cur_res_file);
|
|
if (rm) {
|
|
resError = noErr;
|
|
return CountResourceType1(rm, theType);
|
|
} else {
|
|
resError = resFNotFound;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
Handle GetIndResource(OSType theType, SInt16 index) {
|
|
MemRefList *mrle;
|
|
|
|
mrle = FindIndResource(theType, index);
|
|
resError = mrle ? 0 : resNotFound;
|
|
return mrle->hand;
|
|
}
|
|
|
|
Handle Get1IndResource(OSType theType, SInt16 index) {
|
|
MemRefList *mrle;
|
|
MemRsrcMap *rm;
|
|
|
|
rm = FindResourceMap(cur_res_file);
|
|
if (rm) {
|
|
mrle = FindIndResource1(rm, theType, index);
|
|
if (mrle) {
|
|
resError = noErr;
|
|
return mrle->hand;
|
|
} else {
|
|
resError = resNotFound;
|
|
return 0;
|
|
}
|
|
} else {
|
|
resError = resFNotFound;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
SInt16 Count1Types() {
|
|
SInt16 count;
|
|
MemRsrcTypeList *rtl;
|
|
MemRsrcMap *rm;
|
|
|
|
count = 0;
|
|
rm = FindResourceMap(cur_res_file);
|
|
if (rm) {
|
|
rtl = rm->type_list;
|
|
while (rtl) {
|
|
rtl = rtl->next;
|
|
++count;
|
|
}
|
|
} else {
|
|
resError = resFNotFound;
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
void Get1IndType(OSType *theType, SInt16 index) {
|
|
SInt16 count;
|
|
MemRsrcTypeList *rtl;
|
|
MemRsrcMap *rm;
|
|
|
|
count = 1;
|
|
rm = FindResourceMap(cur_res_file);
|
|
if (rm) {
|
|
rtl = rm->type_list;
|
|
while (rtl && count < index) {
|
|
rtl = rtl->next;
|
|
++count;
|
|
}
|
|
if (rtl)
|
|
*theType = rtl->type;
|
|
else
|
|
resError = inputOutOfBounds;
|
|
} else {
|
|
resError = resFNotFound;
|
|
}
|
|
}
|
|
|
|
void ReleaseResource(Handle theResource) {
|
|
resError = noErr;
|
|
}
|
|
|
|
void DetachResource(Handle theResource) {
|
|
SInt32 ns;
|
|
MemRefList *mrle;
|
|
|
|
mrle = FindResourceHandle(theResource);
|
|
if (mrle) {
|
|
ns = GetHandleSize(theResource);
|
|
mrle->hand = NewHandle(ns);
|
|
if (!mrle->hand) {
|
|
resError = memFullErr;
|
|
} else {
|
|
HLock(mrle->hand);
|
|
HLock(theResource);
|
|
memcpy(*mrle->hand, *theResource, ns);
|
|
HUnlock(theResource);
|
|
HUnlock(mrle->hand);
|
|
resError = noErr;
|
|
}
|
|
} else {
|
|
resError = resNotFound;
|
|
}
|
|
}
|
|
|
|
void RemoveResource(Handle theResource) {
|
|
resError = RemoveResourceHandle(theResource) ? 0 : rmvResFailed;
|
|
}
|
|
|
|
void CloseResFile(SInt16 refNum) {
|
|
MemRsrcMap *rm = FindResourceMap(refNum);
|
|
|
|
if (rm && refNum != -1) {
|
|
WriteResourceFork(refNum);
|
|
DeleteResources(refNum);
|
|
FSClose(refNum);
|
|
}
|
|
|
|
cur_res_file = maplist ? maplist->refnum : 0;
|
|
}
|
|
|
|
SInt16 GetResFileAttrs(SInt16) {
|
|
MemRsrcMap *rm = FindResourceMap(cur_res_file);
|
|
|
|
if (rm) {
|
|
resError = 0;
|
|
return rm->fork_attr;
|
|
} else {
|
|
resError = resFNotFound;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
Boolean LMGetResLoad() {
|
|
return 1;
|
|
}
|