From 7578fbce7388229c6364a4ebb16f55c8ea9ad471 Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Thu, 28 Feb 2013 18:58:37 -0500 Subject: [PATCH] getfinfo / setfinfo --- toolbox/os_highlevel.cpp | 111 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) diff --git a/toolbox/os_highlevel.cpp b/toolbox/os_highlevel.cpp index 1df3ad1..b8a857d 100644 --- a/toolbox/os_highlevel.cpp +++ b/toolbox/os_highlevel.cpp @@ -119,12 +119,20 @@ namespace OS { { // 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; uint32_t dirID; uint32_t fileName; uint32_t spec; + + StackFrame<14>(vRefNum, dirID, fileName, spec); std::string sname = ToolBox::ReadPString(fileName, true); @@ -149,6 +157,8 @@ namespace OS { 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('/'); if (pos == path.npos) @@ -182,6 +192,99 @@ namespace OS { 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) { @@ -196,6 +299,14 @@ namespace OS { return FSMakeFSSpec(); break; + case 0x0007: + return FSpGetFInfo(); + break; + + case 0x0008: + return FSpSetFInfo(); + break; + default: fprintf(stderr, "selector %04x not yet supported\n", selector); exit(1);