📄 macstuff.c
字号:
/*These Functions were originally part of More Files version 1.4.8More Files fixes many of the broken or underfunctionalparts of the file system.More FilesA collection of File Manager and related routinesby Jim Luther (Apple Macintosh Developer Technical Support Emeritus)with significant code contributions by Nitin Ganatra(Apple Macintosh Developer Technical Support Emeritus)Copyright 1992-1998 Apple Computer, Inc.Portions copyright 1995 Jim LutherAll rights reserved.The Package "More Files" is distributed under the followinglicense terms: "You may incorporate this sample code into your applications without restriction, though the sample code has been provided "AS IS" and the responsibility for its operation is 100% yours. However, what you are not permitted to do is to redistribute the source as "DSC Sample Code" after having made changes. If you're going to redistribute the source, we require that you make it clear in the source that the code was descended from Apple Sample Code, but that you've made changes."The following changes are made by Info-ZIP:- The only changes are made by pasting the functions (mostly found in MoreFilesExtras.c / MoreFiles.c) directly into macstuff.c / macstuff.h and slightly reformatting the text (replacement of TABs by spaces, removal/replacement of non-ASCII characters). The code itself is NOT changed.This file has been modified by Info-ZIP for use in MacZip.This file is NOT part of the original package More Files.More Files can be found on the MetroWerks CD and Developer CD fromApple. You can also download the latest version from: http://members.aol.com/JumpLong/#MoreFilesJim Luther's Home-page: http://members.aol.com/JumpLong/*/#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,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -