📄 macstuff.c
字号:
#include <string.h>#include "macstuff.h"extern int errno;static OSErr GetCommentFromDesktopFile(short vRefNum, long dirID, ConstStr255Param name, Str255 comment);static OSErr GetCommentID(short vRefNum, long dirID, ConstStr255Param name, short *commentID);static OSErr GetDesktopFileName(short vRefNum, Str255 desktopName);enum{ kBNDLResType = 'BNDL', kFREFResType = 'FREF', kIconFamResType = 'ICN#', kFCMTResType = 'FCMT', kAPPLResType = 'APPL'};/*****************************************************************************//*** File Manager FSp calls*//*****************************************************************************/pascal OSErr FSMakeFSSpecCompat(short vRefNum, long dirID, ConstStr255Param fileName, FSSpec *spec){ OSErr result;#if !__MACOSSEVENORLATER if ( !FSHasFSSpecCalls() && !QTHasFSSpecCalls() ) { Boolean isDirectory; result = GetObjectLocation(vRefNum, dirID, fileName, &(spec->vRefNum), &(spec->parID), spec->name, &isDirectory); } else#endif /* !__MACOSSEVENORLATER */ { /* Let the file system create the FSSpec if it can since it does the job */ /* much more efficiently than I can. */ result = FSMakeFSSpec(vRefNum, dirID, fileName, spec); /* Fix a bug in Macintosh PC Exchange's MakeFSSpec code where 0 is */ /* returned in the parID field when making an FSSpec to the volume's */ /* root directory by passing a full pathname in MakeFSSpec's */ /* fileName parameter. Fixed in Mac OS 8.1 */ if ( (result == noErr) && (spec->parID == 0) ) spec->parID = fsRtParID; } return ( result );}/*****************************************************************************//* FSHasFSSpecCalls returns true if the file system provides FSSpec calls. */#if !__MACOSSEVENORLATERstatic Boolean FSHasFSSpecCalls(void){ long response;#if !GENERATENODATA static Boolean tested = false; static Boolean result = false;#else Boolean result = false;#endif#if !GENERATENODATA if ( !tested ) { tested = true;#endif if ( Gestalt(gestaltFSAttr, &response) == noErr ) { result = ((response & (1L << gestaltHasFSSpecCalls)) != 0); }#if !GENERATENODATA }#endif return ( result );}#endif /* !__MACOSSEVENORLATER *//*****************************************************************************//* QTHasFSSpecCalls returns true if QuickTime provides FSSpec calls *//* except for FSpExchangeFiles. */#if !__MACOSSEVENORLATERstatic Boolean QTHasFSSpecCalls(void){ long response;#if !GENERATENODATA static Boolean tested = false; static Boolean result = false;#else Boolean result = false;#endif#if !GENERATENODATA if ( !tested ) { tested = true;#endif result = (Gestalt(gestaltQuickTimeVersion, &response) == noErr);#if !GENERATENODATA }#endif return ( result );}#endif /* !__MACOSSEVENORLATER *//* *---------------------------------------------------------------------- * * FSpGetDefaultDir -- * * This function gets the current default directory. * * Results: * The provided FSSpec is changed to point to the "default" * directory. The function returns what ever errors * FSMakeFSSpecCompat may encounter. * * Side effects: * None. * *---------------------------------------------------------------------- */int FSpGetDefaultDir(FSSpecPtr dirSpec) /* On return the default directory. */{ OSErr err; short vRefNum = 0; long int dirID = 0; err = HGetVol(NULL, &vRefNum, &dirID); if (err == noErr) { err = FSMakeFSSpecCompat(vRefNum, dirID, (ConstStr255Param) NULL, dirSpec); } return err;}/* *---------------------------------------------------------------------- * * FSpSetDefaultDir -- * * This function sets the default directory to the directory * pointed to by the provided FSSpec. * * Results: * The function returns what ever errors HSetVol may encounter. * * Side effects: * None. * *---------------------------------------------------------------------- */int FSpSetDefaultDir(FSSpecPtr dirSpec) /* The new default directory. */{ OSErr err; /* * The following special case is needed to work around a bug * in the Macintosh OS. (Acutally PC Exchange.) */ if (dirSpec->parID == fsRtParID) { err = HSetVol(NULL, dirSpec->vRefNum, fsRtDirID); } else { err = HSetVol(dirSpec->name, dirSpec->vRefNum, dirSpec->parID); } return err;}/* *---------------------------------------------------------------------- * * FSpFindFolder -- * * This function is a version of the FindFolder function that * returns the result as a FSSpec rather than a vRefNum and dirID. * * Results: * Results will be simaler to that of the FindFolder function. * * Side effects: * None. * *---------------------------------------------------------------------- */OSErrFSpFindFolder( short vRefNum, /* Volume reference number. */ OSType folderType, /* Folder type taken by FindFolder. */ Boolean createFolder, /* Should we create it if non-existant. */ FSSpec *spec) /* Pointer to resulting directory. */{ short foundVRefNum; long foundDirID; OSErr err; err = FindFolder(vRefNum, folderType, createFolder, &foundVRefNum, &foundDirID); if (err != noErr) { return err; } err = FSMakeFSSpecCompat(foundVRefNum, foundDirID, "\p", spec); return err;}/* *---------------------------------------------------------------------- * * FSpPathFromLocation -- * * This function obtains a full path name for a given macintosh * FSSpec. Unlike the More Files function FSpGetFullPath, this * function will return a C string in the Handle. It also will * create paths for FSSpec that do not yet exist. * * Results: * OSErr code. * * Side effects: * None. * *---------------------------------------------------------------------- */OSErrFSpPathFromLocation( FSSpec *spec, /* The location we want a path for. */ int *length, /* Length of the resulting path. */ Handle *fullPath) /* Handle to path. */{ OSErr err; FSSpec tempSpec; CInfoPBRec pb; *fullPath = NULL; /* * Make a copy of the input FSSpec that can be modified. */ BlockMoveData(spec, &tempSpec, sizeof(FSSpec)); if (tempSpec.parID == fsRtParID) { /* * The object is a volume. Add a colon to make it a full * pathname. Allocate a handle for it and we are done. */ tempSpec.name[0] += 2; tempSpec.name[tempSpec.name[0] - 1] = ':'; tempSpec.name[tempSpec.name[0]] = '\0'; err = PtrToHand(&tempSpec.name[1], fullPath, tempSpec.name[0]); } else { /* * The object isn't a volume. Is the object a file or a directory? */ pb.dirInfo.ioNamePtr = tempSpec.name; pb.dirInfo.ioVRefNum = tempSpec.vRefNum; pb.dirInfo.ioDrDirID = tempSpec.parID; pb.dirInfo.ioFDirIndex = 0; err = PBGetCatInfoSync(&pb); if ((err == noErr) || (err == fnfErr)) { /* * If the file doesn't currently exist we start over. If the * directory exists everything will work just fine. Otherwise we * will just fail later. If the object is a directory, append a * colon so full pathname ends with colon. */ if (err == fnfErr) { BlockMoveData(spec, &tempSpec, sizeof(FSSpec)); } else if ( (pb.hFileInfo.ioFlAttrib & ioDirMask) != 0 ) { tempSpec.name[0] += 1; tempSpec.name[tempSpec.name[0]] = ':'; } /* * Create a new Handle for the object - make it a C string. */ tempSpec.name[0] += 1; tempSpec.name[tempSpec.name[0]] = '\0'; err = PtrToHand(&tempSpec.name[1], fullPath, tempSpec.name[0]); if (err == noErr) { /* * Get the ancestor directory names - loop until we have an * error or find the root directory. */ pb.dirInfo.ioNamePtr = tempSpec.name; pb.dirInfo.ioVRefNum = tempSpec.vRefNum; pb.dirInfo.ioDrParID = tempSpec.parID; do { pb.dirInfo.ioFDirIndex = -1; pb.dirInfo.ioDrDirID = pb.dirInfo.ioDrParID; err = PBGetCatInfoSync(&pb); if (err == noErr) { /* * Append colon to directory name and add * directory name to beginning of fullPath. */ ++tempSpec.name[0]; tempSpec.name[tempSpec.name[0]] = ':'; (void) Munger(*fullPath, 0, NULL, 0, &tempSpec.name[1], tempSpec.name[0]); err = MemError(); } } while ( (err == noErr) && (pb.dirInfo.ioDrDirID != fsRtDirID) ); } } } /* * On error Dispose the handle, set it to NULL & return the err. * Otherwise, set the length & return. */ if (err == noErr) { *length = GetHandleSize(*fullPath) - 1; } else { if ( *fullPath != NULL ) { DisposeHandle(*fullPath); } *fullPath = NULL; *length = 0; } return err;}/*****************************************************************************/pascal OSErr FSpGetDirectoryID(const FSSpec *spec, long *theDirID, Boolean *isDirectory){ return ( GetDirectoryID(spec->vRefNum, spec->parID, spec->name, theDirID, isDirectory) );}/*****************************************************************************/pascal OSErr GetDirectoryID(short vRefNum, long dirID, ConstStr255Param name, long *theDirID, Boolean *isDirectory){ CInfoPBRec pb; OSErr error; error = GetCatInfoNoName(vRefNum, dirID, name, &pb); if ( error == noErr ) { *isDirectory = (pb.hFileInfo.ioFlAttrib & ioDirMask) != 0; if ( *isDirectory ) { *theDirID = pb.dirInfo.ioDrDirID; } else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -