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