mirror of
https://github.com/elliotnunn/mac-rom.git
synced 2024-09-07 09:54:37 +00:00
494 lines
14 KiB
C
494 lines
14 KiB
C
|
/*
|
|||
|
File: FSSpecCalls.c
|
|||
|
|
|||
|
Contains: The FSp wrapper calls to the file system
|
|||
|
|
|||
|
Written by: Dave Feldman
|
|||
|
|
|||
|
Copyright: <EFBFBD> 1990-1992 by Apple Computer, Inc., all rights reserved.
|
|||
|
|
|||
|
Change History (most recent first):
|
|||
|
|
|||
|
<11> 4/4/92 FM #1021881,<DTY>: Add two new calls to turn the ProcessMgr's file
|
|||
|
tracking on and off. SuspendFileTracking and ResumeFileTracking.
|
|||
|
These wil be internal calls for a while.
|
|||
|
<10> 9/13/91 JSM Cleanup header.
|
|||
|
<9> 1/13/91 dnf (jdr) Add compatibility code for FSpExchangeFiles.
|
|||
|
<8> 12/21/90 JL changed constStrxxParameter to ConstStrxxxParam to match change
|
|||
|
in Types.h
|
|||
|
<7> 12/14/90 dnf (w/dba) Have FSpDirCreate use SetCatInfo instead of SetFInfo.
|
|||
|
Changed FSSpecPtr to use const on all calls except FSMakeFSSpec.
|
|||
|
Changed const StringPtr (which doesn't work) to
|
|||
|
constStr255Parameter (which does). Get the resource error with
|
|||
|
RESERR.
|
|||
|
<6> 10/30/90 dnf Set script code byte on create calls. Set ResErr on resource
|
|||
|
manager calls. Switch to PBxxxSync calls.
|
|||
|
<5> 10/2/90 JAL Changed all occurances of .hfileInfo to .hFileInfo to match Interface change
|
|||
|
<4> 8/28/90 dnf Add FSpExchangeFiles
|
|||
|
<3> 8/6/90 dnf Rename implementation routines to use two underscores.
|
|||
|
<2> 8/6/90 dnf Changed routine headers to match latest in files.h.
|
|||
|
<1> 8/6/90 dnf first checked in
|
|||
|
|
|||
|
*/
|
|||
|
|
|||
|
|
|||
|
#include <Types.h>
|
|||
|
#include <Errors.h>
|
|||
|
#include <Files.h>
|
|||
|
#include <MFPrivate.h> // <11>
|
|||
|
#include <Resources.h>
|
|||
|
#include <Traps.h>
|
|||
|
#include <SysEqu.h>
|
|||
|
|
|||
|
/* this is needed for Resource Manager glue */
|
|||
|
|
|||
|
#define RESERR (* (OSErr *) ResErr)
|
|||
|
|
|||
|
|
|||
|
/* Utility Routine */
|
|||
|
|
|||
|
/* Munge a script manager style script code word into encoding used
|
|||
|
for Finder xInfo.
|
|||
|
|
|||
|
In script manager-land, values 0-64 are defined and
|
|||
|
-1 and -2 are special marker values. The Finder xInfo
|
|||
|
definition is that 0 implies "unused" and a high bit
|
|||
|
set indicates that the byte is in use. The script manager's
|
|||
|
-1 and -2 marker values have no meaning on disk, so this
|
|||
|
encoding works out.
|
|||
|
*/
|
|||
|
char ConvertScriptCodeToDiskForm(ScriptCode scriptTag)
|
|||
|
{
|
|||
|
char diskScriptCode;
|
|||
|
|
|||
|
if (scriptTag >= 0)
|
|||
|
diskScriptCode = scriptTag | 0x80; /* set high bit to mark valid */
|
|||
|
else
|
|||
|
diskScriptCode = 0; /* garbage, so leave unused */
|
|||
|
return(diskScriptCode);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
/* File Manager routines */
|
|||
|
|
|||
|
pascal OSErr __FSpOpenDF(const FSSpec* spec, char permission, short *refNum)
|
|||
|
{
|
|||
|
OSErr error;
|
|||
|
HParamBlockRec pb;
|
|||
|
|
|||
|
pb.ioParam.ioVRefNum = spec -> vRefNum;
|
|||
|
pb.fileParam.ioDirID = spec -> parID;
|
|||
|
pb.ioParam.ioNamePtr = (StringPtr) &(spec -> name);
|
|||
|
pb.ioParam.ioVersNum = 0;
|
|||
|
pb.ioParam.ioPermssn = permission;
|
|||
|
pb.ioParam.ioMisc = nil;
|
|||
|
error = PBHOpenDFSync(&pb);
|
|||
|
*refNum = pb.ioParam.ioRefNum;
|
|||
|
return(error);
|
|||
|
}
|
|||
|
|
|||
|
pascal OSErr __FSpOpenRF(const FSSpec* spec, char permission, short *refNum)
|
|||
|
{
|
|||
|
OSErr error;
|
|||
|
HParamBlockRec pb;
|
|||
|
|
|||
|
pb.ioParam.ioVRefNum = spec -> vRefNum;
|
|||
|
pb.fileParam.ioDirID = spec -> parID;
|
|||
|
pb.ioParam.ioNamePtr = (StringPtr) &(spec -> name);
|
|||
|
pb.ioParam.ioVersNum = 0;
|
|||
|
pb.ioParam.ioPermssn = permission;
|
|||
|
pb.ioParam.ioMisc = nil;
|
|||
|
error = PBHOpenRFSync(&pb);
|
|||
|
*refNum = pb.ioParam.ioRefNum;
|
|||
|
return(error);
|
|||
|
}
|
|||
|
|
|||
|
pascal OSErr __FSpCreate(const FSSpec* spec, OSType creator, OSType fileType, ScriptCode scriptTag)
|
|||
|
{
|
|||
|
OSErr error;
|
|||
|
HFileInfo pb;
|
|||
|
|
|||
|
pb.ioVRefNum = spec -> vRefNum;
|
|||
|
pb.ioDirID = spec -> parID;
|
|||
|
pb.ioNamePtr = (StringPtr) &(spec -> name);
|
|||
|
pb.ioFVersNum = 0;
|
|||
|
((HParmBlkPtr) &pb) -> ioParam.ioVersNum = 0;
|
|||
|
error = PBHCreateSync((HParmBlkPtr) &pb);
|
|||
|
if (error == noErr) {
|
|||
|
pb.ioFDirIndex = 0;
|
|||
|
error = PBHGetFInfoSync((HParmBlkPtr) &pb);
|
|||
|
if (error == noErr) {
|
|||
|
pb.ioFlXFndrInfo.fdScript = ConvertScriptCodeToDiskForm(scriptTag);
|
|||
|
pb.ioFlFndrInfo.fdCreator = creator;
|
|||
|
pb.ioFlFndrInfo.fdType = fileType;
|
|||
|
pb.ioDirID = spec -> parID;
|
|||
|
error = PBHSetFInfoSync((HParmBlkPtr)&pb);
|
|||
|
}
|
|||
|
}
|
|||
|
return(error);
|
|||
|
}
|
|||
|
|
|||
|
pascal OSErr __FSpDirCreate(const FSSpec* spec, ScriptCode scriptTag, long *createdDirID)
|
|||
|
{
|
|||
|
OSErr error;
|
|||
|
CInfoPBRec cinfo;
|
|||
|
|
|||
|
cinfo.dirInfo.ioVRefNum = spec -> vRefNum;
|
|||
|
cinfo.dirInfo.ioDrDirID = spec -> parID;
|
|||
|
cinfo.dirInfo.ioNamePtr = (StringPtr) &(spec -> name);
|
|||
|
error = PBDirCreateSync((HParmBlkPtr) &cinfo);
|
|||
|
*createdDirID = cinfo.dirInfo.ioDrDirID;
|
|||
|
if (error == noErr) {
|
|||
|
cinfo.dirInfo.ioFDirIndex = 0;
|
|||
|
cinfo.dirInfo.ioDrDirID = spec -> parID;
|
|||
|
error = PBGetCatInfoSync(&cinfo);
|
|||
|
if (error == noErr) {
|
|||
|
cinfo.dirInfo.ioDrFndrInfo.frScript = ConvertScriptCodeToDiskForm(scriptTag);
|
|||
|
cinfo.dirInfo.ioDrDirID = spec -> parID;
|
|||
|
error = PBSetCatInfoSync(&cinfo);
|
|||
|
}
|
|||
|
}
|
|||
|
return(error);
|
|||
|
}
|
|||
|
|
|||
|
pascal OSErr __FSpDelete(const FSSpec* spec)
|
|||
|
{
|
|||
|
HParamBlockRec pb;
|
|||
|
|
|||
|
pb.ioParam.ioVRefNum = spec -> vRefNum;
|
|||
|
pb.fileParam.ioDirID = spec -> parID;
|
|||
|
pb.ioParam.ioNamePtr = (StringPtr) &(spec -> name);
|
|||
|
pb.ioParam.ioVersNum = 0;
|
|||
|
return(PBHDeleteSync(&pb));
|
|||
|
}
|
|||
|
|
|||
|
pascal OSErr __FSpGetFInfo(const FSSpec* spec, FInfo *fndrInfo)
|
|||
|
{
|
|||
|
OSErr error;
|
|||
|
HParamBlockRec pb;
|
|||
|
|
|||
|
pb.ioParam.ioVRefNum = spec -> vRefNum;
|
|||
|
pb.fileParam.ioDirID = spec -> parID;
|
|||
|
pb.ioParam.ioNamePtr = (StringPtr) &(spec -> name);
|
|||
|
pb.ioParam.ioVersNum = 0;
|
|||
|
pb.fileParam.ioFDirIndex = 0;
|
|||
|
error = PBHGetFInfoSync(&pb);
|
|||
|
*fndrInfo = pb.fileParam.ioFlFndrInfo;
|
|||
|
return(error);
|
|||
|
}
|
|||
|
|
|||
|
pascal OSErr __FSpSetFInfo(const FSSpec* spec, const FInfo *fndrInfo)
|
|||
|
{
|
|||
|
OSErr error;
|
|||
|
HParamBlockRec pb;
|
|||
|
|
|||
|
pb.ioParam.ioVRefNum = spec -> vRefNum;
|
|||
|
pb.fileParam.ioDirID = spec -> parID;
|
|||
|
pb.ioParam.ioNamePtr = (StringPtr) &(spec -> name);
|
|||
|
pb.ioParam.ioVersNum = 0;
|
|||
|
pb.fileParam.ioFDirIndex = 0;
|
|||
|
error = PBHGetFInfoSync(&pb);
|
|||
|
if (error == noErr) {
|
|||
|
pb.fileParam.ioFlFndrInfo = *fndrInfo;
|
|||
|
pb.fileParam.ioDirID = spec -> parID;
|
|||
|
error = PBHSetFInfoSync(&pb);
|
|||
|
}
|
|||
|
return(error);
|
|||
|
}
|
|||
|
|
|||
|
pascal OSErr __FSpSetFLock(const FSSpec* spec)
|
|||
|
{
|
|||
|
HParamBlockRec pb;
|
|||
|
|
|||
|
pb.ioParam.ioVRefNum = spec -> vRefNum;
|
|||
|
pb.fileParam.ioDirID = spec -> parID;
|
|||
|
pb.ioParam.ioNamePtr = (StringPtr) &(spec -> name);
|
|||
|
pb.ioParam.ioVersNum = 0;
|
|||
|
return(PBHSetFLockSync(&pb));
|
|||
|
}
|
|||
|
|
|||
|
pascal OSErr __FSpRstFLock(const FSSpec* spec)
|
|||
|
{
|
|||
|
HParamBlockRec pb;
|
|||
|
|
|||
|
pb.ioParam.ioVRefNum = spec -> vRefNum;
|
|||
|
pb.fileParam.ioDirID = spec -> parID;
|
|||
|
pb.ioParam.ioNamePtr = (StringPtr) &(spec -> name);
|
|||
|
pb.ioParam.ioVersNum = 0;
|
|||
|
return(PBHRstFLockSync(&pb));
|
|||
|
}
|
|||
|
|
|||
|
pascal OSErr __FSpRename(const FSSpec* spec, ConstStr255Param newName)
|
|||
|
{
|
|||
|
HParamBlockRec pb;
|
|||
|
|
|||
|
pb.ioParam.ioVRefNum = spec -> vRefNum;
|
|||
|
pb.fileParam.ioDirID = spec -> parID;
|
|||
|
pb.ioParam.ioNamePtr = (StringPtr) &(spec -> name);
|
|||
|
pb.ioParam.ioVersNum = 0;
|
|||
|
pb.ioParam.ioMisc = (Ptr) newName;
|
|||
|
return(PBHRenameSync(&pb));
|
|||
|
}
|
|||
|
|
|||
|
pascal OSErr __FSpCatMove(const FSSpec* source, const FSSpec* dest)
|
|||
|
{
|
|||
|
CMovePBRec pb;
|
|||
|
|
|||
|
if (source -> vRefNum != dest -> vRefNum)
|
|||
|
return(paramErr);
|
|||
|
pb.ioNamePtr = (StringPtr) &(source -> name);
|
|||
|
pb.ioVRefNum = source -> vRefNum;
|
|||
|
pb.ioDirID = source -> parID;
|
|||
|
pb.ioNewDirID = dest -> parID;
|
|||
|
pb.ioNewName = (StringPtr) &(dest -> name);
|
|||
|
return(PBCatMoveSync(&pb));
|
|||
|
}
|
|||
|
|
|||
|
pascal short __FSpOpenResFile(const FSSpec* spec, char permission)
|
|||
|
{
|
|||
|
return(HOpenResFile(spec -> vRefNum, spec -> parID, &(spec -> name), permission));
|
|||
|
}
|
|||
|
|
|||
|
pascal void __FSpCreateResFile(const FSSpec* spec, OSType creator, OSType fileType, ScriptCode scriptTag)
|
|||
|
{
|
|||
|
OSErr error;
|
|||
|
HFileInfo pb;
|
|||
|
|
|||
|
HCreateResFile(spec -> vRefNum, spec -> parID, &(spec -> name));
|
|||
|
if (RESERR == noErr) {
|
|||
|
pb.ioVRefNum = spec -> vRefNum;
|
|||
|
pb.ioDirID = spec -> parID;
|
|||
|
pb.ioNamePtr = (StringPtr) &(spec -> name);
|
|||
|
((HParmBlkPtr) &pb) -> ioParam.ioVersNum = 0;
|
|||
|
pb.ioFDirIndex = 0;
|
|||
|
error = PBHGetFInfoSync((HParmBlkPtr) &pb);
|
|||
|
if (error == noErr) {
|
|||
|
pb.ioFlXFndrInfo.fdScript = ConvertScriptCodeToDiskForm(scriptTag);
|
|||
|
pb.ioFlFndrInfo.fdCreator = creator;
|
|||
|
pb.ioFlFndrInfo.fdType = fileType;
|
|||
|
pb.ioDirID = spec -> parID;
|
|||
|
error = PBHSetFInfoSync((HParmBlkPtr) &pb);
|
|||
|
}
|
|||
|
RESERR = error;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
pascal OSErr __FSMakeFSSpec( short vRefNum, long dirID, ConstStr255Param fileName, FSSpec* spec)
|
|||
|
{
|
|||
|
HParamBlockRec pb;
|
|||
|
|
|||
|
pb.fileParam.ioNamePtr = fileName;
|
|||
|
pb.fileParam.ioVRefNum = vRefNum;
|
|||
|
pb.fileParam.ioDirID = dirID;
|
|||
|
pb.ioParam.ioMisc = (Ptr) spec;
|
|||
|
return(PBMakeFSSpecSync(&pb));
|
|||
|
}
|
|||
|
|
|||
|
// This one isn<73>t in the interfaces anywhere, but is in the dispatcher.
|
|||
|
// We dreamed it up for use by FSpExchangeFiles, but it<69>s a bit late
|
|||
|
// to make it into Inside Mac. Feel free to add this call later.
|
|||
|
pascal OSErr __FSpGetCatInfo(const FSSpec* spec, CInfoPBPtr cinfo)
|
|||
|
{
|
|||
|
cinfo -> hFileInfo.ioVRefNum = spec -> vRefNum;
|
|||
|
cinfo -> hFileInfo.ioFDirIndex = 0;
|
|||
|
cinfo -> hFileInfo.ioNamePtr = (StringPtr) &(spec -> name);
|
|||
|
cinfo -> hFileInfo.ioDirID = spec -> parID;
|
|||
|
return(PBGetCatInfoSync(cinfo));
|
|||
|
}
|
|||
|
|
|||
|
// These 2 routines were needed by Akiko for opening dictionary files. <11>
|
|||
|
// Right now they just call BeginSysMode and EndSysMode. Hopefully in the <11>
|
|||
|
// future we will be able to release these calls to developers, but for <11>
|
|||
|
// now they are internal only.
|
|||
|
|
|||
|
|
|||
|
// Prevent files opened from being closed when the current process
|
|||
|
// quits!
|
|||
|
|
|||
|
pascal OSErr __SuspendProcessMgrFileTracking(void) // <11>
|
|||
|
{
|
|||
|
OSErr err;
|
|||
|
|
|||
|
err = BeginSystemMode();
|
|||
|
|
|||
|
return err;
|
|||
|
}
|
|||
|
|
|||
|
// Now any files opened will close when the current process
|
|||
|
// quits<74>
|
|||
|
|
|||
|
pascal OSErr __ResumeProcessMgrFileTracking(void) // <11>
|
|||
|
{
|
|||
|
OSErr err;
|
|||
|
|
|||
|
err = EndSystemMode();
|
|||
|
|
|||
|
return err;
|
|||
|
}
|
|||
|
|
|||
|
OSErr IsFile(const FSSpec* spec)
|
|||
|
{
|
|||
|
CInfoPBRec cinfo;
|
|||
|
OSErr error;
|
|||
|
|
|||
|
if (error = __FSpGetCatInfo(spec, &cinfo))
|
|||
|
return(error);
|
|||
|
if (cinfo.hFileInfo.ioFlAttrib & ioDirMask)
|
|||
|
return(notAFileErr);
|
|||
|
else
|
|||
|
return(noErr);
|
|||
|
}
|
|||
|
|
|||
|
OSErr GenerateUniqueName(short volume, long *startSeed, long dir1, long dir2, StringPtr uniqueName)
|
|||
|
{
|
|||
|
OSErr error = noErr;
|
|||
|
long i;
|
|||
|
CInfoPBRec cinfo;
|
|||
|
|
|||
|
cinfo.hFileInfo.ioVRefNum = volume;
|
|||
|
cinfo.hFileInfo.ioFDirIndex = 0;
|
|||
|
cinfo.hFileInfo.ioNamePtr = uniqueName;
|
|||
|
|
|||
|
while (error != fnfErr) {
|
|||
|
(*startSeed)++;
|
|||
|
cinfo.hFileInfo.ioNamePtr[0] = 8;
|
|||
|
for (i = 1; i <= 8; i++)
|
|||
|
cinfo.hFileInfo.ioNamePtr[i] = "0123456789ABCDEF"[((*startSeed >> ((8-i)*4)) & 0xf)];
|
|||
|
cinfo.hFileInfo.ioDirID = dir1;
|
|||
|
error = fnfErr;
|
|||
|
for (i = 1; i <= 2; i++) {
|
|||
|
error = error & PBGetCatInfoSync(&cinfo);
|
|||
|
cinfo.hFileInfo.ioDirID = dir2;
|
|||
|
if ((error != fnfErr) && (error != noErr))
|
|||
|
return(error);
|
|||
|
}
|
|||
|
}
|
|||
|
return(noErr);
|
|||
|
}
|
|||
|
|
|||
|
pascal OSErr __FSpExchangeFiles(const FSSpec* source, const FSSpec* dest)
|
|||
|
{
|
|||
|
HParamBlockRec pb;
|
|||
|
CInfoPBRec catInfoSource, catInfoDest;
|
|||
|
OSErr error, error2;
|
|||
|
Str31 unique1, unique2; // our strings are never more than 11 characters long
|
|||
|
StringPtr unique1Ptr, unique2Ptr, swapola;
|
|||
|
GetVolParmsInfoBuffer volInfo;
|
|||
|
long theSeed, temp;
|
|||
|
|
|||
|
if (source -> vRefNum != dest -> vRefNum)
|
|||
|
return(paramErr);
|
|||
|
pb.fidParam.ioNamePtr = (StringPtr) &(source -> name);
|
|||
|
pb.fidParam.ioVRefNum = source -> vRefNum;
|
|||
|
pb.fidParam.ioDestNamePtr = (StringPtr) &(dest -> name);
|
|||
|
pb.fidParam.ioDestDirID = dest -> parID;
|
|||
|
pb.fidParam.ioSrcDirID = source -> parID;
|
|||
|
|
|||
|
error = PBExchangeFilesSync(&pb);
|
|||
|
|
|||
|
// note that the compatibility case won't work for files with Btree control blocks.
|
|||
|
// Right now only system-like files use btrees
|
|||
|
if (error) {
|
|||
|
|
|||
|
pb.ioParam.ioNamePtr = nil;
|
|||
|
pb.ioParam.ioBuffer = (Ptr) &volInfo;
|
|||
|
pb.ioParam.ioReqCount = sizeof(volInfo);
|
|||
|
error2 = PBHGetVolParmsSync(&pb);
|
|||
|
|
|||
|
// continue if volume has no fileID support (or no GetVolParms support)
|
|||
|
if ((error2 == noErr) && (volInfo.vMAttrib & (1<<bHasFileIDs)))
|
|||
|
return(error);
|
|||
|
|
|||
|
// make sure both files are really files
|
|||
|
if ((error = IsFile(source)) || (error = IsFile(dest)))
|
|||
|
return(error);
|
|||
|
|
|||
|
// generate 2 filenames that are unique in both directories
|
|||
|
theSeed = 0x64666364; // a fine unlikely filename
|
|||
|
unique1Ptr = &unique1;
|
|||
|
unique2Ptr = &unique2;
|
|||
|
|
|||
|
if (error = GenerateUniqueName(source -> vRefNum, &theSeed, source -> parID, dest -> parID, unique1Ptr))
|
|||
|
return(error);
|
|||
|
|
|||
|
if (error = GenerateUniqueName(source -> vRefNum, &theSeed, source -> parID, dest -> parID, unique2Ptr))
|
|||
|
return(error);
|
|||
|
|
|||
|
// get the catalog info for each file
|
|||
|
if (error = __FSpGetCatInfo(source, &catInfoSource))
|
|||
|
return(error);
|
|||
|
if (error = __FSpGetCatInfo(dest, &catInfoDest))
|
|||
|
return(error);
|
|||
|
|
|||
|
// rename source to unique1
|
|||
|
pb.fileParam.ioNamePtr = (StringPtr) &(source -> name);
|
|||
|
pb.ioParam.ioMisc = (Ptr) unique1Ptr;
|
|||
|
if (error = PBHRenameSync(&pb))
|
|||
|
return(error);
|
|||
|
|
|||
|
// rename dest to unique2
|
|||
|
pb.ioParam.ioMisc = (Ptr) unique2Ptr;
|
|||
|
pb.fileParam.ioNamePtr = (StringPtr) &(dest -> name);
|
|||
|
pb.fileParam.ioDirID = dest -> parID;
|
|||
|
if (error = PBHRenameSync(&pb))
|
|||
|
goto error2;
|
|||
|
|
|||
|
// move source file to dest directory
|
|||
|
pb.copyParam.ioNamePtr = unique1Ptr;
|
|||
|
pb.copyParam.ioNewName = nil;
|
|||
|
pb.copyParam.ioNewDirID = dest -> parID;
|
|||
|
pb.copyParam.ioDirID = source -> parID;
|
|||
|
if (error = PBCatMoveSync((CMovePBPtr) &pb))
|
|||
|
goto error1;
|
|||
|
|
|||
|
// move dest file to source directory
|
|||
|
pb.copyParam.ioNamePtr = unique2Ptr;
|
|||
|
pb.copyParam.ioNewDirID = source -> parID;
|
|||
|
pb.copyParam.ioDirID = dest -> parID;
|
|||
|
if (error = PBCatMoveSync((CMovePBPtr) &pb)) {
|
|||
|
// life is very bad. We'll at least try to move source back
|
|||
|
pb.copyParam.ioNamePtr = unique1Ptr;
|
|||
|
pb.copyParam.ioNewName = nil;
|
|||
|
pb.copyParam.ioNewDirID = source -> parID;
|
|||
|
pb.copyParam.ioDirID = dest -> parID;
|
|||
|
PBCatMoveSync((CMovePBPtr) &pb); // ignore errors
|
|||
|
} else {
|
|||
|
// make unique1 point to file in dest
|
|||
|
swapola = unique1Ptr;
|
|||
|
unique1Ptr = unique2Ptr;
|
|||
|
unique2Ptr = swapola;
|
|||
|
}
|
|||
|
|
|||
|
// swap the catalog info by re-aiming the CInfoPB's
|
|||
|
catInfoSource.hFileInfo.ioNamePtr = unique2Ptr;
|
|||
|
catInfoDest.hFileInfo.ioNamePtr = unique1Ptr;
|
|||
|
|
|||
|
catInfoSource.hFileInfo.ioDirID = dest -> parID;
|
|||
|
catInfoDest.hFileInfo.ioDirID = source -> parID;
|
|||
|
|
|||
|
// leave original mod dates w/each file
|
|||
|
temp = catInfoSource.hFileInfo.ioFlMdDat;
|
|||
|
catInfoSource.hFileInfo.ioFlMdDat = catInfoDest.hFileInfo.ioFlMdDat;
|
|||
|
catInfoDest.hFileInfo.ioFlMdDat = temp;
|
|||
|
|
|||
|
// ignore errors
|
|||
|
PBSetCatInfoSync(&catInfoSource);
|
|||
|
PBSetCatInfoSync(&catInfoDest);
|
|||
|
|
|||
|
// rename unique2 back to dest
|
|||
|
error1:
|
|||
|
pb.ioParam.ioMisc = (Ptr) &(dest -> name);
|
|||
|
pb.fileParam.ioNamePtr = unique2Ptr;
|
|||
|
pb.fileParam.ioDirID = dest -> parID;
|
|||
|
PBHRenameSync(&pb); // ignore errors
|
|||
|
|
|||
|
// rename unique1 back to source
|
|||
|
error2:
|
|||
|
pb.ioParam.ioMisc = (Ptr) &(source -> name);
|
|||
|
pb.fileParam.ioNamePtr = unique1Ptr;
|
|||
|
pb.fileParam.ioDirID = source -> parID;
|
|||
|
PBHRenameSync(&pb); // ignore errors
|
|||
|
}
|
|||
|
return(error);
|
|||
|
}
|