📄 macstuff.c
字号:
if ( error == noErr ) { if ( hasDesktopMgr(volParmsInfo) ) { pb.ioNamePtr = (StringPtr)volName; pb.ioVRefNum = vRefNum; error = PBDTOpenInform(&pb); /* PBDTOpenInform informs us if the desktop was just created */ /* by leaving the low bit of ioTagInfo clear (0) */ *newDTDatabase = ((pb.ioTagInfo & 1L) == 0); if ( error == paramErr ) { error = PBDTGetPath(&pb); /* PBDTGetPath doesn't tell us if the database is new */ /* so assume it is not new */ *newDTDatabase = false; } *dtRefNum = pb.ioDTRefNum; } else { error = paramErr; } } return ( error );}/*****************************************************************************//*** GetCommentFromDesktopFile**** Get a file or directory's Finder comment field (if any) from the** Desktop file's 'FCMT' resources.*/static OSErr GetCommentFromDesktopFile(short vRefNum, long dirID, ConstStr255Param name, Str255 comment){ OSErr error; short commentID; short realVRefNum; Str255 desktopName; short savedResFile; short dfRefNum; StringHandle commentHandle; /* Get the comment ID number */ error = GetCommentID(vRefNum, dirID, name, &commentID); if ( error == noErr ) { if ( commentID != 0 ) /* commentID == 0 means there's no comment */ { error = DetermineVRefNum(name, vRefNum, &realVRefNum); if ( error == noErr ) { error = GetDesktopFileName(realVRefNum, desktopName); if ( error == noErr ) { savedResFile = CurResFile(); /* ** Open the 'Desktop' file in the root directory. (because ** opening the resource file could preload unwanted resources, ** bracket the call with SetResLoad(s)) */ SetResLoad(false); dfRefNum = HOpenResFile(realVRefNum, fsRtDirID, desktopName, fsRdPerm); SetResLoad(true); if ( dfRefNum != -1) { /* Get the comment resource */ commentHandle = (StringHandle)Get1Resource(kFCMTResType, commentID); if ( commentHandle != NULL ) { if ( InlineGetHandleSize((Handle)commentHandle) > 0 ) { BlockMoveData(*commentHandle, comment, *commentHandle[0] + 1); } else { /* no comment available */ error = afpItemNotFound; } } else { /* no comment available */ error = afpItemNotFound; } /* restore the resource chain and close the Desktop file */ UseResFile(savedResFile); CloseResFile(dfRefNum); } else { error = afpItemNotFound; } } else { error = afpItemNotFound; } } } else { error = afpItemNotFound; /* no comment available */ } } return ( error );}/*****************************************************************************/pascal OSErr HGetVolParms(ConstStr255Param volName, short vRefNum, GetVolParmsInfoBuffer *volParmsInfo, long *infoSize){ HParamBlockRec pb; OSErr error; pb.ioParam.ioNamePtr = (StringPtr)volName; pb.ioParam.ioVRefNum = vRefNum; pb.ioParam.ioBuffer = (Ptr)volParmsInfo; pb.ioParam.ioReqCount = *infoSize; error = PBHGetVolParmsSync(&pb); if ( error == noErr ) { *infoSize = pb.ioParam.ioActCount; } return ( error );}/*****************************************************************************//*** GetCommentID**** Get the comment ID number for the Desktop file's 'FCMT' resource ID from** the file or folders fdComment (frComment) field.*/static OSErr GetCommentID(short vRefNum, long dirID, ConstStr255Param name, short *commentID){ CInfoPBRec pb; OSErr error; error = GetCatInfoNoName(vRefNum, dirID, name, &pb); *commentID = pb.hFileInfo.ioFlXFndrInfo.fdComment; return ( error );}/*****************************************************************************//*** GetDesktopFileName**** Get the name of the Desktop file.*/static OSErr GetDesktopFileName(short vRefNum, Str255 desktopName){ OSErr error; HParamBlockRec pb; short index; Boolean found; pb.fileParam.ioNamePtr = desktopName; pb.fileParam.ioVRefNum = vRefNum; pb.fileParam.ioFVersNum = 0; index = 1; found = false; do { pb.fileParam.ioDirID = fsRtDirID; pb.fileParam.ioFDirIndex = index; error = PBHGetFInfoSync(&pb); if ( error == noErr ) { if ( (pb.fileParam.ioFlFndrInfo.fdType == 'FNDR') && (pb.fileParam.ioFlFndrInfo.fdCreator == 'ERIK') ) { found = true; } } ++index; } while ( (error == noErr) && !found ); return ( error );}/*****************************************************************************/pascal OSErr XGetVInfo(short volReference, StringPtr volName, short *vRefNum, UnsignedWide *freeBytes, UnsignedWide *totalBytes){ OSErr result; long response; XVolumeParam pb; /* See if large volume support is available */ if ( ( Gestalt(gestaltFSAttr, &response) == noErr ) && ((response & (1L << gestaltFSSupports2TBVols)) != 0) ) { /* Large volume support is available */ pb.ioVRefNum = volReference; pb.ioNamePtr = volName; pb.ioXVersion = 0; /* this XVolumeParam version (0) */ pb.ioVolIndex = 0; /* use ioVRefNum only, return volume name */ result = PBXGetVolInfoSync(&pb); if ( result == noErr ) { /* The volume name was returned in volName (if not NULL) and */ /* we have the volume's vRefNum and allocation block size */ *vRefNum = pb.ioVRefNum; /* return the freeBytes and totalBytes */ *totalBytes = pb.ioVTotalBytes; *freeBytes = pb.ioVFreeBytes; } } else { /* No large volume support */ /* Use HGetVInfo to get the results */ result = HGetVInfo(volReference, volName, vRefNum, &freeBytes->lo, &totalBytes->lo); if ( result == noErr ) { /* zero the high longs of totalBytes and freeBytes */ totalBytes->hi = 0; freeBytes->hi = 0; } } return ( result );}/*****************************************************************************/pascal OSErr HGetVInfo(short volReference, StringPtr volName, short *vRefNum, unsigned long *freeBytes, unsigned long *totalBytes){ HParamBlockRec pb; unsigned long allocationBlockSize; unsigned short numAllocationBlocks; unsigned short numFreeBlocks; VCB *theVCB; Boolean vcbFound; OSErr result; /* Use the File Manager to get the real vRefNum */ pb.volumeParam.ioVRefNum = volReference; pb.volumeParam.ioNamePtr = volName; pb.volumeParam.ioVolIndex = 0; /* use ioVRefNum only, return volume name */ result = PBHGetVInfoSync(&pb); if ( result == noErr ) { /* The volume name was returned in volName (if not NULL) and */ /* we have the volume's vRefNum and allocation block size */ *vRefNum = pb.volumeParam.ioVRefNum; allocationBlockSize = (unsigned long)pb.volumeParam.ioVAlBlkSiz; /* System 7.5 (and beyond) pins the number of allocation blocks and */ /* the number of free allocation blocks returned by PBHGetVInfo to */ /* a value so that when multiplied by the allocation block size, */ /* the volume will look like it has $7fffffff bytes or less. This */ /* was done so older applications that use signed math or that use */ /* the GetVInfo function (which uses signed math) will continue to work. */ /* However, the unpinned numbers (which we want) are always available */ /* in the volume's VCB so we'll get those values from the VCB if possible. */ /* Find the volume's VCB */ vcbFound = false; theVCB = (VCB *)(GetVCBQHdr()->qHead); while ( (theVCB != NULL) && !vcbFound ) { /* Check VCB signature before using VCB. Don't have to check for */ /* MFS (0xd2d7) because they can't get big enough to be pinned */ if ( theVCB->vcbSigWord == 0x4244 ) { if ( theVCB->vcbVRefNum == *vRefNum ) { vcbFound = true; } } if ( !vcbFound ) { theVCB = (VCB *)(theVCB->qLink); } } if ( theVCB != NULL ) { /* Found a VCB we can use. Get the un-pinned number of allocation blocks */ /* and the number of free blocks from the VCB. */ numAllocationBlocks = (unsigned short)theVCB->vcbNmAlBlks; numFreeBlocks = (unsigned short)theVCB->vcbFreeBks; } else { /* Didn't find a VCB we can use. Return the number of allocation blocks */ /* and the number of free blocks returned by PBHGetVInfoSync. */ numAllocationBlocks = (unsigned short)pb.volumeParam.ioVNmAlBlks; numFreeBlocks = (unsigned short)pb.volumeParam.ioVFrBlk; } /* Now, calculate freeBytes and totalBytes using unsigned values */ *freeBytes = numFreeBlocks * allocationBlockSize; *totalBytes = numAllocationBlocks * allocationBlockSize; } return ( result );}/*** PBXGetVolInfoSync is the glue code needed to make PBXGetVolInfoSync** File Manager requests from CFM-based programs. At some point, Apple** will get around to adding this to the standard libraries you link with** and you'll get a duplicate symbol link error. At that time, just delete** this code (or comment it out).**** Non-CFM 68K programs don't needs this glue (and won't get it) because** they instead use the inline assembly glue found in the Files.h interface** file.*/#if __WANTPASCALELIMINATION#undef pascal#endif#if GENERATINGCFMpascal OSErr PBXGetVolInfoSync(XVolumeParamPtr paramBlock){ enum { kXGetVolInfoSelector = 0x0012, /* Selector for XGetVolInfo */ uppFSDispatchProcInfo = kRegisterBased | REGISTER_RESULT_LOCATION(kRegisterD0) | RESULT_SIZE(SIZE_CODE(sizeof(OSErr))) | REGISTER_ROUTINE_PARAMETER(1, kRegisterD1, SIZE_CODE(sizeof(long))) /* trap word */ | REGISTER_ROUTINE_PARAMETER(2, kRegisterD0, SIZE_CODE(sizeof(long))) /* selector */ | REGISTER_ROUTINE_PARAMETER(3, kRegisterA0, SIZE_CODE(sizeof(XVolumeParamPtr))) }; return ( CallOSTrapUniversalProc(NGetTrapAddress(_FSDispatch, OSTrap), uppFSDispatchProcInfo, _FSDispatch, kXGetVolInfoSelector, paramBlock) );}#endif#if __WANTPASCALELIMINATION#define pascal#endif/*****************************************************************************/pascal OSErr GetDirName(short vRefNum, long dirID, Str31 name){ CInfoPBRec pb; OSErr error; if ( name != NULL ) { pb.dirInfo.ioNamePtr = name; pb.dirInfo.ioVRefNum = vRefNum; pb.dirInfo.ioDrDirID = dirID; pb.dirInfo.ioFDirIndex = -1; /* get information about ioDirID */ error = PBGetCatInfoSync(&pb); } else { error = paramErr; } return ( error );}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -