fix CreateRes, add HCreateRes

This commit is contained in:
Kelvin Sherlock 2015-01-17 18:33:34 -05:00
parent acea989367
commit 172da3e250
5 changed files with 188 additions and 16 deletions

View File

@ -22,7 +22,7 @@ LDFLAGS = -w -c 'MPS ' -t MPST \
SCFLAGS = -p
TARGETS = test_new_handle test_new_handle_2 test_new_pointer test_volumes
TARGETS = test_new_handle test_new_handle_2 test_new_pointer test_volumes test_createresfile
all : $(TARGETS)

132
test/test_createresfile.c Normal file
View File

@ -0,0 +1,132 @@
#include <Resources.h>
#include <Files.h>
#include <stdio.h>
#include <stdlib.h>
/*
* Test the three (thanks, Apple) ways to create a resource file.
*
*/
ConstStr255Param fname = (ConstStr255Param)"\pxxx-test-resource-xxx";
void test_fspcreateresfile(void)
{
OSErr err;
FSSpec spec;
err = FSMakeFSSpec(0, 0, fname, &spec);
if (err) {
fprintf(stderr, "FSMakeFSSpec failed: %d\n", err);
exit(3);
}
FSpDelete(&spec);
FSpCreateResFile(&spec, 'TEST', 'BINA', 0);
if ( (err = ResError()) != 0) {
fprintf(stderr, "FSpCreateResFile failed (File does not exist): %d\n", err);
exit(1);
}
// Verify it doesn't fail if the file/fork already exist.
FSpCreateResFile(&spec, 'TEST', 'BINA', 0);
if ( (err = ResError()) != 0) {
fprintf(stderr, "FSpCreateResFile (File/Fork exist) failed: %d\n", err);
exit(2);
}
// Verify it doesn't fail if the file exists w/o a resource fork.
FSpDelete(&spec);
FSpCreate(&spec, 'TEST', 'BINA', 0);
FSpCreateResFile(&spec, 'TEST', 'BINA', 0);
if ( (err = ResError()) != 0) {
fprintf(stderr, "FSpCreateResFile (File exists) failed: %d\n", err);
exit(2);
}
FSpDelete(&spec);
}
void test_hcreateresfile(void)
{
OSErr err;
// will 0, 0 work on real macos?
HDelete(0, 0, fname);
HCreateResFile(0, 0, fname);
if ( (err = ResError()) != 0) {
fprintf(stderr, "HCreateResFile failed (File does not exist): %d\n", err);
exit(1);
}
// Verify it doesn't fail if the file/fork already exist.
HCreateResFile(0, 0, fname);
if ( (err = ResError()) != 0) {
fprintf(stderr, "HCreateResFile (File/Fork exist) failed: %d\n", err);
exit(2);
}
// Verify it doesn't fail if the file exists w/o a resource fork.
HDelete(0, 0, fname);
HCreate(0, 0, fname, 'TEST', 'BINA');
HCreateResFile(0, 0, fname);
if ( (err = ResError()) != 0) {
fprintf(stderr, "HCreateResFile (File exists) failed: %d\n", err);
exit(2);
}
HDelete(0, 0, fname);
}
void test_createresfile(void)
{
OSErr err;
FSDelete(fname, 0);
CreateResFile(fname);
if ( (err = ResError()) != 0) {
fprintf(stderr, "CreateResFile failed (File does not exist): %d\n", err);
exit(1);
}
// Verify it does fail if the file/fork already exist.
CreateResFile(fname);
if ( (err = ResError()) != dupFNErr) {
fprintf(stderr, "CreateResFile (File/Fork exist) failed: %d\n", err);
exit(2);
}
// Verify it doesn't fail if the file exists w/o a resource fork.
FSDelete(fname, 0);
Create(fname, 0, 'TEST', 'BINA');
CreateResFile(fname);
if ( (err = ResError()) != 0) {
fprintf(stderr, "CreateResFile (File exists) failed: %d\n", err);
exit(2);
}
FSDelete(fname, 0);
}
int main(int argc, char **argv)
{
(void)argc;
(void)argv;
test_createresfile();
test_hcreateresfile();
test_fspcreateresfile();
return 0;
}

