···19192020#include "ComponentManager.h"
2121#include <CoreServices/MacErrors.h>
2222+#include <CoreServices/Resources.h>
2323+2424+// Some clues about how this work can be found here:
2525+// https://vintageapple.org/develop/pdf/develop-12_9212_December_1992.pdf
22262327ComponentManager* ComponentManager::instance()
2428{
···11+/*
22+This file is part of Darling.
33+44+Copyright (C) 2020 Lubos Dolezel
55+66+Darling is free software: you can redistribute it and/or modify
77+it under the terms of the GNU General Public License as published by
88+the Free Software Foundation, either version 3 of the License, or
99+(at your option) any later version.
1010+1111+Darling is distributed in the hope that it will be useful,
1212+but WITHOUT ANY WARRANTY; without even the implied warranty of
1313+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1414+GNU General Public License for more details.
1515+1616+You should have received a copy of the GNU General Public License
1717+along with Darling. If not, see <http://www.gnu.org/licenses/>.
1818+*/
1919+120#include "Components.h"
221#include <CoreServices/MacErrors.h>
322#include "ComponentManager.h"
···7392 ComponentManager::instance()->setStorage(aComponentInstance, theStorage);
7493}
75949595+OSErr OpenAComponentResFile(Component aComponent, ResFileRefNum* resRef)
9696+{
9797+ return kResFileNotOpened;
9898+}
+28-145
src/frameworks/CoreServices/FileManager.cpp
···11/*
22This file is part of Darling.
3344-Copyright (C) 2012-2013 Lubos Dolezel
44+Copyright (C) 2012-2020 Lubos Dolezel
5566Darling is free software: you can redistribute it and/or modify
77it under the terms of the GNU General Public License as published by
···1717along with Darling. If not, see <http://www.gnu.org/licenses/>.
1818*/
19192020-#include "FileManager.h"
2020+#include <CoreServices/FileManager.h>
2121#include <cstdlib>
2222#include <string>
2323#include <cstring>
···3838#include <vector>
3939#include "DateTimeUtils.h"
4040#include <errno.h>
4141+#include <ext/file_handle.h>
41424243#define STUB() // TODO
43444444-// Doesn't resolve the last symlink
4545-// Mallocates a new buffer
4646-static char* realpath_ns(const char* path);
4747-/*static*/ bool FSRefMakePath(const FSRef* ref, std::string& out);
4848-static bool FSRefParamMakePath(const FSRefParam* param, std::string& out);
4945// Is the current user member of the specified group?
5046static bool hasgid(gid_t gid);
51475252-static bool string_endsWith(const std::string& str, const std::string& what)
5353-{
5454- if (str.size() < what.size())
5555- return false;
5656- else
5757- return str.compare(str.size()-what.size(), what.size(), what) == 0;
5858-}
5959-6060-static std::vector<std::string> string_explode(const std::string& str, char delim, bool keepEmpty)
6161-{
6262- std::vector<std::string> rv;
6363- size_t start = 0, end;
6464-6565- do
6666- {
6767- std::string substr;
6868-6969- end = str.find(delim, start);
7070- substr = str.substr(start, (end != std::string::npos) ? end-start : std::string::npos);
7171-7272- if (keepEmpty || !substr.empty())
7373- rv.push_back(substr);
7474-7575- start = end+1;
7676- }
7777- while (end != std::string::npos);
7878-7979- return rv;
8080-}
8181-8248OSStatus FSPathMakeRef(const uint8_t* path, FSRef* fsref, Boolean* isDirectory)
8349{
8450 return FSPathMakeRefWithOptions(path, kFSPathMakeRefDoNotFollowLeafSymlink, fsref, isDirectory);
···8955 if (!path || !fsref)
9056 return paramErr;
91579292- std::string fullPath;
9393- char* rpath;
9494-5858+ int flags = 1;
9559 if (options & kFSPathMakeRefDoNotFollowLeafSymlink)
9696- rpath = realpath_ns(reinterpret_cast<const char*>(path));
9797- else
9898- rpath = realpath(reinterpret_cast<const char*>(path), nullptr);
6060+ flags = 0;
9961100100- if (!rpath)
6262+ int err = sys_name_to_handle((const char*) path, (RefData*) fsref, flags);
6363+ if (err != 0)
10164 return fnfErr;
102102- if (std::count(rpath, rpath+strlen(rpath), '/') > FSRef_MAX_DEPTH)
103103- {
104104- free(rpath);
105105- return unimpErr;
106106- }
10765108108- fullPath = rpath;
109109- free(rpath);
110110-111111- memset(fsref, 0, sizeof(*fsref));
112112-113113- if (fullPath == "/")
6666+ if (isDirectory)
11467 {
115115- if (isDirectory)
116116- *isDirectory = true;
117117- return noErr;
118118- }
6868+ struct stat st;
11969120120- std::vector<std::string> components = string_explode(fullPath, '/', false);
121121- std::string position = "/";
122122- size_t pos;
7070+ if (options & kFSPathMakeRefDoNotFollowLeafSymlink)
7171+ err = lstat((const char*) path, &st);
7272+ else
7373+ err = stat((const char*) path, &st);
12374124124- for (size_t pos = 0; pos < components.size(); pos++)
125125- {
126126- bool found = false;
127127- struct dirent* ent;
128128-129129- DIR* dir = opendir(position.c_str());
130130- if (!dir)
131131- return makeOSStatus(errno);
132132-133133- while ((ent = readdir(dir)))
134134- {
135135- if (components[pos] == ent->d_name)
136136- {
137137- found = true;
138138- fsref->inodes[pos] = ent->d_ino;
139139-140140- if (pos+1 == components.size() && isDirectory != nullptr)
141141- *isDirectory = ent->d_type == DT_DIR;
142142- break;
143143- }
144144- }
145145-146146- closedir(dir);
147147-148148- if (!found)
149149- return fnfErr;
150150-151151- if (!string_endsWith(position, "/"))
152152- position += '/';
153153- position += components[pos];
154154-155155- pos++;
7575+ if (err == 0)
7676+ *isDirectory = S_ISDIR(st.st_mode);
7777+ else
7878+ *isDirectory = 0;
15679 }
1578015881 return noErr;
15982}
16083161161-char* realpath_ns(const char* path)
162162-{
163163- char *dup1, *dup2;
164164- char *dname, *bname;
165165- char *real, *complete;
166166-167167- dup1 = strdup(path);
168168- dup2 = strdup(path);
169169- dname = dirname(dup1);
170170- bname = basename(dup2);
171171-172172- real = realpath(dname, nullptr);
173173- complete = (char*) malloc(strlen(real) + strlen(bname) + 2);
174174-175175- strcpy(complete, real);
176176- if (strrchr(complete, '/') != complete+strlen(complete)-1)
177177- strcat(complete, "/");
178178- strcat(complete, bname);
179179-180180- free(real);
181181- free(dup1);
182182- free(dup2);
183183-184184- return complete;
185185-}
186186-18784bool FSRefMakePath(const FSRef* fsref, std::string& out)
18885{
189189- out = '/';
190190- for (int i = 0; i < FSRef_MAX_DEPTH && fsref->inodes[i] != 0; i++)
191191- {
192192- ino_t inode = fsref->inodes[i];
193193- DIR* dir = opendir(out.c_str());
194194- struct dirent* ent;
195195- bool found = false;
8686+ char name[4096];
8787+ int ret = sys_handle_to_name((RefData*) fsref, name);
8888+ if (ret != 0)
8989+ return false;
19690197197- while ((ent = readdir(dir)))
198198- {
199199- if (strcmp(ent->d_name, "..") == 0 || strcmp(ent->d_name, ".") == 0)
200200- continue;
201201- if (ent->d_ino == inode)
202202- {
203203- found = true;
204204- if (!string_endsWith(out, "/"))
205205- out += '/';
206206- out += ent->d_name;
207207- }
208208- }
209209-210210- closedir(dir);
211211-212212- if (!found)
213213- return false;
214214- }
9191+ out = name;
21592 return true;
21693}
21794···279156280157 if (parentDir)
281158 {
159159+ /*
282160 memcpy(parentDir, ref, sizeof(FSRef));
283161 ino_t* last = std::find(parentDir->inodes, parentDir->inodes+FSRef_MAX_DEPTH, 0);
284162285163 if (last != parentDir->inodes)
286164 *(last-1) = 0;
165165+ */
166166+ // TODO
287167 }
288168289169 if (infoOut && infoBits != kFSCatInfoNone)
···303183304184 if (infoBits & (kFSCatInfoParentDirID|kFSCatInfoNodeID))
305185 {
186186+ /*
306187 if (infoBits & kFSCatInfoNodeID)
307188 infoOut->nodeID = ref->inodes[0];
308189 for (int i = FSRef_MAX_DEPTH-1; i > 0; i--)
···315196 if (infoBits & kFSCatInfoNodeID)
316197 infoOut->nodeID = ref->inodes[i];
317198 }
199199+ */
200200+ // TODO
318201 }
319202320203 if (infoBits & kFSCatInfoDataSizes)
-245
src/frameworks/CoreServices/FileManager.h
···11-/*
22-This file is part of Darling.
33-44-Copyright (C) 2012-2013 Lubos Dolezel
55-66-Darling is free software: you can redistribute it and/or modify
77-it under the terms of the GNU General Public License as published by
88-the Free Software Foundation, either version 3 of the License, or
99-(at your option) any later version.
1010-1111-Darling is distributed in the hope that it will be useful,
1212-but WITHOUT ANY WARRANTY; without even the implied warranty of
1313-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1414-GNU General Public License for more details.
1515-1616-You should have received a copy of the GNU General Public License
1717-along with Darling. If not, see <http://www.gnu.org/licenses/>.
1818-*/
1919-2020-2121-#ifndef FILEMANAGER_H
2222-#define FILEMANAGER_H
2323-#include <stdint.h>
2424-#include <dirent.h>
2525-#include "MacErrors.h"
2626-#include "DateTimeUtils.h"
2727-#include "MacTypes.h"
2828-#include <CoreFoundation/CFURL.h>
2929-3030-#ifdef __cplusplus
3131-extern "C" {
3232-#endif
3333-3434-#define FSRef_MAX_DEPTH (80 / sizeof(ino_t))
3535-3636-typedef struct FSRef
3737-{
3838- union
3939- {
4040- uint8_t hidden[80];
4141-4242- // Inode numbers leading to the file in the directory structure
4343- //
4444- // EXAMPLES:
4545- // All zeroes: /
4646- // sequence 1,2,0: [dir with inode 1]/[dir or file with inode 2]
4747- ino_t inodes[FSRef_MAX_DEPTH];
4848- };
4949-} FSRef;
5050-typedef struct FSRef* FSRefPtr;
5151-typedef struct FSRef FSRef;
5252-5353-struct HFSUniStr255
5454-{
5555- uint16_t length;
5656- uint16_t unicode[255];
5757-};
5858-struct FSSpec;
5959-6060-typedef struct FSSpec* FSSpecPtr;
6161-6262-struct FSPermissionInfo
6363-{
6464- uint32_t userID, groupID; // uid, gid
6565- uint8_t reserved1;
6666- uint8_t userAccess; // mode for the current user
6767- uint16_t mode; // mode
6868- uint32_t reserved2;
6969-};
7070-7171-struct FSCatalogInfo
7272-{
7373- uint16_t nodeFlags;
7474- int16_t volume;
7575- uint32_t parentDirID;
7676- uint32_t nodeID;
7777- uint8_t sharingFlags;
7878- uint8_t userPrivileges;
7979- uint8_t reserved1;
8080- uint8_t reserved2;
8181- struct UTCDateTime createDate;
8282- struct UTCDateTime contentModDate;
8383- struct UTCDateTime attributeModDate;
8484- struct UTCDateTime accessDate;
8585- struct UTCDateTime backupDate;
8686-8787- union
8888- {
8989- uint32_t permissions[4];
9090- struct FSPermissionInfo fsPermissionInfo;
9191- };
9292-9393- uint8_t finderInfo[16];
9494- uint8_t extFinderInfo[16];
9595- uint64_t dataLogicalSize;
9696- uint64_t dataPhysicalSize;
9797- uint64_t rsrcLogicalSize;
9898- uint64_t rsrcPhysicalSize;
9999- uint32_t valence; // file count within a directory
100100- uint32_t textEncodingHint;
101101-};
102102-103103-typedef void* IOCompletionUPP;
104104-typedef void* QElemPtr;
105105-typedef uint16_t FSAllocationFlags;
106106-typedef uint32_t FSCatalogInfoBitmap;
107107-typedef unsigned long UniCharCount;
108108-typedef UInt32 TextEncoding;
109109-110110-struct FSRefParam
111111-{
112112- QElemPtr qLink;
113113- short qType;
114114- short ioTrap;
115115- Ptr ioCmdAddr;
116116- IOCompletionUPP ioCompletion;
117117- volatile OSErr ioResult;
118118- const Str255* ioNamePtr;
119119- short ioVRefNum;
120120- SInt16 reserved1;
121121- UInt8 reserved2;
122122- UInt8 reserved3;
123123- const FSRefPtr ref;
124124- FSCatalogInfoBitmap whichInfo;
125125- struct FSCatalogInfo* catInfo;
126126- UniCharCount nameLength;
127127- const UniChar* name;
128128- long ioDirID;
129129- FSSpecPtr spec;
130130- FSRefPtr parentRef;
131131- FSRefPtr newRef;
132132- TextEncoding textEncodingHint;
133133- struct HFSUniStr255* outName;
134134-};
135135-136136-struct CatPositionRec
137137-{
138138- long initialize;
139139- short priv[6];
140140-};
141141-142142-struct FSForkIOParam
143143-{
144144- QElemPtr qLink;
145145- short qType;
146146- short ioTrap;
147147- Ptr ioCmdAddr;
148148- IOCompletionUPP ioCompletion;
149149- volatile OSErr ioResult;
150150- void * reserved1;
151151- SInt16 reserved2;
152152- SInt16 forkRefNum;
153153- UInt8 reserved3;
154154- SInt8 permissions;
155155- const FSRefPtr ref;
156156- Ptr buffer;
157157- UInt32 requestCount;
158158- UInt32 actualCount;
159159- UInt16 positionMode;
160160- SInt64 positionOffset;
161161- FSAllocationFlags allocationFlags;
162162- UInt64 allocationAmount;
163163- UniCharCount forkNameLength;
164164- const UniChar * forkName;
165165- struct CatPositionRec forkIterator;
166166- struct HFSUniStr255* outForkName;
167167-};
168168-169169-enum
170170-{
171171- kFSPathMakeRefDefaultOptions = 0,
172172- kFSPathMakeRefDoNotFollowLeafSymlink = 1
173173-};
174174-175175-enum
176176-{
177177- kFSCatInfoNone = 0x0,
178178- kFSCatInfoTextEncoding = 0x1,
179179- kFSCatInfoNodeFlags = 0x2,
180180- kFSCatInfoVolume = 0x4,
181181- kFSCatInfoParentDirID = 0x8,
182182- kFSCatInfoNodeID = 0x10,
183183- kFSCatInfoCreateDate = 0x20,
184184- kFSCatInfoContentMod = 0x40,
185185- kFSCatInfoAttrMod = 0x80,
186186- kFSCatInfoAccessDate = 0x100,
187187- kFSCatInfoBackupDate = 0x200,
188188- kFSCatInfoPermissions = 0x400,
189189- kFSCatInfoFinderInfo = 0x800,
190190- kFSCatInfoFinderXInfo = 0x1000,
191191- kFSCatInfoValence = 0x2000,
192192- kFSCatInfoDataSizes = 0x4000,
193193- kFSCatInfoRsrcSizes = 0x8000,
194194- kFSCatInfoSharingFlags = 0x10000,
195195- kFSCatInfoUserPrivs = 0x20000,
196196- kFSCatInfoUserAccess = 0x80000,
197197- kFSCatInfoSetOwnership = 0x100000
198198-};
199199-200200-enum
201201-{
202202- kSystemFolderType = 'macs',
203203- kDesktopFolderType = 'desk',
204204- kSystemDesktopFolderType = 'sdsk',
205205- kTrashFolderType = 'trsh',
206206- kSystemTrashFolderType = 'strs',
207207- kWhereToEmptyTrashFolderType = 'empt',
208208- kPrintMonitorDocsFolderType = 'prnt',
209209- kStartupFolderType = 'strt',
210210- kShutdownFolderType = 'shdf',
211211- kAppleMenuFolderType = 'amnu',
212212- kControlPanelFolderType = 'ctrl',
213213- kSystemControlPanelFolderType = 'sctl',
214214- kExtensionFolderType = 'extn',
215215- kFontsFolderType = 'font',
216216- kPreferencesFolderType = 'pref',
217217- kSystemPreferencesFolderType = 'sprf',
218218- kTemporaryFolderType = 'temp'
219219-};
220220-221221-OSStatus FSPathMakeRef(const uint8_t* path, struct FSRef* fsref, Boolean* isDirectory);
222222-OSStatus FSPathMakeRefWithOptions(const uint8_t* path, long options, struct FSRef* fsref, Boolean* isDirectory);
223223-OSStatus FSRefMakePath(const struct FSRef* fsref, uint8_t* path, uint32_t maxSize);
224224-Boolean CFURLGetFSRef(CFURLRef urlref, struct FSRef* fsref); // in CF
225225-CFURLRef CFURLCreateFromFSRef(CFAllocatorRef alloc, struct FSRef* location); // --> in CF
226226-OSStatus FSFindFolder(long vRefNum, OSType folderType, Boolean createFolder, struct FSRef* location);
227227-228228-OSStatus FSGetCatalogInfo(const FSRefPtr ref, uint32_t infoBits, struct FSCatalogInfo* infoOut, struct HFSUniStr255* nameOut, FSSpecPtr fsspec, FSRefPtr parentDir);
229229-230230-OSErr PBCreateDirectoryUnicodeSync(struct FSRefParam* paramBlock);
231231-OSErr PBCreateFileUnicodeSync(struct FSRefParam* paramBlock);
232232-OSErr PBGetCatalogInfoSync(struct FSRefParam *paramBlock);
233233-OSErr PBMakeFSRefUnicodeSync(struct FSRefParam *paramBlock);
234234-OSErr PBOpenForkSync(struct FSForkIOParam *paramBlock);
235235-OSErr PBReadForkSync(struct FSForkIOParam *paramBlock);
236236-OSErr PBWriteForkSync(struct FSForkIOParam *paramBlock);
237237-OSErr PBIterateForksSync(struct FSForkIOParam *paramBlock);
238238-OSErr PBCloseForkSync(struct FSForkIOParam *paramBlock);
239239-240240-#ifdef __cplusplus
241241-}
242242-#endif
243243-244244-#endif
245245-
+23
src/frameworks/CoreServices/Resources.cpp
···11+/*
22+This file is part of Darling.
33+44+Copyright (C) 2020 Lubos Dolezel
55+66+Darling is free software: you can redistribute it and/or modify
77+it under the terms of the GNU General Public License as published by
88+the Free Software Foundation, either version 3 of the License, or
99+(at your option) any later version.
1010+1111+Darling is distributed in the hope that it will be useful,
1212+but WITHOUT ANY WARRANTY; without even the implied warranty of
1313+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1414+GNU General Public License for more details.
1515+1616+You should have received a copy of the GNU General Public License
1717+along with Darling. If not, see <http://www.gnu.org/licenses/>.
1818+*/
1919+2020+#include <CoreServices/Resources.h>
2121+2222+// Usage example:
2323+// https://github.com/nathanday/ndalias/blob/master/Classes/NDResourceFork.m
···11+/*
22+This file is part of Darling.
33+44+Copyright (C) 2020 Lubos Dolezel
55+66+Darling is free software: you can redistribute it and/or modify
77+it under the terms of the GNU General Public License as published by
88+the Free Software Foundation, either version 3 of the License, or
99+(at your option) any later version.
1010+1111+Darling is distributed in the hope that it will be useful,
1212+but WITHOUT ANY WARRANTY; without even the implied warranty of
1313+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1414+GNU General Public License for more details.
1515+1616+You should have received a copy of the GNU General Public License
1717+along with Darling. If not, see <http://www.gnu.org/licenses/>.
1818+*/
1919+120#ifndef COMPONENTS_H
221#define COMPONENTS_H
322#include <MacTypes.h>
2323+#include <CoreServices/Resources.h>
424525struct ComponentDescription;
626typedef struct ComponentDescription ComponentDescription;
···6282 defaultComponentAnyFlagsAnyManufacturerAnySubType = (defaultComponentFlags + defaultComponentAnyManufacturer + defaultComponentAnySubType),
6383};
64848585+typedef struct ResourceSpec
8686+{
8787+ OSType resType;
8888+ SInt16 resID;
8989+} ResourceSpec;
9090+9191+typedef struct ComponentPlatformInfo
9292+{
9393+ SInt32 componentFlags;
9494+ ResourceSpec component;
9595+ SInt16 platformType;
9696+} ComponentPlatformInfo;
9797+9898+struct ComponentDescription
9999+{
100100+ OSType componentType, componentSubType, componentManufacturer;
101101+ UInt32 componentFlags, componentFlagsMask;
102102+};
103103+104104+typedef struct ExtComponentResource
105105+{
106106+ ComponentDescription cs;
107107+ ResourceSpec component;
108108+ ResourceSpec componentName;
109109+ ResourceSpec componentInfo;
110110+ ResourceSpec componentIcon;
111111+ SInt32 componentVersion;
112112+ SInt32 componentRegisterFlags;
113113+ SInt16 componentIconFamily;
114114+ SInt32 count;
115115+ ComponentPlatformInfo platformArray[1];
116116+} ExtComponentResource;
117117+65118typedef ComponentResult (*ComponentRoutineProcPtr)(ComponentParameters* cp, Handle componentStorage);
66119typedef ComponentRoutineProcPtr ComponentRoutineUPP;
67120···86139Handle GetComponentInstanceStorage(ComponentInstance aComponentInstance);
87140void SetComponentInstanceStorage(ComponentInstance aComponentInstance, Handle theStorage);
88141142142+OSErr OpenAComponentResFile(Component aComponent, ResFileRefNum* resRef);
143143+89144#ifdef __cplusplus
90145}
91146#endif
9292-9393-struct ComponentDescription
9494-{
9595- OSType componentType, componentSubType, componentManufacturer;
9696- UInt32 componentFlags, componentFlagsMask;
9797-};
9814799148enum
100149{
···11+/*
22+This file is part of Darling.
33+44+Copyright (C) 2020 Lubos Dolezel
55+66+Darling is free software: you can redistribute it and/or modify
77+it under the terms of the GNU General Public License as published by
88+the Free Software Foundation, either version 3 of the License, or
99+(at your option) any later version.
1010+1111+Darling is distributed in the hope that it will be useful,
1212+but WITHOUT ANY WARRANTY; without even the implied warranty of
1313+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1414+GNU General Public License for more details.
1515+1616+You should have received a copy of the GNU General Public License
1717+along with Darling. If not, see <http://www.gnu.org/licenses/>.
1818+*/
1919+2020+2121+#ifndef _CS_FILES_H
2222+#define _CS_FILES_H
2323+#include <CoreServices/MacTypes.h>
2424+2525+#if __LP64__
2626+ typedef int FSIORefNum;
2727+#else
2828+ typedef SInt16 FSIORefNum;
2929+#endif
3030+3131+#endif