FspCreateResFile

This commit is contained in:
Kelvin Sherlock 2014-12-21 22:30:04 -05:00
parent 91a0da2e0a
commit 30d6b05adc
3 changed files with 99 additions and 1 deletions

View File

@ -321,6 +321,9 @@ namespace OS {
case 0x000d:
return RM::FSpOpenResFile();
case 0x000e:
return RM::FSpCreateResFile();
default:
fprintf(stderr, "HighLevelHFSDispatch selector %04x not yet supported\n", selector);
exit(1);

View File

@ -43,7 +43,7 @@
#include <macos/sysequ.h>
#include <macos/errors.h>
#include <macos/tool_return.h>
#include <macos/tool_return.h>
#include "stackframe.h"
#include "fs_spec.h"
@ -54,6 +54,7 @@ using namespace ToolBox;
using MacOS::tool_return;
using MacOS::macos_error_from_errno;
using MacOS::macos_error;
namespace
{
@ -404,6 +405,39 @@ namespace RM
return SetResError(::ResError());
}
tool_return<void> CreateResFile(const std::string &path)
{
if (path.empty()) return MacOS::paramErr;
FSRef ref;
OSErr error;
int fd;
error = ::FSPathMakeRef((const UInt8 *)path.c_str(), &ref, NULL);
if (error != noErr)
return macos_error(error);
// FSCreateResourceFork only works with existing files.
fd = ::open(path.c_str(), O_CREAT | O_EXCL | O_RDWR, 0666);
if (fd < 0)
{
if (errno != EEXIST) return macos_error_from_errno();
}
if (fd >= 0) close(fd);
HFSUniStr255 fork = {0,{0}};
::FSGetResourceForkName(&fork);
error = ::FSCreateResourceFork(&ref, fork.length, fork.unicode, 0);
return macos_error(error);
}
uint16_t CreateResFile(uint16_t trap)
{
// PROCEDURE CreateResFile (fileName: Str255);
@ -459,6 +493,65 @@ namespace RM
}
uint16_t FSpCreateResFile(void)
{
// PROCEDURE FSpCreateResFile (spec: FSSpec; creator, fileType: OSType; scriptTag: ScriptCode);
// creates the file, if necessary.
uint32_t sp;
uint32_t spec;
uint32_t creator;
uint32_t fileType;
uint16_t scriptTag;
sp = StackFrame<14>(spec, creator, fileType, scriptTag);
int parentID = memoryReadLong(spec + 2);
std::string sname = ToolBox::ReadPString(spec + 6, false);
Log(" FSpCreateResFile(%s, %08x ('%s'), %08x ('%s'), %02x)\n",
sname.c_str(),
creator, ToolBox::TypeToString(creator).c_str(),
fileType, ToolBox::TypeToString(fileType).c_str(),
scriptTag);
sname = OS::FSSpecManager::ExpandPath(sname, parentID);
if (sname.empty())
{
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)
{
char buffer[32];
std::memset(buffer, 0, sizeof(buffer));
buffer[0] = fileType >> 24;
buffer[1] = fileType >> 16;
buffer[2] = fileType >> 8;
buffer[3] = fileType >> 0;
buffer[4] = creator >> 24;
buffer[5] = creator >> 16;
buffer[6] = creator >> 8;
buffer[7] = creator >> 0;
std::memcpy(buffer+4, &creator, 4);
OS::Internal::SetFinderInfo(sname, buffer, false);
}
return SetResError(rv.error() == errFSForkExists ? 0 : rv.error());
}
tool_return<int16_t> OpenResCommon(const std::string &path, uint16_t permission = 0)
{
OSErr error;
@ -576,6 +669,7 @@ namespace RM
}
uint16_t OpenRFPerm(uint16_t trap)
{
// FUNCTION OpenRFPerm (fileName: Str255; vRefNum: Integer;

View File

@ -58,6 +58,7 @@ namespace RM
uint16_t FSpOpenResFile(void);
uint16_t FSpCreateResFile(void);
}