getfinfo / setfinfo

This commit is contained in:
Kelvin Sherlock 2013-02-28 18:58:37 -05:00
parent 233c625cb0
commit 7578fbce73

View File

@ -119,12 +119,20 @@ namespace OS {
{ {
// FSMakeFSSpec(vRefNum: Integer; dirID: LongInt; fileName: Str255; VAR spec: FSSpec): OSErr; // FSMakeFSSpec(vRefNum: Integer; dirID: LongInt; fileName: Str255; VAR spec: FSSpec): OSErr;
/*
* See Chapter 2, File Manager / Using the File Manager, 2-35
*
*
*/
uint16_t vRefNum; uint16_t vRefNum;
uint32_t dirID; uint32_t dirID;
uint32_t fileName; uint32_t fileName;
uint32_t spec; uint32_t spec;
StackFrame<14>(vRefNum, dirID, fileName, spec); StackFrame<14>(vRefNum, dirID, fileName, spec);
std::string sname = ToolBox::ReadPString(fileName, true); std::string sname = ToolBox::ReadPString(fileName, true);
@ -149,6 +157,8 @@ namespace OS {
path.assign(cp); path.assign(cp);
// if sname is null then the target is the default directory...
// so this should be ok.
int pos = path.find_last_of('/'); int pos = path.find_last_of('/');
if (pos == path.npos) if (pos == path.npos)
@ -182,6 +192,99 @@ namespace OS {
return 0; return 0;
} }
uint16_t FSpGetFInfo()
{
// FSpGetFInfo (spec: FSSpec; VAR fndrInfo: FInfo): OSErr;
uint32_t spec;
uint32_t finderInfo;
StackFrame<8>(spec, finderInfo);
int parentID = memoryReadLong(spec + 2);
std::string leaf = ToolBox::ReadPString(spec + 6, false);
std::string path = FSSpecManager::pathForID(parentID);
path += leaf;
Log(" FSpGetFInfo(%s, %08x)\n", path.c_str(), finderInfo);
// todo -- move to separate function? used in multiple places.
uint8_t buffer[32];
std::memset(buffer, 0, sizeof(buffer));
int rv;
rv = ::getxattr(path.c_str(), XATTR_FINDERINFO_NAME, buffer, 32, 0, 0);
if (rv < 0)
{
switch (errno)
{
case ENOENT:
case EACCES:
return errno_to_oserr(errno);
}
}
// override for source files.
if (IsTextFile(path))
{
std::memcpy(buffer, "TEXTMPS ", 8);
}
std::memmove(memoryPointer(finderInfo), buffer, 16);
return 0;
}
uint16_t FSpSetFInfo()
{
// FSpSetFInfo (spec: FSSpec; VAR fndrInfo: FInfo): OSErr;
uint32_t spec;
uint32_t finderInfo;
StackFrame<8>(spec, finderInfo);
int parentID = memoryReadLong(spec + 2);
std::string leaf = ToolBox::ReadPString(spec + 6, false);
std::string path = FSSpecManager::pathForID(parentID);
path += leaf;
Log(" FSpSetFInfo(%s, %08x)\n", path.c_str(), finderInfo);
// todo -- move to separate function? used in multiple places.
uint8_t buffer[32];
std::memset(buffer, 0, sizeof(buffer));
int rv;
rv = ::getxattr(path.c_str(), XATTR_FINDERINFO_NAME, buffer, 32, 0, 0);
if (rv < 0)
{
switch (errno)
{
case ENOENT:
case EACCES:
return errno_to_oserr(errno);
}
}
std::memmove(buffer, memoryPointer(finderInfo), 16);
rv = ::setxattr(path.c_str(), XATTR_FINDERINFO_NAME, buffer, 32, 0, 0);
return rv < 0 ? errno_to_oserr(errno) : 0;
}
uint16_t HighLevelHFSDispatch(uint16_t trap) uint16_t HighLevelHFSDispatch(uint16_t trap)
{ {
@ -196,6 +299,14 @@ namespace OS {
return FSMakeFSSpec(); return FSMakeFSSpec();
break; break;
case 0x0007:
return FSpGetFInfo();
break;
case 0x0008:
return FSpSetFInfo();
break;
default: default:
fprintf(stderr, "selector %04x not yet supported\n", selector); fprintf(stderr, "selector %04x not yet supported\n", selector);
exit(1); exit(1);