00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 
00049 
00050 
00051 
00052 
00053 
00054 
00055 
00056 
00057 
00058 
00059 
00060 
00061 
00062 
00063 
00064 
00065 
00066 
00067 
00068 
00069 
00070 
00071 
00072 #include <Carbon/Carbon.h>
00073 #include <string.h>
00074 
00075 #include "MoreFilesX.h"
00076 
00077 
00078 #ifndef BuildingMoreFilesXForMacOS9
00079         #define BuildingMoreFilesXForMacOS9 0
00080 #endif
00081 
00082 
00083 
00084 #pragma mark ----- Local type definitions -----
00085 
00086 struct FSIterateContainerGlobals
00087 {
00088         IterateContainerFilterProcPtr   iterateFilter;  
00089         FSCatalogInfoBitmap                             whichInfo;              
00090         FSCatalogInfo                                   catalogInfo;    
00091         FSRef                                                   ref;                    
00092         FSSpec                                                  spec;                   
00093         FSSpec                                                  *specPtr;               
00094         HFSUniStr255                                    name;                   
00095         HFSUniStr255                                    *namePtr;               
00096         void                                                    *yourDataPtr;   
00097         ItemCount                                               maxLevels;              
00098         ItemCount                                               currentLevel;   
00099         Boolean                                                 quitFlag;               
00100         Boolean                                                 containerChanged; 
00101         OSErr                                                   result;                 
00102         ItemCount                                               actualObjects;  
00103 };
00104 typedef struct FSIterateContainerGlobals FSIterateContainerGlobals;
00105 
00106 struct FSDeleteContainerGlobals
00107 {
00108         OSErr                                                   result;                 
00109         ItemCount                                               actualObjects;  
00110         FSCatalogInfo                                   catalogInfo;    
00111 };
00112 typedef struct FSDeleteContainerGlobals FSDeleteContainerGlobals;
00113 
00114 
00115 
00116 #pragma mark ----- Local prototypes -----
00117 
00118 static
00119 void
00120 FSDeleteContainerLevel(
00121         const FSRef *container,
00122         FSDeleteContainerGlobals *theGlobals);
00123 
00124 static
00125 void
00126 FSIterateContainerLevel(
00127         FSIterateContainerGlobals *theGlobals);
00128 
00129 static
00130 OSErr
00131 GenerateUniqueHFSUniStr(
00132         long *startSeed,
00133         const FSRef *dir1,
00134         const FSRef *dir2,
00135         HFSUniStr255 *uniqueName);
00136 
00137 
00138 
00139 #pragma mark ----- File Access Routines -----
00140 
00141 
00142 
00143 OSErr
00144 FSCopyFork(
00145         SInt16 srcRefNum,
00146         SInt16 dstRefNum,
00147         void *copyBufferPtr,
00148         ByteCount copyBufferSize)
00149 {
00150         OSErr           srcResult;
00151         OSErr           dstResult;
00152         OSErr           result;
00153         SInt64          forkSize;
00154         ByteCount       readActualCount;
00155         
00156         
00157         require_action((NULL != copyBufferPtr) && (0 != copyBufferSize), BadParameter, result = paramErr);
00158         
00159         
00160         result = FSGetForkSize(srcRefNum, &forkSize);
00161         require_noerr(result, SourceFSGetForkSizeFailed);
00162         
00163         
00164         result = FSSetForkSize(dstRefNum, fsFromStart, forkSize);
00165         require_noerr(result, DestinationFSSetForkSizeFailed);
00166         
00167         
00168         result = FSSetForkPosition(srcRefNum, fsFromStart, 0);
00169         require_noerr(result, SourceFSSetForkPositionFailed);
00170         
00171         
00172         result = FSSetForkPosition(dstRefNum, fsFromStart, 0);
00173         require_noerr(result, DestinationFSSetForkPositionFailed);
00174 
00175         
00176         
00177         if ( (copyBufferSize >= 0x00001000) && ((copyBufferSize & 0x00000fff) != 0) )
00178         {
00179                 copyBufferSize &= ~(0x00001000 - 1);
00180         }
00181         
00182         
00183         srcResult = dstResult = noErr;
00184         while ( (noErr == srcResult) && (noErr == dstResult) )
00185         {
00186                 srcResult = FSReadFork(srcRefNum, fsAtMark + noCacheMask, 0, copyBufferSize, copyBufferPtr, &readActualCount);
00187                 dstResult = FSWriteFork(dstRefNum, fsAtMark + noCacheMask, 0, readActualCount, copyBufferPtr, NULL);
00188         }
00189         
00190         
00191         require_noerr_action(dstResult, DestinationFSWriteForkFailed, result = dstResult);
00192         
00193         
00194         require_action(eofErr == srcResult, SourceResultNotEofErr, result = srcResult);
00195         
00196         
00197         result = noErr;
00198 
00199 SourceResultNotEofErr:
00200 DestinationFSWriteForkFailed:
00201 DestinationFSSetForkPositionFailed:
00202 SourceFSSetForkPositionFailed:
00203 DestinationFSSetForkSizeFailed:
00204 SourceFSGetForkSizeFailed:
00205 BadParameter:
00206 
00207         return ( result );
00208 }
00209 
00210 
00211 
00212 #pragma mark ----- Volume Access Routines -----
00213 
00214  
00215 
00216 OSErr
00217 FSGetVolParms(
00218         FSVolumeRefNum volRefNum,
00219         UInt32 bufferSize,
00220         GetVolParmsInfoBuffer *volParmsInfo,
00221         UInt32 *actualInfoSize)
00222 {
00223         OSErr                   result;
00224         HParamBlockRec  pb;
00225         
00226         
00227         require_action((NULL != volParmsInfo) && (NULL != actualInfoSize),
00228                 BadParameter, result = paramErr);
00229         
00230         pb.ioParam.ioNamePtr = NULL;
00231         pb.ioParam.ioVRefNum = volRefNum;
00232         pb.ioParam.ioBuffer = (Ptr)volParmsInfo;
00233         pb.ioParam.ioReqCount = (SInt32)bufferSize;
00234         result = PBHGetVolParmsSync(&pb);
00235         require_noerr(result, PBHGetVolParmsSync);
00236         
00237         
00238         *actualInfoSize = (UInt32)pb.ioParam.ioActCount;
00239         
00240 PBHGetVolParmsSync:
00241 BadParameter:
00242 
00243         return ( result );
00244 }
00245 
00246 
00247 
00248 OSErr
00249 FSGetVRefNum(
00250         const FSRef *ref,
00251         FSVolumeRefNum *vRefNum)
00252 {
00253         OSErr                   result;
00254         FSCatalogInfo   catalogInfo;
00255         
00256         
00257         require_action(NULL != vRefNum, BadParameter, result = paramErr);
00258         
00259         
00260         result = FSGetCatalogInfo(ref, kFSCatInfoVolume, &catalogInfo, NULL, NULL, NULL);
00261         require_noerr(result, FSGetCatalogInfo);
00262         
00263         
00264         *vRefNum = catalogInfo.volume;
00265         
00266 FSGetCatalogInfo:
00267 BadParameter:
00268 
00269         return ( result );
00270 }
00271 
00272 
00273 
00274 OSErr
00275 FSGetVInfo(
00276         FSVolumeRefNum volume,
00277         HFSUniStr255 *volumeName,       
00278         UInt64 *freeBytes,                      
00279         UInt64 *totalBytes)                     
00280 {
00281         OSErr                           result;
00282         FSVolumeInfo            info;
00283         
00284         
00285         result = FSGetVolumeInfo(volume, 0, NULL,
00286                 (((NULL != freeBytes) || (NULL != totalBytes)) ? kFSVolInfoSizes : kFSVolInfoNone),
00287                 &info, volumeName, NULL);
00288         require_noerr(result, FSGetVolumeInfo);
00289         
00290         if ( NULL != freeBytes )
00291         {
00292                 *freeBytes = info.freeBytes;
00293         }
00294         if ( NULL != totalBytes )
00295         {
00296                 *totalBytes = info.totalBytes;
00297         }
00298         
00299 FSGetVolumeInfo:
00300 
00301         return ( result );
00302 }
00303 
00304 
00305 
00306 OSErr
00307 FSGetVolFileSystemID(
00308         FSVolumeRefNum volume,
00309         UInt16 *fileSystemID,   
00310         UInt16 *signature)              
00311 {
00312         OSErr                   result;
00313         FSVolumeInfo    info;
00314         
00315         result = FSGetVolumeInfo(volume, 0, NULL, kFSVolInfoFSInfo, &info, NULL, NULL);
00316         require_noerr(result, FSGetVolumeInfo);
00317         
00318         if ( NULL != fileSystemID )
00319         {
00320                 *fileSystemID = info.filesystemID;
00321         }
00322         if ( NULL != signature )
00323         {
00324                 *signature = info.signature;
00325         }
00326         
00327 FSGetVolumeInfo:
00328 
00329         return ( result );
00330 }
00331 
00332 
00333 
00334 OSErr
00335 FSGetMountedVolumes(
00336         FSRef ***volumeRefsHandle,      
00337         ItemCount *numVolumes)
00338 {
00339         OSErr           result;
00340         OSErr           memResult;
00341         ItemCount       volumeIndex;
00342         FSRef           ref;
00343         
00344         
00345         require_action((NULL != volumeRefsHandle) && (NULL != numVolumes),
00346                 BadParameter, result = paramErr);
00347         
00348         
00349         *numVolumes = 0;
00350         
00351         
00352         *volumeRefsHandle = (FSRef **)NewHandle(0);
00353         require_action(NULL != *volumeRefsHandle, NewHandle, result = memFullErr);
00354         
00355         
00356         volumeIndex = 1;
00357         do
00358         {
00359                 result = FSGetVolumeInfo(0, volumeIndex, NULL, kFSVolInfoNone, NULL, NULL, &ref);
00360                 if ( noErr == result )
00361                 {
00362                         
00363                         PtrAndHand(&ref, (Handle)*volumeRefsHandle, sizeof(FSRef));
00364                         memResult = MemError();
00365                         require_noerr_action(memResult, MemoryAllocationFailed, result = memResult);
00366                         
00367                         ++(*numVolumes);        
00368                         ++volumeIndex;          
00369                 }
00370         } while ( noErr == result );
00371         
00372         
00373         require(nsvErr == result, FSGetVolumeInfo);
00374                 
00375         return ( noErr );
00376         
00377         
00378         
00379 MemoryAllocationFailed:
00380 FSGetVolumeInfo:
00381 
00382         
00383         if ( NULL != *volumeRefsHandle )
00384         {
00385                 DisposeHandle((Handle)*volumeRefsHandle);
00386                 *volumeRefsHandle = NULL;
00387         }
00388         *numVolumes = 0;
00389         
00390 NewHandle:
00391 BadParameter:
00392 
00393         return ( result );
00394 }
00395 
00396 
00397 
00398 #pragma mark ----- FSRef/FSpec/Path/Name Conversion Routines -----
00399 
00400 
00401 
00402 OSErr
00403 FSRefMakeFSSpec(
00404         const FSRef *ref,
00405         FSSpec *spec)
00406 {
00407         OSErr   result;
00408         
00409         
00410         require_action(NULL != spec, BadParameter, result = paramErr);
00411         
00412         result = FSGetCatalogInfo(ref, kFSCatInfoNone, NULL, NULL, spec, NULL);
00413         require_noerr(result, FSGetCatalogInfo);
00414         
00415 FSGetCatalogInfo:
00416 BadParameter:
00417 
00418         return ( result );
00419 }
00420 
00421 
00422 
00423 OSErr
00424 FSMakeFSRef(
00425         FSVolumeRefNum volRefNum,
00426         SInt32 dirID,
00427         ConstStr255Param name,
00428         FSRef *ref)
00429 {
00430         OSErr           result;
00431         FSRefParam      pb;
00432         
00433         
00434         require_action(NULL != ref, BadParameter, result = paramErr);
00435         
00436         pb.ioVRefNum = volRefNum;
00437         pb.ioDirID = dirID;
00438         pb.ioNamePtr = (StringPtr)name;
00439         pb.newRef = ref;
00440         result = PBMakeFSRefSync(&pb);
00441         require_noerr(result, PBMakeFSRefSync);
00442         
00443 PBMakeFSRefSync:
00444 BadParameter:
00445 
00446         return ( result );
00447 }
00448 
00449 
00450 
00451 OSStatus
00452 FSMakePath(
00453         SInt16 volRefNum,
00454         SInt32 dirID,
00455         ConstStr255Param name,
00456         UInt8 *path,
00457         UInt32 maxPathSize)
00458 {
00459         OSStatus        result;
00460         FSRef           ref;
00461         
00462         
00463         require_action(NULL != path, BadParameter, result = paramErr);
00464         
00465         
00466         result = FSMakeFSRef(volRefNum, dirID, name, &ref);
00467         require_noerr(result, FSMakeFSRef);
00468         
00469         
00470         result = FSRefMakePath(&ref, path, maxPathSize);
00471         require_noerr(result, FSRefMakePath);
00472         
00473 FSRefMakePath:
00474 FSMakeFSRef:
00475 BadParameter:
00476 
00477         return ( result );
00478 }
00479 
00480 
00481 
00482 OSStatus
00483 FSPathMakeFSSpec(
00484         const UInt8 *path,
00485         FSSpec *spec,
00486         Boolean *isDirectory)   
00487 {
00488         OSStatus        result;
00489         FSRef           ref;
00490         
00491         
00492         require_action(NULL != spec, BadParameter, result = paramErr);
00493         
00494         
00495         result = FSPathMakeRef(path, &ref, isDirectory);
00496         require_noerr(result, FSPathMakeRef);
00497         
00498         
00499         result = FSGetCatalogInfo(&ref, kFSCatInfoNone, NULL, NULL, spec, NULL);
00500         require_noerr(result, FSGetCatalogInfo);
00501         
00502 FSGetCatalogInfo:
00503 FSPathMakeRef:
00504 BadParameter:
00505 
00506         return ( result );
00507 }
00508 
00509 
00510 
00511 OSErr
00512 UnicodeNameGetHFSName(
00513         UniCharCount nameLength,
00514         const UniChar *name,
00515         TextEncoding textEncodingHint,
00516         Boolean isVolumeName,
00517         Str31 hfsName)
00518 {
00519         OSStatus                        result;
00520         ByteCount                       unicodeByteLength;
00521         ByteCount                       unicodeBytesConverted;
00522         ByteCount                       actualPascalBytes;
00523         UnicodeMapping          uMapping;
00524         UnicodeToTextInfo       utInfo;
00525         
00526         
00527         require_action(NULL != hfsName, BadParameter, result = paramErr);
00528         
00529         
00530         hfsName[0] = 0;
00531         
00532         unicodeByteLength = nameLength * sizeof(UniChar);
00533         if ( 0 == unicodeByteLength )
00534         {
00535                 
00536                 result = noErr;
00537         }
00538         else
00539         {
00540                 
00541                 if ( kTextEncodingUnknown == textEncodingHint )
00542                 {
00543                         ScriptCode                      script;
00544                         RegionCode                      region;
00545                         
00546                         script = (ScriptCode)GetScriptManagerVariable(smSysScript);
00547                         region = (RegionCode)GetScriptManagerVariable(smRegionCode);
00548                         result = UpgradeScriptInfoToTextEncoding(script, kTextLanguageDontCare, region,
00549                                 NULL, &textEncodingHint );
00550                         if ( paramErr == result )
00551                         {
00552                                 
00553                                 result = UpgradeScriptInfoToTextEncoding(script, kTextLanguageDontCare,
00554                                         kTextRegionDontCare, NULL, &textEncodingHint );
00555                         }
00556                         if ( noErr != result )
00557                         {
00558                                 
00559                                 textEncodingHint = kTextEncodingMacRoman;
00560                         }
00561                 }
00562                 
00563                 uMapping.unicodeEncoding = CreateTextEncoding(kTextEncodingUnicodeV2_0,
00564                         kUnicodeCanonicalDecompVariant, kUnicode16BitFormat);
00565                 uMapping.otherEncoding = GetTextEncodingBase(textEncodingHint);
00566                 uMapping.mappingVersion = kUnicodeUseHFSPlusMapping;
00567         
00568                 result = CreateUnicodeToTextInfo(&uMapping, &utInfo);
00569                 require_noerr(result, CreateUnicodeToTextInfo);
00570                 
00571                 result = ConvertFromUnicodeToText(utInfo, unicodeByteLength, name, kUnicodeLooseMappingsMask,
00572                         0, NULL, 0, NULL,       
00573                         isVolumeName ? kHFSMaxVolumeNameChars : kHFSMaxFileNameChars,
00574                         &unicodeBytesConverted, &actualPascalBytes, &hfsName[1]);
00575                 require_noerr(result, ConvertFromUnicodeToText);
00576                 
00577                 hfsName[0] = (unsigned char)actualPascalBytes;  
00578 
00579 ConvertFromUnicodeToText:
00580                 
00581                 
00582                 verify_noerr(DisposeUnicodeToTextInfo(&utInfo));
00583         }
00584         
00585 CreateUnicodeToTextInfo:        
00586 BadParameter:
00587 
00588         return ( result );
00589 }
00590 
00591 
00592 
00593 OSErr
00594 HFSNameGetUnicodeName(
00595         ConstStr31Param hfsName,
00596         TextEncoding textEncodingHint,
00597         HFSUniStr255 *unicodeName)
00598 {
00599         ByteCount                       unicodeByteLength;
00600         OSStatus                        result;
00601         UnicodeMapping          uMapping;
00602         TextToUnicodeInfo       tuInfo;
00603         ByteCount                       pascalCharsRead;
00604         
00605         
00606         require_action(NULL != unicodeName, BadParameter, result = paramErr);
00607         
00608         
00609         unicodeName->length = 0;
00610         
00611         if ( 0 == StrLength(hfsName) )
00612         {
00613                 result = noErr;
00614         }
00615         else
00616         {
00617                 
00618                 if ( kTextEncodingUnknown == textEncodingHint )
00619                 {
00620                         ScriptCode                      script;
00621                         RegionCode                      region;
00622                         
00623                         script = GetScriptManagerVariable(smSysScript);
00624                         region = GetScriptManagerVariable(smRegionCode);
00625                         result = UpgradeScriptInfoToTextEncoding(script, kTextLanguageDontCare, region,
00626                                 NULL, &textEncodingHint);
00627                         if ( paramErr == result )
00628                         {
00629                                 
00630                                 result = UpgradeScriptInfoToTextEncoding(script, kTextLanguageDontCare,
00631                                         kTextRegionDontCare, NULL, &textEncodingHint);
00632                         }
00633                         if ( noErr != result )
00634                         {
00635                                 
00636                                 textEncodingHint = kTextEncodingMacRoman;
00637                         }
00638                 }
00639                 
00640                 uMapping.unicodeEncoding = CreateTextEncoding(kTextEncodingUnicodeV2_0,
00641                         kUnicodeCanonicalDecompVariant, kUnicode16BitFormat);
00642                 uMapping.otherEncoding = GetTextEncodingBase(textEncodingHint);
00643                 uMapping.mappingVersion = kUnicodeUseHFSPlusMapping;
00644         
00645                 result = CreateTextToUnicodeInfo(&uMapping, &tuInfo);
00646                 require_noerr(result, CreateTextToUnicodeInfo);
00647                         
00648                 result = ConvertFromTextToUnicode(tuInfo, hfsName[0], &hfsName[1],
00649                         0,                                                              
00650                         0, NULL, 0, NULL,                               
00651                         sizeof(unicodeName->unicode),   
00652                         &pascalCharsRead, &unicodeByteLength, unicodeName->unicode);
00653                 require_noerr(result, ConvertFromTextToUnicode);
00654                 
00655                 
00656                 unicodeName->length = unicodeByteLength / sizeof(UniChar);
00657 
00658 ConvertFromTextToUnicode:
00659 
00660                 
00661                 verify_noerr(DisposeTextToUnicodeInfo(&tuInfo));
00662         }
00663         
00664 CreateTextToUnicodeInfo:
00665 BadParameter:
00666 
00667         return ( result );
00668 }
00669 
00670 
00671 
00672 #pragma mark ----- File/Directory Manipulation Routines -----
00673 
00674 
00675 
00676 Boolean FSRefValid(const FSRef *ref)
00677 {
00678         return ( noErr == FSGetCatalogInfo(ref, kFSCatInfoNone, NULL, NULL, NULL, NULL) );
00679 }
00680 
00681 
00682 
00683 OSErr
00684 FSGetParentRef(
00685         const FSRef *ref,
00686         FSRef *parentRef)
00687 {
00688         OSErr   result;
00689         FSCatalogInfo   catalogInfo;
00690         
00691         
00692         require_action(NULL != parentRef, BadParameter, result = paramErr);
00693         
00694         result = FSGetCatalogInfo(ref, kFSCatInfoNodeID, &catalogInfo, NULL, NULL, parentRef);
00695         require_noerr(result, FSGetCatalogInfo);
00696         
00697         
00698 
00699 
00700 
00701 
00702 
00703 
00704 
00705         if ( fsRtDirID == catalogInfo.nodeID )
00706         {
00707                 
00708                 memset(parentRef, 0, sizeof(FSRef));
00709         }
00710 
00711 FSGetCatalogInfo:
00712 BadParameter:
00713 
00714         return ( result );
00715 }
00716 
00717 
00718 
00719 OSErr
00720 FSGetFileDirName(
00721         const FSRef *ref,
00722         HFSUniStr255 *outName)
00723 {
00724         OSErr   result;
00725         
00726         
00727         require_action(NULL != outName, BadParameter, result = paramErr);
00728         
00729         result = FSGetCatalogInfo(ref, kFSCatInfoNone, NULL, outName, NULL, NULL);
00730         require_noerr(result, FSGetCatalogInfo);
00731         
00732 FSGetCatalogInfo:
00733 BadParameter:
00734 
00735         return ( result );
00736 }
00737 
00738 
00739 
00740 OSErr
00741 FSGetNodeID(
00742         const FSRef *ref,
00743         long *nodeID,                   
00744         Boolean *isDirectory)   
00745 {
00746         OSErr                           result;
00747         FSCatalogInfo           catalogInfo;
00748         FSCatalogInfoBitmap whichInfo;
00749         
00750         
00751         whichInfo = kFSCatInfoNone; 
00752         if ( NULL != nodeID )
00753         {
00754                 whichInfo |= kFSCatInfoNodeID;
00755         }
00756         if ( NULL != isDirectory )
00757         {
00758                 whichInfo |= kFSCatInfoNodeFlags;
00759         }
00760         
00761         result = FSGetCatalogInfo(ref, whichInfo, &catalogInfo, NULL, NULL, NULL);
00762         require_noerr(result, FSGetCatalogInfo);
00763         
00764         if ( NULL != nodeID )
00765         {
00766                 *nodeID = catalogInfo.nodeID;
00767         }
00768         if ( NULL != isDirectory )
00769         {
00770                 *isDirectory = (0 != (kFSNodeIsDirectoryMask & catalogInfo.nodeFlags));
00771         }
00772         
00773 FSGetCatalogInfo:
00774 
00775         return ( result );
00776 }
00777 
00778 
00779 
00780 OSErr
00781 FSGetUserPrivilegesPermissions(
00782         const FSRef *ref,
00783         UInt8 *userPrivileges,          
00784         UInt32 permissions[4])          
00785 {
00786         OSErr                   result;
00787         FSCatalogInfo   catalogInfo;
00788         FSCatalogInfoBitmap whichInfo;
00789         
00790         
00791         whichInfo = kFSCatInfoNone; 
00792         if ( NULL != userPrivileges )
00793         {
00794                 whichInfo |= kFSCatInfoUserPrivs;
00795         }
00796         if ( NULL != permissions )
00797         {
00798                 whichInfo |= kFSCatInfoPermissions;
00799         }
00800         
00801         result = FSGetCatalogInfo(ref, whichInfo, &catalogInfo, NULL, NULL, NULL);
00802         require_noerr(result, FSGetCatalogInfo);
00803         
00804         if ( NULL != userPrivileges )
00805         {
00806                 *userPrivileges = catalogInfo.userPrivileges;
00807         }
00808         if ( NULL != permissions )
00809         {
00810                 BlockMoveData(&catalogInfo.permissions, permissions, sizeof(UInt32) * 4);
00811         }
00812         
00813 FSGetCatalogInfo:
00814 
00815         return ( result );
00816 }
00817 
00818 
00819 
00820 OSErr
00821 FSCheckLock(
00822         const FSRef *ref)
00823 {
00824         OSErr                   result;
00825         FSCatalogInfo   catalogInfo;
00826         FSVolumeInfo    volumeInfo;
00827         
00828         
00829         result = FSGetCatalogInfo(ref, kFSCatInfoNodeFlags + kFSCatInfoVolume, &catalogInfo, NULL, NULL,NULL);
00830         require_noerr(result, FSGetCatalogInfo);
00831         
00832         
00833         if ( 0 != (catalogInfo.nodeFlags & kFSNodeLockedMask) )
00834         {
00835                 result = fLckdErr;      
00836         }
00837         else
00838         {
00839                 
00840                 
00841                 
00842                 result = FSGetVolumeInfo(catalogInfo.volume, 0, NULL, kFSVolInfoFlags, &volumeInfo, NULL, NULL);
00843                 require_noerr(result, FSGetVolumeInfo);
00844                 
00845                 if ( 0 != (volumeInfo.flags & kFSVolFlagHardwareLockedMask) )
00846                 {
00847                         result = wPrErr;        
00848                 }
00849                 else if ( 0 != (volumeInfo.flags & kFSVolFlagSoftwareLockedMask) )
00850                 {
00851                         result = vLckdErr;      
00852                 }
00853         }
00854         
00855 FSGetVolumeInfo:
00856 FSGetCatalogInfo:
00857 
00858         return ( result );
00859 }
00860 
00861 
00862 
00863 OSErr
00864 FSGetForkSizes(
00865         const FSRef *ref,
00866         UInt64 *dataLogicalSize,        
00867         UInt64 *rsrcLogicalSize)        
00868 {
00869         OSErr                           result;
00870         FSCatalogInfoBitmap whichInfo;
00871         FSCatalogInfo           catalogInfo;
00872         
00873         whichInfo = kFSCatInfoNodeFlags;
00874         if ( NULL != dataLogicalSize )
00875         {
00876                 
00877                 whichInfo |= kFSCatInfoDataSizes;
00878         }
00879         if ( NULL != rsrcLogicalSize )
00880         {
00881                 
00882                 whichInfo |= kFSCatInfoRsrcSizes;
00883         }
00884 
00885         
00886         result = FSGetCatalogInfo(ref, whichInfo, &catalogInfo, NULL, NULL,NULL);
00887         require_noerr(result, FSGetCatalogInfo);
00888         
00889         
00890         require_action(0 == (catalogInfo.nodeFlags & kFSNodeIsDirectoryMask), FSRefNotFile, result = notAFileErr);
00891         
00892         if ( NULL != dataLogicalSize )
00893         {
00894                 
00895                 *dataLogicalSize = catalogInfo.dataLogicalSize;
00896         }
00897         if ( NULL != rsrcLogicalSize )
00898         {
00899                 
00900                 *rsrcLogicalSize = catalogInfo.rsrcLogicalSize;
00901         }
00902         
00903 FSRefNotFile:
00904 FSGetCatalogInfo:
00905 
00906         return ( result );
00907 }
00908 
00909 
00910 
00911 OSErr
00912 FSGetTotalForkSizes(
00913         const FSRef *ref,
00914         UInt64 *totalLogicalSize,       
00915         UInt64 *totalPhysicalSize,      
00916         ItemCount *forkCount)           
00917 {
00918         OSErr                   result;
00919         CatPositionRec  forkIterator;
00920         SInt64                  forkSize;
00921         SInt64                  *forkSizePtr;
00922         UInt64                  forkPhysicalSize;
00923         UInt64                  *forkPhysicalSizePtr;
00924         
00925         
00926         if ( NULL != totalLogicalSize)
00927         {
00928                 *totalLogicalSize = 0;
00929                 forkSizePtr = &forkSize;
00930         }
00931         else
00932         {
00933                 forkSizePtr = NULL;
00934         }
00935         
00936         
00937         if ( NULL != totalPhysicalSize )
00938         {
00939                 *totalPhysicalSize = 0;
00940                 forkPhysicalSizePtr = &forkPhysicalSize;
00941         }
00942         else
00943         {
00944                 forkPhysicalSizePtr = NULL;
00945         }
00946         
00947         
00948         if ( NULL != forkCount )
00949         {
00950                 *forkCount = 0;
00951         }
00952         
00953         
00954         forkIterator.initialize = 0;
00955         do
00956         {
00957                 result = FSIterateForks(ref, &forkIterator, NULL, forkSizePtr, forkPhysicalSizePtr);
00958                 if ( noErr == result )
00959                 {
00960                         if ( NULL != totalLogicalSize )
00961                         {
00962                                 *totalLogicalSize += forkSize;
00963                         }
00964                         
00965                         if ( NULL != totalPhysicalSize )
00966                         {
00967                                 *totalPhysicalSize += forkPhysicalSize;
00968                         }
00969                         
00970                         if ( NULL != forkCount )
00971                         {
00972                                 ++*forkCount;
00973                         }
00974                 }
00975         } while ( noErr == result );
00976         
00977         
00978         require(errFSNoMoreItems == result, FSIterateForks);
00979         
00980         
00981         result = noErr;
00982 
00983 FSIterateForks:
00984         
00985         return ( result );
00986 }
00987 
00988 
00989 
00990 OSErr
00991 FSBumpDate(
00992         const FSRef *ref)
00993 {
00994         OSStatus                result;
00995         FSCatalogInfo   catalogInfo;
00996         UTCDateTime             oldDateTime;
00997 #if !BuildingMoreFilesXForMacOS9
00998         FSRef                   parentRef;
00999         Boolean                 notifyParent;
01000 #endif
01001 
01002 #if !BuildingMoreFilesXForMacOS9
01003         
01004         result = FSGetCatalogInfo(ref, kFSCatInfoNodeFlags + kFSCatInfoContentMod, &catalogInfo, NULL, NULL, &parentRef);
01005         require_noerr(result, FSGetCatalogInfo);
01006         
01007         
01008         notifyParent = (0 == (catalogInfo.nodeFlags & kFSNodeIsDirectoryMask));
01009 #else
01010         
01011         result = FSGetCatalogInfo(ref, kFSCatInfoContentMod, &catalogInfo, NULL, NULL, NULL);
01012         require_noerr(result, FSGetCatalogInfo);
01013 #endif
01014         
01015         oldDateTime = catalogInfo.contentModDate;
01016 
01017         
01018         result = GetUTCDateTime(&catalogInfo.contentModDate, kUTCDefaultOptions);
01019         require_noerr(result, GetUTCDateTime);
01020         
01021         
01022         if ( (catalogInfo.contentModDate.fraction == oldDateTime.fraction) &&
01023                  (catalogInfo.contentModDate.lowSeconds == oldDateTime.lowSeconds) &&
01024                  (catalogInfo.contentModDate.highSeconds == oldDateTime.highSeconds) )
01025         {
01026                 ++catalogInfo.contentModDate.lowSeconds;
01027                 if ( 0 == catalogInfo.contentModDate.lowSeconds )
01028                 {
01029                         ++catalogInfo.contentModDate.highSeconds;
01030                 }
01031         }
01032         
01033         
01034         result = FSSetCatalogInfo(ref, kFSCatInfoContentMod, &catalogInfo);
01035         require_noerr(result, FSSetCatalogInfo);
01036 
01037 #if !BuildingMoreFilesXForMacOS9
01038         
01039 
01040 
01041 
01042 
01043 
01044         
01045         
01046         result = FNNotify(notifyParent ? &parentRef : ref, kFNDirectoryModifiedMessage, kNilOptions);
01047         require_noerr(result, FNNotify);
01048 #endif
01049 
01050         
01051 FNNotify:
01052 FSSetCatalogInfo:
01053         
01054         return ( noErr );
01055         
01056         
01057         
01058 GetUTCDateTime:
01059 FSGetCatalogInfo:
01060 
01061         return ( result );
01062 }
01063 
01064 
01065 
01066 OSErr
01067 FSGetFinderInfo(
01068         const FSRef *ref,
01069         FinderInfo *info,                                       
01070         ExtendedFinderInfo *extendedInfo,       
01071         Boolean *isDirectory)                           
01072 {
01073         OSErr                           result;
01074         FSCatalogInfo           catalogInfo;
01075         FSCatalogInfoBitmap whichInfo;
01076         
01077         
01078         whichInfo = kFSCatInfoNone;
01079         
01080         if ( NULL != info )
01081         {
01082                 
01083                 whichInfo |= kFSCatInfoFinderInfo;
01084         }
01085         
01086         if ( NULL != extendedInfo )
01087         {
01088                 
01089                 whichInfo |= kFSCatInfoFinderXInfo;
01090         }
01091         
01092         if ( NULL != isDirectory )
01093         {
01094                 whichInfo |= kFSCatInfoNodeFlags;
01095         }
01096         
01097         result = FSGetCatalogInfo(ref, whichInfo, &catalogInfo, NULL, NULL, NULL);
01098         require_noerr(result, FSGetCatalogInfo);
01099         
01100         
01101         if ( NULL != info )
01102         {
01103                 BlockMoveData(catalogInfo.finderInfo, info, sizeof(FinderInfo));
01104         }
01105         
01106         
01107         if ( NULL != extendedInfo)
01108         {
01109                 BlockMoveData(catalogInfo.extFinderInfo, extendedInfo, sizeof(ExtendedFinderInfo));
01110         }
01111         
01112         
01113         if ( NULL != isDirectory)
01114         {
01115                 *isDirectory = (0 != (kFSNodeIsDirectoryMask & catalogInfo.nodeFlags));
01116         }
01117         
01118 FSGetCatalogInfo:
01119 
01120         return ( result );
01121 }
01122 
01123 
01124 
01125 OSErr
01126 FSSetFinderInfo(
01127         const FSRef *ref,
01128         const FinderInfo *info,
01129         const ExtendedFinderInfo *extendedInfo)
01130 {
01131         OSErr                           result;
01132         FSCatalogInfo           catalogInfo;
01133         FSCatalogInfoBitmap whichInfo;
01134         
01135         
01136         whichInfo = kFSCatInfoNone; 
01137         if ( NULL != info )
01138         {
01139                 
01140                 whichInfo |= kFSCatInfoFinderInfo;
01141                 BlockMoveData(info, catalogInfo.finderInfo, sizeof(FinderInfo));
01142         }
01143         if ( NULL != extendedInfo )
01144         {
01145                 
01146                 whichInfo |= kFSCatInfoFinderXInfo;
01147                 BlockMoveData(extendedInfo, catalogInfo.extFinderInfo, sizeof(ExtendedFinderInfo));
01148         }
01149         
01150         result = FSSetCatalogInfo(ref, whichInfo, &catalogInfo);
01151         require_noerr(result, FSGetCatalogInfo);
01152         
01153 FSGetCatalogInfo:
01154 
01155         return ( result );
01156 }
01157 
01158 
01159 
01160 OSErr
01161 FSChangeCreatorType(
01162         const FSRef *ref,
01163         OSType fileCreator,
01164         OSType fileType)
01165 {
01166         OSErr                   result;
01167         FSCatalogInfo   catalogInfo;
01168         FSRef                   parentRef;
01169         
01170         
01171         result = FSGetCatalogInfo(ref, kFSCatInfoNodeFlags + kFSCatInfoFinderInfo, &catalogInfo , NULL, NULL, &parentRef);
01172         require_noerr(result, FSGetCatalogInfo);
01173         
01174         
01175         require_action(0 == (catalogInfo.nodeFlags & kFSNodeIsDirectoryMask), FSRefNotFile, result = notAFileErr);
01176         
01177         
01178         if ( fileType != (OSType)0x00000000 )
01179         {
01180                 ((FileInfo *)&catalogInfo.finderInfo)->fileType = fileType;
01181         }
01182         
01183         
01184         if ( fileCreator != (OSType)0x00000000 )
01185         {
01186                 ((FileInfo *)&catalogInfo.finderInfo)->fileCreator = fileCreator;
01187         }
01188         
01189         
01190         result = FSSetCatalogInfo(ref, kFSCatInfoFinderInfo, &catalogInfo);
01191         require_noerr(result, FSSetCatalogInfo);
01192         
01193         
01194         
01195         verify_noerr(FSBumpDate(&parentRef));
01196         
01197 FSSetCatalogInfo:
01198 FSRefNotFile:
01199 FSGetCatalogInfo:
01200 
01201         return ( result );
01202 }
01203 
01204 
01205 
01206 OSErr
01207 FSChangeFinderFlags(
01208         const FSRef *ref,
01209         Boolean setBits,
01210         UInt16 flagBits)
01211 {
01212         OSErr                   result;
01213         FSCatalogInfo   catalogInfo;
01214         FSRef                   parentRef;
01215         
01216         
01217         result = FSGetCatalogInfo(ref, kFSCatInfoFinderInfo, &catalogInfo, NULL, NULL, &parentRef);
01218         require_noerr(result, FSGetCatalogInfo);
01219         
01220         
01221         if ( setBits )
01222         {
01223                 
01224                 ((FileInfo *)&catalogInfo.finderInfo)->finderFlags |= flagBits;
01225         }
01226         else
01227         {
01228                 
01229                 ((FileInfo *)&catalogInfo.finderInfo)->finderFlags &= ~flagBits;
01230         }
01231         
01232         
01233         result = FSSetCatalogInfo(ref, kFSCatInfoFinderInfo, &catalogInfo);
01234         require_noerr(result, FSSetCatalogInfo);
01235         
01236         
01237         
01238         verify_noerr(FSBumpDate(&parentRef));
01239         
01240 FSSetCatalogInfo:
01241 FSGetCatalogInfo:
01242 
01243         return ( result );
01244 }
01245 
01246 
01247 
01248 OSErr
01249 FSSetInvisible(
01250         const FSRef *ref)
01251 {
01252         return ( FSChangeFinderFlags(ref, true, kIsInvisible) );
01253 }
01254 
01255 OSErr
01256 FSClearInvisible(
01257         const FSRef *ref)
01258 {
01259         return ( FSChangeFinderFlags(ref, false, kIsInvisible) );
01260 }
01261 
01262 
01263 
01264 OSErr
01265 FSSetNameLocked(
01266         const FSRef *ref)
01267 {
01268         return ( FSChangeFinderFlags(ref, true, kNameLocked) );
01269 }
01270 
01271 OSErr
01272 FSClearNameLocked(
01273         const FSRef *ref)
01274 {
01275         return ( FSChangeFinderFlags(ref, false, kNameLocked) );
01276 }
01277 
01278 
01279 
01280 OSErr
01281 FSSetIsStationery(
01282         const FSRef *ref)
01283 {
01284         return ( FSChangeFinderFlags(ref, true, kIsStationery) );
01285 }
01286 
01287 OSErr
01288 FSClearIsStationery(
01289         const FSRef *ref)
01290 {
01291         return ( FSChangeFinderFlags(ref, false, kIsStationery) );
01292 }
01293 
01294 
01295 
01296 OSErr
01297 FSSetHasCustomIcon(
01298         const FSRef *ref)
01299 {
01300         return ( FSChangeFinderFlags(ref, true, kHasCustomIcon) );
01301 }
01302 
01303 OSErr
01304 FSClearHasCustomIcon(
01305         const FSRef *ref)
01306 {
01307         return ( FSChangeFinderFlags(ref, false, kHasCustomIcon) );
01308 }
01309 
01310 
01311 
01312 OSErr
01313 FSClearHasBeenInited(
01314         const FSRef *ref)
01315 {
01316         return ( FSChangeFinderFlags(ref, false, kHasBeenInited) );
01317 }
01318 
01319 
01320 
01321 OSErr
01322 FSCopyFileMgrAttributes(
01323         const FSRef *sourceRef,
01324         const FSRef *destinationRef,
01325         Boolean copyLockBit)
01326 {
01327         OSErr                   result;
01328         FSCatalogInfo   catalogInfo;
01329         
01330         
01331         result = FSGetCatalogInfo(sourceRef, kFSCatInfoSettableInfo, &catalogInfo, NULL, NULL, NULL);
01332         require_noerr(result, FSGetCatalogInfo);
01333         
01334         
01335         ((FileInfo *)&catalogInfo.finderInfo)->finderFlags &= ~kHasBeenInited;
01336         
01337         
01338         if ( !copyLockBit )
01339         {
01340                 
01341                 catalogInfo.nodeFlags &= ~kFSNodeLockedMask;
01342         }
01343                 
01344         
01345         result = FSSetCatalogInfo(destinationRef, kFSCatInfoSettableInfo, &catalogInfo);
01346         require_noerr(result, FSSetCatalogInfo);
01347         
01348 FSSetCatalogInfo:
01349 FSGetCatalogInfo:
01350 
01351         return ( result );
01352 }
01353 
01354 
01355 
01356 OSErr
01357 FSMoveRenameObjectUnicode(
01358         const FSRef *ref,
01359         const FSRef *destDirectory,
01360         UniCharCount nameLength,
01361         const UniChar *name,                    
01362         TextEncoding textEncodingHint,
01363         FSRef *newRef)                                  
01364 {
01365         OSErr                   result;
01366         FSVolumeRefNum  vRefNum;
01367         FSCatalogInfo   catalogInfo;
01368         FSRef                   originalDirectory;
01369         TextEncoding    originalTextEncodingHint;
01370         HFSUniStr255    originalName;
01371         HFSUniStr255    uniqueName;             
01372         long                    theSeed;                
01373         
01374         
01375         require_action(NULL != newRef, BadParameter, result = paramErr);
01376         
01377         
01378         BlockMoveData(ref, newRef, sizeof(FSRef));
01379         
01380         
01381         result = FSGetCatalogInfo(destDirectory, kFSCatInfoVolume, &catalogInfo, NULL, NULL, NULL);
01382         require_noerr(result, DestinationBad);
01383         
01384         
01385         vRefNum = catalogInfo.volume;
01386         
01387         
01388         result = FSGetCatalogInfo(ref, kFSCatInfoTextEncoding + kFSCatInfoVolume, &catalogInfo, &originalName, NULL, &originalDirectory);
01389         require_noerr(result, SourceBad);
01390         
01391         
01392         originalTextEncodingHint = catalogInfo.textEncodingHint;
01393         
01394         
01395         require_action(vRefNum == catalogInfo.volume, NotSameVolume, result = diffVolErr);
01396         
01397         
01398         if ( NULL != name )
01399         {
01400                 
01401                 theSeed = 0x4a696d4c;   
01402                 
01403                 result = GenerateUniqueHFSUniStr(&theSeed, &originalDirectory, destDirectory, &uniqueName);
01404                 require_noerr(result, GenerateUniqueHFSUniStrFailed);
01405                 
01406                 
01407                 result = FSRenameUnicode(ref, uniqueName.length, uniqueName.unicode, kTextEncodingUnknown, newRef);
01408                 require_noerr(result, FSRenameUnicodeBeforeMoveFailed);
01409                 
01410                 
01411                 result = FSMoveObject(newRef, destDirectory, newRef);
01412                 require_noerr(result, FSMoveObjectAfterRenameFailed);
01413                 
01414                 
01415                 result = FSRenameUnicode(ref, nameLength, name, textEncodingHint, newRef);
01416                 require_noerr(result, FSRenameUnicodeAfterMoveFailed);
01417         }
01418         else
01419         {
01420                 
01421                 result = FSMoveObject(newRef, destDirectory, newRef);
01422                 require_noerr(result, FSMoveObjectNoRenameFailed);
01423         }
01424         
01425         return ( result );
01426         
01427         
01428 
01429 
01430 
01431 
01432 
01433 FSRenameUnicodeAfterMoveFailed:
01434 
01435         
01436         verify_noerr(FSMoveObject(newRef, &originalDirectory, newRef));
01437         
01438 FSMoveObjectAfterRenameFailed:
01439 
01440         
01441         verify_noerr(FSRenameUnicode(newRef, originalName.length, originalName.unicode, originalTextEncodingHint, newRef));
01442         
01443 FSRenameUnicodeBeforeMoveFailed:
01444 GenerateUniqueHFSUniStrFailed:
01445 
01446 
01447 
01448 
01449 FSMoveObjectNoRenameFailed:
01450 NotSameVolume:
01451 SourceBad:
01452 DestinationBad:
01453 BadParameter:
01454 
01455         return ( result );
01456 }
01457 
01458 
01459 
01460 
01461 
01462 
01463 
01464 
01465 
01466 
01467 
01468 
01469 
01470 
01471 
01472 
01473 
01474 
01475 static
01476 void
01477 FSDeleteContainerLevel(
01478         const FSRef *container,
01479         FSDeleteContainerGlobals *theGlobals)
01480 {
01481         
01482         FSIterator                                      iterator;
01483         FSRef                                           itemToDelete;
01484         UInt16                                          nodeFlags;
01485         
01486         
01487         theGlobals->result = FSOpenIterator(container, kFSIterateFlat + kFSIterateDelete, &iterator);
01488         require_noerr(theGlobals->result, FSOpenIterator);
01489         
01490         
01491         do
01492         {
01493                 
01494                 theGlobals->result = FSGetCatalogInfoBulk(iterator, 1, &theGlobals->actualObjects,
01495                                                                 NULL, kFSCatInfoNodeFlags, &theGlobals->catalogInfo,
01496                                                                 &itemToDelete, NULL, NULL);
01497                 if ( (noErr == theGlobals->result) && (1 == theGlobals->actualObjects) )
01498                 {
01499                         
01500                         nodeFlags = theGlobals->catalogInfo.nodeFlags;
01501                         
01502                         
01503                         if ( 0 != (nodeFlags & kFSNodeIsDirectoryMask) )
01504                         {
01505                                 
01506                                 FSDeleteContainerLevel(&itemToDelete, theGlobals);
01507                         }
01508                         
01509                         if ( noErr == theGlobals->result )
01510                         {
01511                                 
01512                                 if ( 0 != (nodeFlags & kFSNodeLockedMask) )
01513                                 {
01514                                         
01515                                         theGlobals->catalogInfo.nodeFlags = nodeFlags & ~kFSNodeLockedMask;
01516                                         (void) FSSetCatalogInfo(&itemToDelete, kFSCatInfoNodeFlags, &theGlobals->catalogInfo);
01517                                 }
01518                                 
01519                                 theGlobals->result = FSDeleteObject(&itemToDelete);
01520                         }
01521                 }
01522         } while ( noErr == theGlobals->result );
01523         
01524         
01525         if ( errFSNoMoreItems == theGlobals->result )
01526         {
01527                 theGlobals->result = noErr;
01528         }
01529         
01530         
01531         verify_noerr(FSCloseIterator(iterator));
01532 
01533 FSOpenIterator:
01534 
01535         return;
01536 }
01537 
01538 
01539 
01540 OSErr
01541 FSDeleteContainerContents(
01542         const FSRef *container)
01543 {
01544         FSDeleteContainerGlobals        theGlobals;
01545         
01546         
01547         FSDeleteContainerLevel(container, &theGlobals);
01548         
01549         return ( theGlobals.result );
01550 }
01551 
01552 
01553 
01554 OSErr
01555 FSDeleteContainer(
01556         const FSRef *container)
01557 {
01558         OSErr                   result;
01559         FSCatalogInfo   catalogInfo;
01560         
01561         
01562         result = FSGetCatalogInfo(container, kFSCatInfoNodeFlags, &catalogInfo, NULL, NULL,NULL);
01563         require_noerr(result, FSGetCatalogInfo);
01564         
01565         
01566         require_action(0 != (catalogInfo.nodeFlags & kFSNodeIsDirectoryMask), ContainerNotDirectory, result = dirNFErr);
01567         
01568         
01569         result = FSDeleteContainerContents(container);
01570         require_noerr(result, FSDeleteContainerContents);
01571         
01572         
01573         if ( 0 != (catalogInfo.nodeFlags & kFSNodeLockedMask) )
01574         {
01575                 
01576                 catalogInfo.nodeFlags &= ~kFSNodeLockedMask;
01577                 (void) FSSetCatalogInfo(container, kFSCatInfoNodeFlags, &catalogInfo);
01578         }
01579         
01580         
01581         result = FSDeleteObject(container);
01582         
01583 FSDeleteContainerContents:
01584 ContainerNotDirectory:
01585 FSGetCatalogInfo:
01586 
01587         return ( result );
01588 }
01589 
01590 
01591 
01592 
01593 
01594 
01595 
01596 
01597 
01598 
01599 
01600 
01601 
01602 
01603 
01604 
01605 
01606 
01607 
01608 static
01609 void
01610 FSIterateContainerLevel(
01611         FSIterateContainerGlobals *theGlobals)
01612 {       
01613         FSIterator      iterator;
01614         
01615         
01616         
01617         if ( (theGlobals->maxLevels == 0) ||
01618                  (theGlobals->currentLevel < theGlobals->maxLevels) )
01619         {
01620                 
01621                 theGlobals->result = FSOpenIterator(&theGlobals->ref, kFSIterateFlat, &iterator);
01622                 require_noerr(theGlobals->result, FSOpenIterator);
01623                 
01624                 ++theGlobals->currentLevel; 
01625                 
01626                 
01627                 do
01628                 {
01629                         theGlobals->result = FSGetCatalogInfoBulk(iterator, 1, &theGlobals->actualObjects,
01630                                 &theGlobals->containerChanged, theGlobals->whichInfo, &theGlobals->catalogInfo,
01631                                 &theGlobals->ref, theGlobals->specPtr, theGlobals->namePtr);
01632                         if ( (noErr == theGlobals->result || errFSNoMoreItems == theGlobals->result) &&
01633                                 (0 != theGlobals->actualObjects) )
01634                         {
01635                                 
01636                                 theGlobals->quitFlag = CallIterateContainerFilterProc(theGlobals->iterateFilter,
01637                                         theGlobals->containerChanged, theGlobals->currentLevel,
01638                                         &theGlobals->catalogInfo, &theGlobals->ref,
01639                                         theGlobals->specPtr, theGlobals->namePtr, theGlobals->yourDataPtr);
01640                                 
01641                                 if ( 0 != (theGlobals->catalogInfo.nodeFlags & kFSNodeIsDirectoryMask) )
01642                                 {
01643                                         
01644                                         if ( !theGlobals->quitFlag )
01645                                         {
01646                                                 
01647                                                 FSIterateContainerLevel(theGlobals);
01648                                         }
01649                                 }
01650                         }
01651                         
01652                 } while ( (noErr == theGlobals->result) && (!theGlobals->quitFlag) );
01653                 
01654                 
01655                 
01656                 if ( (errFSNoMoreItems == theGlobals->result) ||
01657                          (afpAccessDenied == theGlobals->result) )
01658                 {
01659                         theGlobals->result = noErr;
01660                 }
01661                 
01662                 --theGlobals->currentLevel; 
01663                 
01664                 
01665                 verify_noerr(FSCloseIterator(iterator));
01666         }
01667         
01668 FSOpenIterator:
01669 
01670         return;
01671 }
01672 
01673 
01674 
01675 OSErr
01676 FSIterateContainer(
01677         const FSRef *container,
01678         ItemCount maxLevels,
01679         FSCatalogInfoBitmap whichInfo,
01680         Boolean wantFSSpec,
01681         Boolean wantName,
01682         IterateContainerFilterProcPtr iterateFilter,
01683         void *yourDataPtr)
01684 {
01685         OSErr                                           result;
01686         FSIterateContainerGlobals       theGlobals;
01687         
01688         
01689         require_action(iterateFilter != NULL, NoIterateFilter, result = paramErr);
01690         
01691         
01692 
01693 
01694         theGlobals.iterateFilter = iterateFilter;
01695         
01696         theGlobals.whichInfo = whichInfo | kFSCatInfoNodeFlags;
01697         
01698         theGlobals.ref = *container;
01699         if ( wantFSSpec )
01700         {
01701                 theGlobals.specPtr = &theGlobals.spec;
01702         }
01703         else
01704         {
01705                 theGlobals.specPtr = NULL;
01706         }
01707         if ( wantName )
01708         {
01709                 theGlobals.namePtr = &theGlobals.name;
01710         }
01711         else
01712         {
01713                 theGlobals.namePtr = NULL;
01714         }
01715         theGlobals.yourDataPtr = yourDataPtr;
01716         theGlobals.maxLevels = maxLevels;
01717         theGlobals.currentLevel = 0;
01718         theGlobals.quitFlag = false;
01719         theGlobals.containerChanged = false;
01720         theGlobals.result = noErr;
01721         theGlobals.actualObjects = 0;
01722         
01723         
01724         FSIterateContainerLevel(&theGlobals);
01725         result = theGlobals.result;
01726         require_noerr(result, FSIterateContainerLevel);
01727         
01728 FSIterateContainerLevel:
01729 NoIterateFilter:
01730 
01731         return ( result );
01732 }
01733 
01734 
01735 
01736 OSErr
01737 FSGetDirectoryItems(
01738         const FSRef *container,
01739         FSRef ***refsHandle,    
01740         ItemCount *numRefs,
01741         Boolean *containerChanged)
01742 {
01743         
01744         enum { kMaxItemsPerBulkCall = 10 };
01745         
01746         OSErr           result;
01747         OSErr           memResult;
01748         FSIterator      iterator;
01749         FSRef           refs[kMaxItemsPerBulkCall];
01750         ItemCount       actualObjects;
01751         Boolean         changed;
01752         
01753         
01754         require_action((NULL != refsHandle) && (NULL != numRefs) && (NULL != containerChanged),
01755                 BadParameter, result = paramErr);
01756         
01757         *numRefs = 0;
01758         *containerChanged = false;
01759         *refsHandle = (FSRef **)NewHandle(0);
01760         require_action(NULL != *refsHandle, NewHandle, result = memFullErr);
01761         
01762         
01763         result = FSOpenIterator(container, kFSIterateFlat, &iterator);
01764         require_noerr(result, FSOpenIterator);
01765         
01766         
01767         do
01768         {
01769                 result = FSGetCatalogInfoBulk(iterator, kMaxItemsPerBulkCall, &actualObjects,
01770                                         &changed, kFSCatInfoNone,  NULL,  refs, NULL, NULL);
01771                 
01772                 
01773                 if ( changed )
01774                 {
01775                         *containerChanged = changed;
01776                 }
01777                 
01778                 
01779                 require((noErr == result) || (errFSNoMoreItems == result), FSGetCatalogInfoBulk);
01780                 
01781                 
01782                 if ( 0 != actualObjects )
01783                 {
01784                         
01785                         PtrAndHand(refs, (Handle)*refsHandle, actualObjects * sizeof(FSRef));
01786                         memResult = MemError();
01787                         require_noerr_action(memResult, MemoryAllocationFailed, result = memResult);
01788                         
01789                         *numRefs += actualObjects;
01790                 }
01791         } while ( noErr == result );
01792         
01793         verify_noerr(FSCloseIterator(iterator)); 
01794         
01795         return ( noErr );
01796         
01797         
01798         
01799 MemoryAllocationFailed:
01800 FSGetCatalogInfoBulk:
01801 
01802         
01803         verify_noerr(FSCloseIterator(iterator));
01804 
01805 FSOpenIterator:
01806         
01807         if ( NULL != *refsHandle )
01808         {
01809                 DisposeHandle((Handle)*refsHandle);
01810                 *refsHandle = NULL;
01811         }
01812         *numRefs = 0;
01813         
01814 NewHandle:
01815 BadParameter:
01816 
01817         return ( result );
01818 }
01819 
01820 
01821 
01822 
01823 
01824 
01825 
01826 
01827 
01828 
01829 
01830 
01831 
01832 
01833 
01834 
01835 
01836 static
01837 OSErr
01838 GenerateUniqueHFSUniStr(
01839         long *startSeed,
01840         const FSRef *dir1,
01841         const FSRef *dir2,
01842         HFSUniStr255 *uniqueName)
01843 {
01844         OSErr                   result;
01845         long                    i;
01846         FSRefParam              pb;
01847         FSRef                   newRef;
01848         unsigned char   hexStr[17] = "0123456789ABCDEF";                
01849         
01850         
01851         pb.name = uniqueName->unicode;
01852         pb.nameLength = 8;      
01853         pb.textEncodingHint = kTextEncodingUnknown;
01854         pb.newRef = &newRef;
01855 
01856         
01857         result = noErr;
01858         while ( fnfErr != result )
01859         {
01860                 
01861                 uniqueName->length = 8;
01862                 for ( i = 0; i < 8; ++i )
01863                 {
01864                         uniqueName->unicode[i] = hexStr[((*startSeed >> ((7-i)*4)) & 0xf)];
01865                 }
01866                 
01867                 
01868                 pb.ref = dir1;
01869                 result = PBMakeFSRefUnicodeSync(&pb);
01870                 if ( fnfErr == result )
01871                 {
01872                         
01873                         pb.ref = dir2;
01874                         result = PBMakeFSRefUnicodeSync(&pb);
01875                         if ( fnfErr != result )
01876                         {
01877                                 
01878                                 require_noerr(result, Dir2PBMakeFSRefUnicodeSyncFailed);
01879                         }
01880                 }
01881                 else
01882                 {
01883                         
01884                         require_noerr(result, Dir1PBMakeFSRefUnicodeSyncFailed);
01885                 }
01886                 
01887                 
01888                 
01889                 ++(*startSeed);
01890         }
01891         
01892         
01893         result = noErr;
01894         
01895 Dir2PBMakeFSRefUnicodeSyncFailed:
01896 Dir1PBMakeFSRefUnicodeSyncFailed:
01897 
01898         return ( result );
01899 }
01900 
01901 
01902 
01903 OSErr
01904 FSExchangeObjectsCompat(
01905         const FSRef *sourceRef,
01906         const FSRef *destRef,
01907         FSRef *newSourceRef,
01908         FSRef *newDestRef)
01909 {
01910         enum
01911         {
01912                 
01913                 kGetCatInformationMask = (kFSCatInfoSettableInfo |
01914                                                                   kFSCatInfoVolume |
01915                                                                   kFSCatInfoParentDirID) &
01916                                                                  ~(kFSCatInfoContentMod | kFSCatInfoAttrMod),
01917                 
01918                 kSetCatinformationMask = kFSCatInfoSettableInfo &
01919                                                                  ~(kFSCatInfoContentMod | kFSCatInfoAttrMod)
01920         };
01921         
01922         OSErr                                   result;
01923         GetVolParmsInfoBuffer   volParmsInfo;
01924         UInt32                                  infoSize;
01925         FSCatalogInfo                   sourceCatalogInfo;      
01926         FSCatalogInfo                   destCatalogInfo;        
01927         HFSUniStr255                    sourceName;                     
01928         HFSUniStr255                    destName;                       
01929         FSRef                                   sourceCurrentRef;       
01930         FSRef                                   destCurrentRef;         
01931         FSRef                                   sourceParentRef;        
01932         FSRef                                   destParentRef;          
01933         HFSUniStr255                    sourceUniqueName;       
01934         HFSUniStr255                    destUniqueName;         
01935         long                                    theSeed;                        
01936         Boolean                                 sameParentDirs;         
01937         
01938         
01939         require_action((NULL != newSourceRef) && (NULL != newDestRef), BadParameter, result = paramErr);
01940         
01941         
01942         BlockMoveData(sourceRef, newSourceRef, sizeof(FSRef));
01943         BlockMoveData(sourceRef, &sourceCurrentRef, sizeof(FSRef));
01944         
01945         BlockMoveData(destRef, newDestRef, sizeof(FSRef));
01946         BlockMoveData(destRef, &destCurrentRef, sizeof(FSRef));
01947 
01948         
01949         result = FSGetCatalogInfo(&sourceCurrentRef, kFSCatInfoVolume, &sourceCatalogInfo, NULL, NULL, NULL);
01950         require_noerr(result, DetermineSourceVRefNumFailed);
01951         
01952         
01953         result = FSGetVolParms(sourceCatalogInfo.volume, sizeof(GetVolParmsInfoBuffer),
01954                 &volParmsInfo, &infoSize);
01955         if ( (noErr == result) && VolSupportsFSExchangeObjects(&volParmsInfo) )
01956         {
01957                 
01958                 result = FSExchangeObjects(sourceRef, destRef);
01959         }
01960         else
01961         {
01962                 
01963                 
01964                 
01965                 
01966                 
01967                 
01968                 result = FSGetCatalogInfo(&sourceCurrentRef, kGetCatInformationMask, &sourceCatalogInfo, &sourceName, NULL, &sourceParentRef);
01969                 require_noerr(result, SourceFSGetCatalogInfoFailed);
01970                 
01971                 result = FSGetCatalogInfo(&destCurrentRef, kGetCatInformationMask, &destCatalogInfo, &destName, NULL, &destParentRef);
01972                 require_noerr(result, DestFSGetCatalogInfoFailed);
01973                 
01974                 
01975                 require_action(sourceCatalogInfo.volume == destCatalogInfo.volume, NotSameVolume, result = diffVolErr);
01976                 
01977                 
01978                 require_action((0 == (sourceCatalogInfo.nodeFlags & kFSNodeIsDirectoryMask)) &&
01979                                            (0 == (destCatalogInfo.nodeFlags & kFSNodeIsDirectoryMask)), NotAFile, result = notAFileErr);
01980                 
01981                 
01982                 theSeed = 0x4a696d4c;   
01983                 
01984                 result = GenerateUniqueHFSUniStr(&theSeed, &sourceParentRef, &destParentRef, &sourceUniqueName);
01985                 require_noerr(result, GenerateUniqueHFSUniStr1Failed);
01986                 
01987                 result = GenerateUniqueHFSUniStr(&theSeed, &sourceParentRef, &destParentRef, &destUniqueName);
01988                 require_noerr(result, GenerateUniqueHFSUniStr2Failed);
01989 
01990                 
01991                 result = FSRenameUnicode(&sourceCurrentRef, sourceUniqueName.length, sourceUniqueName.unicode, kTextEncodingUnknown, newSourceRef);
01992                 require_noerr(result, FSRenameUnicode1Failed);
01993                 BlockMoveData(newSourceRef, &sourceCurrentRef, sizeof(FSRef));
01994                 
01995                 
01996                 result = FSRenameUnicode(&destCurrentRef, destUniqueName.length, destUniqueName.unicode, kTextEncodingUnknown, newDestRef);
01997                 require_noerr(result, FSRenameUnicode2Failed);
01998                 BlockMoveData(newDestRef, &destCurrentRef, sizeof(FSRef));
01999                 
02000                 
02001                 sameParentDirs = ( sourceCatalogInfo.parentDirID == destCatalogInfo.parentDirID );
02002                 if ( !sameParentDirs )
02003                 {
02004                         
02005                         result = FSMoveObject(&sourceCurrentRef, &destParentRef, newSourceRef);
02006                         require_noerr(result, FSMoveObject1Failed);
02007                         BlockMoveData(newSourceRef, &sourceCurrentRef, sizeof(FSRef));
02008                         
02009                         
02010                         result = FSMoveObject(&destCurrentRef, &sourceParentRef, newDestRef);
02011                         require_noerr(result, FSMoveObject2Failed);
02012                         BlockMoveData(newDestRef, &destCurrentRef, sizeof(FSRef));
02013                 }
02014                 
02015                 
02016                 
02017                 
02018                 
02019                                 
02020                 
02021                 result = FSSetCatalogInfo(&sourceCurrentRef, kSetCatinformationMask, &destCatalogInfo);
02022                 require_noerr(result, FSSetCatalogInfo1Failed);
02023                 
02024                 
02025                 result = FSSetCatalogInfo(&destCurrentRef, kSetCatinformationMask, &sourceCatalogInfo);
02026                 require_noerr(result, FSSetCatalogInfo2Failed);
02027                 
02028                 
02029                 result = FSRenameUnicode(&sourceCurrentRef, destName.length, destName.unicode, destCatalogInfo.textEncodingHint, newSourceRef);
02030                 require_noerr(result, FSRenameUnicode3Failed);
02031                 BlockMoveData(newSourceRef, &sourceCurrentRef, sizeof(FSRef));
02032                 
02033                 
02034                 result = FSRenameUnicode(&destCurrentRef, sourceName.length, sourceName.unicode, sourceCatalogInfo.textEncodingHint, newDestRef);
02035                 require_noerr(result, FSRenameUnicode4Failed);
02036                 
02037                 
02038                 BlockMoveData(newDestRef, newSourceRef, sizeof(FSRef));
02039                 BlockMoveData(&sourceCurrentRef, newDestRef, sizeof(FSRef));
02040         }
02041         
02042         return ( result );
02043         
02044         
02045 
02046 
02047 
02048 
02049         
02050 FSRenameUnicode4Failed:
02051 
02052         
02053         if ( noErr == FSRenameUnicode(&sourceCurrentRef, sourceUniqueName.length, sourceUniqueName.unicode, kTextEncodingUnknown, newSourceRef) )
02054         {
02055                 BlockMoveData(newSourceRef, &sourceCurrentRef, sizeof(FSRef));
02056         }
02057 
02058 FSRenameUnicode3Failed:
02059 
02060         
02061         verify_noerr(FSSetCatalogInfo(&destCurrentRef, kFSCatInfoSettableInfo, &destCatalogInfo));
02062 
02063 FSSetCatalogInfo2Failed:
02064 
02065         
02066         verify_noerr(FSSetCatalogInfo(&sourceCurrentRef, kFSCatInfoSettableInfo, &sourceCatalogInfo));
02067 
02068 FSSetCatalogInfo1Failed:
02069 
02070         if ( !sameParentDirs )
02071         {
02072                 
02073                 if ( noErr == FSMoveObject(&destCurrentRef, &destParentRef, newDestRef) )
02074                 {
02075                         BlockMoveData(newDestRef, &destCurrentRef, sizeof(FSRef));
02076                 }
02077         }
02078 
02079 FSMoveObject2Failed:
02080 
02081         if ( !sameParentDirs )
02082         {
02083                 
02084                 if ( noErr == FSMoveObject(&sourceCurrentRef, &sourceParentRef, newSourceRef) )
02085                 {
02086                         BlockMoveData(newSourceRef, &sourceCurrentRef, sizeof(FSRef));
02087                 }
02088         }
02089 
02090 FSMoveObject1Failed:
02091 
02092         
02093         verify_noerr(FSRenameUnicode(&destCurrentRef, destName.length, destName.unicode, destCatalogInfo.textEncodingHint, newDestRef));
02094 
02095 FSRenameUnicode2Failed:
02096 
02097         
02098         verify_noerr(FSRenameUnicode(&sourceCurrentRef, sourceName.length, sourceName.unicode, sourceCatalogInfo.textEncodingHint, newSourceRef));
02099 
02100 FSRenameUnicode1Failed:
02101 GenerateUniqueHFSUniStr2Failed:
02102 GenerateUniqueHFSUniStr1Failed:
02103 NotAFile:
02104 NotSameVolume:
02105 DestFSGetCatalogInfoFailed:
02106 SourceFSGetCatalogInfoFailed:
02107 DetermineSourceVRefNumFailed:   
02108 BadParameter:
02109 
02110         return ( result );
02111 }
02112 
02113 
02114 
02115 #pragma mark ----- Shared Environment Routines -----
02116 
02117 
02118 
02119 OSErr
02120 MoreFiles_FSLockRange(
02121         SInt16 refNum,
02122         SInt32 rangeLength,
02123         SInt32 rangeStart)
02124 {
02125         OSErr                   result;
02126         ParamBlockRec   pb;
02127 
02128         pb.ioParam.ioRefNum = refNum;
02129         pb.ioParam.ioReqCount = rangeLength;
02130         pb.ioParam.ioPosMode = fsFromStart;
02131         pb.ioParam.ioPosOffset = rangeStart;
02132         result = PBLockRangeSync(&pb);
02133         require_noerr(result, PBLockRangeSync);
02134         
02135 PBLockRangeSync:
02136 
02137         return ( result );
02138 }
02139 
02140 
02141 
02142 OSErr
02143 MoreFiles_FSUnlockRange(
02144         SInt16 refNum,
02145         SInt32 rangeLength,
02146         SInt32 rangeStart)
02147 {
02148         OSErr                   result;
02149         ParamBlockRec   pb;
02150 
02151         pb.ioParam.ioRefNum = refNum;
02152         pb.ioParam.ioReqCount = rangeLength;
02153         pb.ioParam.ioPosMode = fsFromStart;
02154         pb.ioParam.ioPosOffset = rangeStart;
02155         result = PBUnlockRangeSync(&pb);
02156         require_noerr(result, PBUnlockRangeSync);
02157         
02158 PBUnlockRangeSync:
02159 
02160         return ( result );
02161 }
02162 
02163 
02164 
02165 OSErr
02166 FSGetDirAccess(
02167         const FSRef *ref,
02168         SInt32 *ownerID,                
02169         SInt32 *groupID,                
02170         SInt32 *accessRights)   
02171 {
02172         OSErr                   result;
02173         FSSpec                  spec;
02174         HParamBlockRec  pb;
02175         
02176         
02177         result = FSGetCatalogInfo(ref, kFSCatInfoNone, NULL, NULL, &spec, NULL);
02178         require_noerr(result, FSGetCatalogInfo);
02179         
02180         
02181         pb.accessParam.ioNamePtr = (StringPtr)spec.name;
02182         pb.accessParam.ioVRefNum = spec.vRefNum;
02183         pb.fileParam.ioDirID = spec.parID;
02184         result = PBHGetDirAccessSync(&pb);
02185         require_noerr(result, PBHGetDirAccessSync);
02186         
02187         
02188         if ( NULL != ownerID )
02189         {
02190                 *ownerID = pb.accessParam.ioACOwnerID;
02191         }
02192         if ( NULL != groupID )
02193         {
02194                 *groupID = pb.accessParam.ioACGroupID;
02195         }
02196         if ( NULL != accessRights )
02197         {
02198                 *accessRights = pb.accessParam.ioACAccess;
02199         }
02200         
02201 PBHGetDirAccessSync:
02202 FSGetCatalogInfo:
02203 
02204         return ( result );
02205 }
02206 
02207 
02208 
02209 OSErr
02210 FSSetDirAccess(
02211         const FSRef *ref,
02212         SInt32 ownerID,
02213         SInt32 groupID,
02214         SInt32 accessRights)
02215 {
02216         OSErr                   result;
02217         FSSpec                  spec;
02218         HParamBlockRec  pb;
02219 
02220         enum
02221         {
02222                 
02223                 kSetDirAccessSettableMask = (kioACAccessBlankAccessMask +
02224                         kioACAccessEveryoneWriteMask + kioACAccessEveryoneReadMask + kioACAccessEveryoneSearchMask +
02225                         kioACAccessGroupWriteMask + kioACAccessGroupReadMask + kioACAccessGroupSearchMask +
02226                         kioACAccessOwnerWriteMask + kioACAccessOwnerReadMask + kioACAccessOwnerSearchMask)
02227         };
02228         
02229         
02230         result = FSGetCatalogInfo(ref, kFSCatInfoNone, NULL, NULL, &spec, NULL);
02231         require_noerr(result, FSGetCatalogInfo);
02232         
02233         
02234         pb.accessParam.ioNamePtr = (StringPtr)spec.name;
02235         pb.accessParam.ioVRefNum = spec.vRefNum;
02236         pb.fileParam.ioDirID = spec.parID;
02237         pb.accessParam.ioACOwnerID = ownerID;
02238         pb.accessParam.ioACGroupID = groupID;
02239         pb.accessParam.ioACAccess = accessRights & kSetDirAccessSettableMask;
02240         result = PBHSetDirAccessSync(&pb);
02241         require_noerr(result, PBHSetDirAccessSync);
02242         
02243 PBHSetDirAccessSync:
02244 FSGetCatalogInfo:
02245 
02246         return ( result );
02247 }
02248 
02249 
02250 
02251 OSErr
02252 FSGetVolMountInfoSize(
02253         FSVolumeRefNum volRefNum,
02254         SInt16 *size)
02255 {
02256         OSErr                   result;
02257         ParamBlockRec   pb;
02258 
02259         
02260         require_action(NULL != size, BadParameter, result = paramErr);
02261         
02262         pb.ioParam.ioNamePtr = NULL;
02263         pb.ioParam.ioVRefNum = volRefNum;
02264         pb.ioParam.ioBuffer = (Ptr)size;
02265         result = PBGetVolMountInfoSize(&pb);
02266         require_noerr(result, PBGetVolMountInfoSize);
02267         
02268 PBGetVolMountInfoSize:
02269 BadParameter:
02270 
02271         return ( result );
02272 }
02273 
02274 
02275 
02276 OSErr
02277 FSGetVolMountInfo(
02278         FSVolumeRefNum volRefNum,
02279         void *volMountInfo)
02280 {
02281         OSErr                   result;
02282         ParamBlockRec   pb;
02283 
02284         
02285         require_action(NULL != volMountInfo, BadParameter, result = paramErr);
02286         
02287         pb.ioParam.ioNamePtr = NULL;
02288         pb.ioParam.ioVRefNum = volRefNum;
02289         pb.ioParam.ioBuffer = (Ptr)volMountInfo;
02290         result = PBGetVolMountInfo(&pb);
02291         require_noerr(result, PBGetVolMountInfo);
02292         
02293 PBGetVolMountInfo:
02294 BadParameter:
02295 
02296         return ( result );
02297 }
02298 
02299 
02300 
02301 OSErr
02302 FSVolumeMount(
02303         const void *volMountInfo,
02304         FSVolumeRefNum *volRefNum)
02305 {
02306         OSErr                   result;
02307         ParamBlockRec   pb;
02308 
02309         
02310         require_action(NULL != volRefNum, BadParameter, result = paramErr);
02311         
02312         pb.ioParam.ioBuffer = (Ptr)volMountInfo;
02313         result = PBVolumeMount(&pb);
02314         require_noerr(result, PBVolumeMount);
02315         
02316         
02317         *volRefNum = pb.ioParam.ioVRefNum;
02318 
02319 PBVolumeMount:
02320 BadParameter:
02321 
02322         return ( result );
02323 }
02324 
02325 
02326 
02327 OSErr
02328 FSMapID(
02329         FSVolumeRefNum volRefNum,
02330         SInt32 ugID,
02331         SInt16 objType,
02332         Str31 name)
02333 {
02334         OSErr                   result;
02335         HParamBlockRec  pb;
02336 
02337         
02338         require_action(NULL != name, BadParameter, result = paramErr);
02339         
02340         pb.objParam.ioNamePtr = NULL;
02341         pb.objParam.ioVRefNum = volRefNum;
02342         pb.objParam.ioObjType = objType;
02343         pb.objParam.ioObjNamePtr = name;
02344         pb.objParam.ioObjID = ugID;
02345         result = PBHMapIDSync(&pb);
02346         require_noerr(result, PBHMapIDSync);
02347         
02348 PBHMapIDSync:
02349 BadParameter:
02350 
02351         return ( result );
02352 }
02353 
02354 
02355 
02356 OSErr
02357 FSMapName(
02358         FSVolumeRefNum volRefNum,
02359         ConstStr255Param name,
02360         SInt16 objType,
02361         SInt32 *ugID)
02362 {
02363         OSErr                   result;
02364         HParamBlockRec  pb;
02365 
02366         
02367         require_action(NULL != ugID, BadParameter, result = paramErr);
02368         
02369         pb.objParam.ioNamePtr = NULL;
02370         pb.objParam.ioVRefNum = volRefNum;
02371         pb.objParam.ioObjType = objType;
02372         pb.objParam.ioObjNamePtr = (StringPtr)name;
02373         result = PBHMapNameSync(&pb);
02374         require_noerr(result, PBHMapNameSync);
02375         
02376         
02377         *ugID = pb.objParam.ioObjID;
02378         
02379 PBHMapNameSync:
02380 BadParameter:
02381 
02382         return ( result );
02383 }
02384 
02385 
02386 
02387 OSErr
02388 FSCopyFile(
02389         const FSRef *srcFileRef,
02390         const FSRef *dstDirectoryRef,
02391         UniCharCount nameLength,
02392         const UniChar *copyName,        
02393         TextEncoding textEncodingHint,
02394         FSRef *newRef)                          
02395 {
02396         OSErr                                   result;
02397         FSSpec                                  srcFileSpec;
02398         FSCatalogInfo                   catalogInfo;
02399         HParamBlockRec                  pb;
02400         Str31                                   hfsName;
02401         GetVolParmsInfoBuffer   volParmsInfo;
02402         UInt32                                  infoSize;
02403         
02404         
02405         result = FSGetCatalogInfo(srcFileRef, kFSCatInfoNone, NULL, NULL, &srcFileSpec, NULL);
02406         require_noerr(result, FSGetCatalogInfo_srcFileRef);
02407         
02408         
02409         result = FSGetVolParms(srcFileSpec.vRefNum, sizeof(GetVolParmsInfoBuffer),
02410                 &volParmsInfo, &infoSize);
02411         require_action((noErr == result) && VolHasCopyFile(&volParmsInfo),
02412                 NoCopyFileSupport, result = paramErr);
02413 
02414         
02415         result = FSGetCatalogInfo(dstDirectoryRef, kFSCatInfoVolume + kFSCatInfoNodeID,
02416                 &catalogInfo, NULL, NULL, NULL);
02417         require_noerr(result, FSGetCatalogInfo_dstDirectoryRef);
02418         
02419         
02420         pb.copyParam.ioVRefNum = srcFileSpec.vRefNum;
02421         pb.copyParam.ioDirID = srcFileSpec.parID;
02422         pb.copyParam.ioNamePtr = (StringPtr)srcFileSpec.name;
02423         pb.copyParam.ioDstVRefNum = catalogInfo.volume;
02424         pb.copyParam.ioNewDirID = (long)catalogInfo.nodeID;
02425         pb.copyParam.ioNewName = NULL;
02426         if ( NULL != copyName )
02427         {
02428                 result = UnicodeNameGetHFSName(nameLength, copyName, textEncodingHint, false, hfsName);
02429                 require_noerr(result, UnicodeNameGetHFSName);
02430                 
02431                 pb.copyParam.ioCopyName = hfsName;
02432         }
02433         else
02434         {
02435                 pb.copyParam.ioCopyName = NULL;
02436         }
02437         result = PBHCopyFileSync(&pb);
02438         require_noerr(result, PBHCopyFileSync);
02439         
02440         if ( NULL != newRef )
02441         {
02442                 verify_noerr(FSMakeFSRef(pb.copyParam.ioDstVRefNum, pb.copyParam.ioNewDirID,
02443                         pb.copyParam.ioCopyName, newRef));
02444         }
02445                 
02446 PBHCopyFileSync:
02447 UnicodeNameGetHFSName:
02448 FSGetCatalogInfo_dstDirectoryRef:
02449 NoCopyFileSupport:
02450 FSGetCatalogInfo_srcFileRef:
02451 
02452         return ( result );
02453 }
02454 
02455 
02456 
02457 OSErr
02458 FSMoveRename(
02459         const FSRef *srcFileRef,
02460         const FSRef *dstDirectoryRef,
02461         UniCharCount nameLength,
02462         const UniChar *moveName,        
02463         TextEncoding textEncodingHint,
02464         FSRef *newRef)                          
02465 {
02466         OSErr                                   result;
02467         FSSpec                                  srcFileSpec;
02468         FSCatalogInfo                   catalogInfo;
02469         HParamBlockRec                  pb;
02470         Str31                                   hfsName;
02471         GetVolParmsInfoBuffer   volParmsInfo;
02472         UInt32                                  infoSize;
02473         
02474         
02475         result = FSGetCatalogInfo(srcFileRef, kFSCatInfoNone, NULL, NULL, &srcFileSpec, NULL);
02476         require_noerr(result, FSGetCatalogInfo_srcFileRef);
02477         
02478         
02479         result = FSGetVolParms(srcFileSpec.vRefNum, sizeof(GetVolParmsInfoBuffer),
02480                 &volParmsInfo, &infoSize);
02481         require_action((noErr == result) && VolHasMoveRename(&volParmsInfo),
02482                 NoMoveRenameSupport, result = paramErr);
02483 
02484         
02485         result = FSGetCatalogInfo(dstDirectoryRef, kFSCatInfoVolume + kFSCatInfoNodeID,
02486                 &catalogInfo, NULL, NULL, NULL);
02487         require_noerr(result, FSGetCatalogInfo_dstDirectoryRef);
02488         
02489         
02490         require_action(srcFileSpec.vRefNum == catalogInfo.volume, NotSameVolume, result = diffVolErr);
02491         
02492         
02493         pb.copyParam.ioVRefNum = srcFileSpec.vRefNum;
02494         pb.copyParam.ioDirID = srcFileSpec.parID;
02495         pb.copyParam.ioNamePtr = (StringPtr)srcFileSpec.name;
02496         pb.copyParam.ioNewDirID = (long)catalogInfo.nodeID;
02497         pb.copyParam.ioNewName = NULL;
02498         if ( NULL != moveName )
02499         {
02500                 result = UnicodeNameGetHFSName(nameLength, moveName, textEncodingHint, false, hfsName);
02501                 require_noerr(result, UnicodeNameGetHFSName);
02502                 
02503                 pb.copyParam.ioCopyName = hfsName;
02504         }
02505         else
02506         {
02507                 pb.copyParam.ioCopyName = NULL;
02508         }
02509         result = PBHMoveRenameSync(&pb);
02510         require_noerr(result, PBHMoveRenameSync);
02511         
02512         if ( NULL != newRef )
02513         {
02514                 verify_noerr(FSMakeFSRef(pb.copyParam.ioVRefNum, pb.copyParam.ioNewDirID,
02515                         pb.copyParam.ioCopyName, newRef));
02516         }
02517         
02518 PBHMoveRenameSync:
02519 UnicodeNameGetHFSName:
02520 NotSameVolume:
02521 FSGetCatalogInfo_dstDirectoryRef:
02522 NoMoveRenameSupport:
02523 FSGetCatalogInfo_srcFileRef:
02524 
02525         return ( result );
02526 }
02527 
02528 
02529 
02530 #pragma mark ----- File ID Routines -----
02531 
02532 
02533 
02534 OSErr
02535 FSResolveFileIDRef(
02536         FSVolumeRefNum volRefNum,
02537         SInt32 fileID,
02538         FSRef *ref)
02539 {
02540         OSErr           result;
02541         FIDParam        pb;
02542         Str255          tempStr;
02543         
02544         
02545         require_action(NULL != ref, BadParameter, result = paramErr);
02546         
02547         
02548         tempStr[0] = 0;
02549         pb.ioNamePtr = tempStr;
02550         pb.ioVRefNum = volRefNum;
02551         pb.ioFileID = fileID;
02552         result = PBResolveFileIDRefSync((HParmBlkPtr)&pb);
02553         require_noerr(result, PBResolveFileIDRefSync);
02554         
02555         
02556         result = FSMakeFSRef(volRefNum, pb.ioSrcDirID, tempStr, ref);
02557         require_noerr(result, FSMakeFSRef);
02558         
02559 FSMakeFSRef:
02560 PBResolveFileIDRefSync:
02561 BadParameter:
02562 
02563         return ( result );
02564 }
02565 
02566 
02567 
02568 OSErr
02569 FSCreateFileIDRef(
02570         const FSRef *ref,
02571         SInt32 *fileID)
02572 {
02573         OSErr           result;
02574         FSSpec          spec;
02575         FIDParam        pb;
02576         
02577         
02578         require_action(NULL != fileID, BadParameter, result = paramErr);
02579         
02580         
02581         result = FSGetCatalogInfo(ref, kFSCatInfoNone, NULL, NULL, &spec, NULL);
02582         require_noerr(result, FSGetCatalogInfo);
02583         
02584         
02585         pb.ioNamePtr = (StringPtr)spec.name;
02586         pb.ioVRefNum = spec.vRefNum;
02587         pb.ioSrcDirID = spec.parID;
02588         result = PBCreateFileIDRefSync((HParmBlkPtr)&pb);
02589         require((noErr == result) || (fidExists == result) || (afpIDExists == result),
02590                 PBCreateFileIDRefSync);
02591         
02592         
02593         *fileID = pb.ioFileID;
02594         
02595 PBCreateFileIDRefSync:
02596 FSGetCatalogInfo:
02597 BadParameter:
02598 
02599         return ( result );
02600 }
02601 
02602 
02603 
02604 #pragma mark ----- Utility Routines -----
02605 
02606 
02607 
02608 Ptr
02609 GetTempBuffer(
02610         ByteCount buffReqSize,
02611         ByteCount *buffActSize)
02612 {
02613         enum
02614         {
02615                 kSlopMemory = 0x00008000        
02616         };
02617         
02618         Ptr tempPtr;
02619         
02620         
02621         require_action(NULL != buffActSize, BadParameter, tempPtr = NULL);
02622         
02623         
02624         buffReqSize = buffReqSize & 0xfffff000;
02625         
02626         if ( buffReqSize < 0x00001000 )
02627         {
02628                 
02629                 buffReqSize = 0x00001000;
02630         }
02631         
02632         
02633         tempPtr = NewPtr(buffReqSize);
02634         
02635         
02636         if ( (tempPtr == NULL) && (buffReqSize > 0x00001000) )
02637         {
02638                 
02639 
02640 
02641 
02642                 long freeMemory = (FreeMem() - kSlopMemory) & 0xfffff000;
02643                 
02644                 buffReqSize = MaxBlock() & 0xfffff000;
02645                 
02646                 if ( buffReqSize > freeMemory )
02647                 {
02648                         buffReqSize = freeMemory;
02649                 }
02650                 
02651                 if ( buffReqSize == 0 )
02652                 {
02653                         buffReqSize = 0x00001000;
02654                 }
02655                 
02656                 tempPtr = NewPtr(buffReqSize);
02657         }
02658         
02659         
02660         if ( tempPtr != NULL )
02661         {
02662                 *buffActSize = buffReqSize;
02663         }
02664         else
02665         {
02666                 *buffActSize = 0;
02667         }
02668         
02669 BadParameter:
02670 
02671         return ( tempPtr );
02672 }
02673 
02674 
02675 
02676 OSErr
02677 FileRefNumGetFSRef(
02678         short refNum,
02679         FSRef *ref)
02680 {
02681         return ( FSGetForkCBInfo(refNum, 0, NULL, NULL, NULL, ref, NULL) );
02682 }
02683 
02684 
02685 
02686 OSErr
02687 FSSetDefault(
02688         const FSRef *newDefault,
02689         FSRef *oldDefault)
02690 {
02691         OSErr                   result;
02692         FSVolumeRefNum  vRefNum;
02693         long                    dirID;
02694         FSCatalogInfo   catalogInfo;
02695         
02696         
02697         require_action((NULL != newDefault) && (NULL != oldDefault), BadParameter, result = paramErr);
02698         
02699         
02700         result = FSGetCatalogInfo(newDefault,
02701                 kFSCatInfoNodeFlags + kFSCatInfoVolume + kFSCatInfoNodeID,
02702                 &catalogInfo, NULL, NULL, NULL);
02703         require_noerr(result, FSGetCatalogInfo);
02704         
02705         
02706         require_action(0 != (kFSNodeIsDirectoryMask & catalogInfo.nodeFlags), NewDefaultNotDirectory,
02707                 result = dirNFErr);
02708         
02709         
02710         result = HGetVol(NULL, &vRefNum, &dirID);
02711         require_noerr(result, HGetVol);
02712         
02713         
02714         result = FSMakeFSRef(vRefNum, dirID, NULL, oldDefault);
02715         require_noerr(result, FSMakeFSRef);
02716         
02717         
02718         result = HSetVol(NULL, catalogInfo.volume, catalogInfo.nodeID);
02719         require_noerr(result, HSetVol);
02720 
02721 HSetVol:
02722 FSMakeFSRef:
02723 HGetVol:
02724 NewDefaultNotDirectory:
02725 FSGetCatalogInfo:
02726 BadParameter:
02727 
02728         return ( result );
02729 }
02730 
02731 
02732 
02733 OSErr
02734 FSRestoreDefault(
02735         const FSRef *oldDefault)
02736 {
02737         OSErr                   result;
02738         FSCatalogInfo   catalogInfo;
02739         
02740         
02741         require_action(NULL != oldDefault, BadParameter, result = paramErr);
02742         
02743         
02744         result = FSGetCatalogInfo(oldDefault,
02745                 kFSCatInfoNodeFlags + kFSCatInfoVolume + kFSCatInfoNodeID,
02746                 &catalogInfo, NULL, NULL, NULL);
02747         require_noerr(result, FSGetCatalogInfo);
02748         
02749         
02750         require_action(0 != (kFSNodeIsDirectoryMask & catalogInfo.nodeFlags), OldDefaultNotDirectory,
02751                 result = dirNFErr);
02752         
02753         
02754         result = HSetVol(NULL, catalogInfo.volume, catalogInfo.nodeID);
02755         require_noerr(result, HSetVol);
02756 
02757 HSetVol:
02758 OldDefaultNotDirectory:
02759 FSGetCatalogInfo:
02760 BadParameter:
02761 
02762         return ( result );
02763 }
02764 
02765