View File

@ -418,7 +418,7 @@ namespace RM
}
tool_return<void> CreateResFile(const std::string &path)
tool_return<void> CreateResFile(const std::string &path, uint32_t creator = 0, uint32_t fileType = 0)
{
if (path.empty()) return MacOS::paramErr;
@ -427,10 +427,7 @@ namespace RM
OSErr error;
int fd;
error = ::FSPathMakeRef((const UInt8 *)path.c_str(), &ref, NULL);
if (error != noErr)
return macos_error(error);
// FSPathMakeRef only works with existing files.
// FSCreateResourceFork only works with existing files.
fd = ::open(path.c_str(), O_CREAT | O_EXCL | O_RDWR, 0666);
@ -438,7 +435,18 @@ namespace RM
{
if (errno != EEXIST) return macos_error_from_errno();
}
if (fd >= 0) close(fd);
else
{
if (creator || fileType)
OS::Internal::SetFinderInfo(path, fileType, creator);
close(fd);
}
error = ::FSPathMakeRef((const UInt8 *)path.c_str(), &ref, NULL);
if (error != noErr)
return macos_error(error);
HFSUniStr255 fork = {0,{0}};
@ -447,6 +455,11 @@ namespace RM
error = ::FSCreateResourceFork(&ref, fork.length, fork.unicode, 0);
// CreateResFile returns an error if the fork exists, HCreateResFile
// and FSpCreateResFile do not.
if (error == errFSForkExists) error = MacOS::dupFNErr;
return macos_error(error);
}
@ -476,7 +489,35 @@ namespace RM
auto rv = CreateResFile(sname);
return SetResError(rv.error() == errFSForkExists ? 0 : rv.error());
return SetResError(rv.error());
}
uint16_t HCreateResFile(uint16_t trap)
{
// PROCEDURE HCreateResFile (vRefNum: Integer; dirID: LongInt;
// fileName: Str255);
uint16_t vRefNum;
uint32_t dirID;
uint32_t fileName;
StackFrame<10>(vRefNum, dirID, fileName);
std::string sname = ToolBox::ReadPString(fileName, true);
Log("%04x HCreateResFile(%04x, %08x, %s)\n",
trap, vRefNum, dirID, sname.c_str());
sname = OS::FSSpecManager::ExpandPath(sname, dirID);
if (sname.empty())
{
return SetResError(MacOS::dirNFErr);
}
auto rv = CreateResFile(sname);
return SetResError(rv.error() == MacOS::dupFNErr ? 0 : rv.error());
}
@ -512,15 +553,9 @@ namespace RM
return SetResError(MacOS::dirNFErr);
}
auto rv = CreateResFile(sname);
// returns errFSForkExists if fork already exists.
// therefore, if no error, set the ftype/ctype.
if (rv.error() == 0)
{
OS::Internal::SetFinderInfo(sname, fileType, creator);
}
auto rv = CreateResFile(sname, creator, fileType);
return SetResError(rv.error() == errFSForkExists ? 0 : rv.error());
return SetResError(rv.error() == MacOS::dupFNErr ? 0 : rv.error());
}

View File

@ -33,6 +33,7 @@ namespace RM
uint16_t UseResFile(uint16_t trap);
uint16_t CreateResFile(uint16_t trap);
uint16_t HCreateResFile(uint16_t trap);
uint16_t Count1Resources(uint16_t trap);
uint16_t UpdateResFile(uint16_t trap);

View File

@ -434,6 +434,10 @@ namespace ToolBox {
d0 = RM::HOpenResFile(trap);
break;
case 0xa81b:
d0 = RM::HCreateResFile(trap);
break;
case 0xa81c:
d0 = RM::Count1Types(trap);
break;