2
* Copyright (c) 1999-2006 Apple Computer, Inc. All rights reserved.
4
* @APPLE_LICENSE_HEADER_START@
6
* "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7
* Reserved. This file contains Original Code and/or Modifications of
8
* Original Code as defined in and that are subject to the Apple Public
9
* Source License Version 1.0 (the 'License'). You may not use this file
10
* except in compliance with the License. Please obtain a copy of the
11
* License at http://www.apple.com/publicsource and read it before using
14
* The Original Code and all software distributed under the License are
15
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18
* FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19
* License for the specific language governing rights and limitations
22
* @APPLE_LICENSE_HEADER_END@
33
#include "BTreePrivate.h"
35
#include "BTreeScanner.h"
36
#include "hfs_endian.h"
37
#include "../fsck_debug.h"
40
#include <sys/xattr.h>
42
#include <sys/kauth.h>
43
#include <sys/errno.h>
44
#include <sys/syslimits.h>
51
#define kFSCKMountVersion 0x6673636B /* 'fsck' made changes */
54
Log2BlkLo = 9, // number of left shifts to convert bytes to block.lo
55
Log2BlkHi = 23 // number of right shifts to convert bytes to block.hi
67
/* IO size for reading or writing disk blocks */
68
#define DISK_IOSIZE 32768
70
#define kMaxReScan 3 /* max times to re-scan volume on repair success */
72
#define kBTreeHeaderUserBytes 128
74
#define kBusErrorValue 0x50FF8001
76
//�� Danger! This should not be hard coded
77
#define kMaxClumpSize 0x100000 /* max clump size is 1MB (2048 btree nodes) */
79
#define MDB_FNum 1 /* file number representing the MDB */
80
#define AMDB_FNum -1 /* file number representing the alternate MDB */
81
#define VBM_FNum 2 /* file number representing the volume bit map */
82
#define MDB_BlkN 2 /* logical block number for the MDB */
84
#define kCalculatedExtentRefNum ( 0 )
85
#define kCalculatedCatalogRefNum ( 1*sizeof(SFCB) )
86
#define kCalculatedAllocationsRefNum ( 2*sizeof(SFCB) )
87
#define kCalculatedAttributesRefNum ( 3*sizeof(SFCB) )
88
#define kCalculatedStartupRefNum ( 4*sizeof(SFCB) )
89
#define kCalculatedRepairRefNum ( 5*sizeof(SFCB) )
91
#define Max_ABSiz 0x7FFFFE00 /* max allocation block size (multiple of 512 */
92
#define Blk_Size 512 /* size of a logical block */
93
#define kHFSBlockSize 512 /* HFS block size */
95
// only the lower 7 bits are considered to be invalid, all others are valid -djb
96
#define VAtrb_Msk 0x007F /* volume attribute mask - invalid bits */
97
#define VAtrb_DFlt 0x0100 /* default volume attribute flags */
98
#define VAtrb_Cons 0x0100 /* volume consistency flag */
99
#define kHFSCatalogNodeIDsReused 0x1000
102
* File type and creator for symbolic links (from xnu/bsd/hfs/hfs.h)
105
kSymLinkFileType = 0x736C6E6B, /* 'slnk' */
106
kSymLinkCreator = 0x72686170 /* 'rhap' */
110
* File type and creator for TextEdit documents
113
kTextFileType = 0x54455854, /* 'TEXT' */
114
kTextFileCreator = 0x74747874, /* 'ttxt' */
117
/*------------------------------------------------------------------------------
118
BTree data structures
119
------------------------------------------------------------------------------*/
121
/* misc BTree constants */
123
#define BTMaxDepth 8 /* max tree depth */
124
#define Num_HRecs 3 /* number of records in BTree Header node */
125
#define Num_MRecs 1 /* number of records in BTree Map node */
129
// DFA extensions to the HFS/HFS+ BTreeControlBlock
130
typedef struct BTreeExtensionsRec
132
Ptr BTCBMPtr; // pointer to scavenger BTree bit map
133
UInt32 BTCBMSize; // size of the bitmap, bytes
134
BTreeControlBlock *altBTCB; // BTCB DFA builds up
135
UInt32 realFreeNodeCount; // Number of real free nodes, taken from disk, for more accurate progress information
136
} BTreeExtensionsRec;
141
* Scavenger BTree Path Record (STPR)
143
typedef struct STPR {
144
UInt32 TPRNodeN; /* node number */
145
SInt16 TPRRIndx; /* record index */
146
SInt16 unused; /* not used - makes debugging easier */
147
UInt32 TPRLtSib; /* node number of left sibling node */
148
UInt32 TPRRtSib; /* node number of right sibling node */
151
typedef STPR SBTPT[BTMaxDepth]; /* BTree path table */
153
#define LenSBTPT ( sizeof(STPR) * BTMaxDepth ) /* length of BTree Path Table */
158
/*------------------------------------------------------------------------------
159
CM (Catalog Manager) data structures
160
------------------------------------------------------------------------------*/
165
#define CMMaxDepth 100 /* max catalog depth (Same as Finder 7.0) */
167
#define fNameLocked 4096
173
typedef union CatalogName CatalogName;
176
// Scavenger Directory Path Record (SDPR)
178
typedef struct SDPR {
179
UInt32 directoryID; // directory ID
180
UInt32 offspringIndex; // offspring index
181
UInt32 directoryHint; // BTree hint for directory record
182
long threadHint; // BTree hint for thread record
183
HFSCatalogNodeID parentDirID; // parent directory ID
184
CatalogName directoryName; // directory CName
187
typedef SDPR SDPT[CMMaxDepth]; // directory path table
189
#define LenSDPT ( sizeof(SDPR) * CMMaxDepth ) // length of Tree Path Table
193
// kInvalidMRUCacheKey = -1L, /* flag to denote current MRU cache key is invalid*/
194
kDefaultNumMRUCacheBlocks = 16 /* default number of blocks in each cache*/
199
* UTCacheReadIP and UTCacheWriteIP cacheOption
203
noCacheBit = 5, /* don't cache this please */
204
noCacheMask = 0x0020,
205
rdVerifyBit = 6, /* read verify */
206
rdVerifyMask = 0x0040
210
/*------------------------------------------------------------------------------
211
Low-level File System Error codes
212
------------------------------------------------------------------------------*/
214
/* The DCE bits are defined as follows (for the word of flags): */
219
Is_Agent = 1, // future use
220
FollowsNewRules = 2, // New DRVR Rules Bit
232
Is_AppleTalk_Mask = 1 << Is_AppleTalk,
233
Is_Agent_Mask = 1 << Is_Agent,
234
FollowsRules_Mask = 1 << FollowsNewRules,
235
Is_Open_Mask = 1 << Is_Open,
236
Is_Ram_Based_Mask = 1 << Is_Ram_Based,
237
Is_Active_Mask = 1 << Is_Active,
238
Read_Enable_Mask = 1 << Read_Enable,
239
Write_Enable_Mask = 1 << Write_Enable,
240
Control_Enable_Mask = 1 << Control_Enable,
241
Status_Enable_Mask = 1 << Status_Enable,
242
Needs_Goodbye_Mask = 1 << Needs_Goodbye,
243
Needs_Time_Mask = 1 << Needs_Time,
244
Needs_Lock_Mask = 1 << Needs_Lock
248
cdInternalErr = -1312, // internal CheckDisk error
249
cdVolumeNotFoundErr = -1313, // cound not find volume (could be offline)
250
cdCannotReadErr = -1314, // unable to read from disk
251
cdCannotWriteErr = -1315, // unable to write to disk
252
cdNotHFSVolumeErr = -1316, // not an HFS disk
253
cdUnrepairableErr = -1317, // volume needs major repairs that CheckDisk cannot fix
254
cdRepairFailedErr = -1318, // repair failed
255
cdUserCanceledErr = -1319, // user interrupt
256
cdVolumeInUseErr = -1320, // volume modifed by another app
257
cdNeedsRepairsErr = -1321, // volume needs repairs (see repairInfo for additional info)
258
cdReMountErr = -1322, // Cannot remount volume
259
cdUnknownProcessesErr = -1323, // Volume cannot be unmounted and unknown processes are running
260
cdDamagedWrapperErr = -1324, // HFS Wrapper damaged error.
261
cdIncompatibleOSErr = -1325, // Current OS version is incompatible
262
cdMemoryFullErr = -1326 // not enough memory to check disk
267
fsDSIntErr = -127 /* non-hardware Internal file system error */
270
// Repair Info - additional info returned when a repair is attempted
272
kFileSharingEnabled = 0x00000001,
273
kDiskIsLocked = 0x00000002,
274
kDiskIsBoot = 0x00000004,
275
kDiskHasOpenFiles = 0x00000008,
276
kVolumeHadOverlappingExtents = 0x00000010, // repairLevelSomeDataLoss
277
kVolumeClean = 0x00000020,
279
kRepairsWereMade = 0x80000000
282
// Input parameters to CheckDisk
285
ignoreRunningProcessesMask = 0x00000001, // Assumes caller has shut down processes
286
checkDiskVersionMask = 0x00000004 // Will just return back the version in repairInfo.
289
// Message types, so the user can treat and display accordingly
291
kStatusMessage = 0x0000,
292
kTitleMessage = 0x0001,
293
kErrorMessage = 0x0002
296
// <10> Current stage of CheckDisk passed to cancel proc.
297
// File System is marked busy during kRepairStage, so WaitNextEvent and I/O cannot be done during this stage.
306
// Resource ID of 'STR ' resource containing the name of of the folder to create aliases to damaged files.
308
rDamagedFilesDirSTRid = -20886
313
kUnknownVolumeType = 0,
315
kEmbededHFSPlusVolumeType,
316
kPureHFSPlusVolumeType
324
kHighLevelInfo = 1100,
332
/*------------------------------------------------------------------------------
333
Minor Repair Interface (records compiled during scavenge, later repaired)
334
Note that not all repair types use all of these fields.
335
-----------------------------------------------------------------------------*/
337
typedef struct RepairOrder /* a node describing a needed minor repair */
339
struct RepairOrder *link; /* link to next node, or NULL */
340
SInt16 type; /* type of error, as an error code (E_DirVal etc) */
341
SInt16 forkType; /* which file fork */
342
UInt64 correct; /* correct valence */
343
UInt64 incorrect; /* valence as found in volume (for consistency chk) */
344
UInt32 maskBit; /* incorrect bit */
345
UInt32 hint; /* B-tree node hint */
346
UInt32 parid; /* parent ID */
347
unsigned char name[1]; /* dir or file name */
348
} RepairOrder, *RepairOrderPtr;
351
typedef struct EmbededVolDescription
354
UInt16 drEmbedSigWord;
355
HFSExtentDescriptor drEmbedExtent;
356
} EmbededVolDescription;
359
// define the correct drive queue structure
360
typedef struct ExtendedDrvQueue
364
char dQUsedInternally;
365
char dQDiskIsSingleSided;
376
/*------------------------------------------------------------------------------
377
Scavenger Global Area - (SGlob)
378
------------------------------------------------------------------------------*/
379
typedef struct MissingThread
381
struct MissingThread *link; /* link to next node, or NULL */
383
HFSPlusCatalogKey nextKey;
384
HFSPlusCatalogThread thread;
388
#define kRsrcFork (-1)
392
HFSCatalogNodeID fileID;
395
UInt32 newStartBlock;
398
/* didRepair stores the result of moving of overlap extent and is used
399
* to decide which disk blocks (original blocks or blocks allocated for
400
* for new extent location) should be marked used and free.
404
typedef struct ExtentInfo ExtentInfo;
406
struct ExtentsTable {
408
ExtentInfo extentInfo[1];
410
typedef struct ExtentsTable ExtentsTable;
413
struct FileIdentifier {
415
HFSCatalogNodeID fileID;
416
HFSCatalogNodeID parID; // Used for files on HFS volumes without threads
417
Str31 name; // Used for files on HFS volumes without threads
419
typedef struct FileIdentifier FileIdentifier;
421
struct FileIdentifierTable {
423
FileIdentifier fileIdentifier[1];
425
typedef struct FileIdentifierTable FileIdentifierTable;
427
/* Universal Extent Key */
431
HFSPlusExtentKey hfsPlus;
433
typedef union ExtentKey ExtentKey;
434
/* Universal extent descriptor */
436
union ExtentDescriptor {
437
HFSExtentDescriptor hfs;
438
HFSPlusExtentDescriptor hfsPlus;
440
typedef union ExtentDescriptor ExtentDescriptor;
441
/* Universal extent record */
445
HFSPlusExtentRecord hfsPlus;
447
typedef union ExtentRecord ExtentRecord;
448
/* Universal catalog key */
452
HFSPlusCatalogKey hfsPlus;
454
typedef union CatalogKey CatalogKey;
455
/* Universal catalog data record */
457
union CatalogRecord {
459
HFSCatalogFolder hfsFolder;
460
HFSCatalogFile hfsFile;
461
HFSCatalogThread hfsThread;
462
HFSPlusCatalogFolder hfsPlusFolder;
463
HFSPlusCatalogFile hfsPlusFile;
464
HFSPlusCatalogThread hfsPlusThread;
466
typedef union CatalogRecord CatalogRecord;
469
Key for records in the attributes file. Fields are compared in the order:
470
cnid, attributeName, startBlock
473
struct AttributeKey {
474
UInt16 keyLength; /* must set kBTBigKeysMask and kBTVariableIndexKeysMask in BTree header's attributes */
476
HFSCatalogNodeID cnid; /* file or folder ID */
477
UInt32 startBlock; /* block # relative to start of attribute */
478
UInt16 attrNameLen; /* number of unicode characters */
479
UInt16 attrName[127]; /* attribute name (Unicode) */
481
typedef struct AttributeKey AttributeKey;
483
kAttributeKeyMaximumLength = sizeof(AttributeKey) - sizeof(UInt16),
484
kAttributeKeyMinimumLength = kAttributeKeyMaximumLength - 127 * sizeof(UInt16) + sizeof(UInt16)
488
QElemPtr qLink; /*queue link in header*/
489
short qType; /*type byte for safety check*/
490
short ioTrap; /*FS: the Trap*/
491
Ptr ioCmdAddr; /*FS: address to dispatch to*/
492
void* ioCompletion; /*completion routine addr (0 for synch calls)*/
493
OSErr ioResult; /*result code*/
494
StringPtr ioNamePtr; /*ptr to Vol:FileName string*/
495
short ioVRefNum; /*volume refnum (DrvNum for Eject and MountVol)*/
506
typedef struct HIOParam HIOParam;
508
typedef HIOParam * HIOParamPtr;
512
UInt32 length; /* first word is FCB part length*/
513
SFCB fcb[1]; /* fcb array*/
515
typedef struct FCBArray FCBArray;
518
UserCancel callback routine
521
progress: number from 1 to 100 indicating current progress
522
progressChanged: boolean flag that is true if progress number has been updated
523
context: pointer to context data (if any) that the caller passed to CheckDisk
526
return true if the user wants to cancel the CheckDisk operation
529
typedef int (*UserCancelProcPtr)(UInt16 progress, UInt16 secondsRemaining, Boolean progressChanged, UInt16 stage, void *context);
534
//-- User Cancel Proc
535
typedef UniversalProcPtr UserCancelUPP;
538
uppUserCancelProcInfo = kPascalStackBased
539
| RESULT_SIZE(kTwoByteCode)
540
| STACK_ROUTINE_PARAMETER(1, kTwoByteCode)
541
| STACK_ROUTINE_PARAMETER(2, kTwoByteCode)
542
| STACK_ROUTINE_PARAMETER(3, kTwoByteCode)
543
| STACK_ROUTINE_PARAMETER(4, kTwoByteCode)
544
| STACK_ROUTINE_PARAMETER(5, kFourByteCode)
547
#define NewUserCancelProc(userRoutine) \
548
(UserCancelUPP) NewRoutineDescriptor((ProcPtr)(userRoutine), uppUserCancelProcInfo, GetCurrentArchitecture())
550
#define CallUserCancelProc(userRoutine, progress, secondsRemaining, progressChanged, stage, context) \
551
CallUniversalProc((UniversalProcPtr)(userRoutine), uppUserCancelProcInfo, (progress), (secondsRemaining), (progressChanged), (stage), (context))
555
typedef UserCancelProcPtr UserCancelUPP;
557
#define NewUserCancelProc(userRoutine) \
558
((UserCancelUPP) (userRoutine))
560
#define CallUserCancelProc(userRoutine, progress, secondsRemaining, progressChanged, stage, context) \
561
(*(userRoutine))((progress), (secondsRemaining), (progressChanged), (stage), (context))
567
UserMessage callback routine
570
message: message from CheckDisk
571
messageType: type of message
572
context: pointer to context data (if any) that the caller passed to CheckDisk
575
return true if the user wants to cancel the CheckDisk operation
579
typedef pascal void (*UserMessageProcPtr)(StringPtr message, SInt16 messageType, void *context);
583
//-- User Message Proc
584
typedef UniversalProcPtr UserMessageUPP;
587
uppUserMessageProcInfo = kPascalStackBased
588
| STACK_ROUTINE_PARAMETER(1, kFourByteCode)
589
| STACK_ROUTINE_PARAMETER(2, kTwoByteCode)
590
| STACK_ROUTINE_PARAMETER(3, kFourByteCode)
593
#define NewUserMessageProc(userRoutine) \
594
(UserMessageUPP) NewRoutineDescriptor((ProcPtr)(userRoutine), uppUserMessageProcInfo, GetCurrentArchitecture())
596
#define CallUserMessageProc(userRoutine, message, messageType, context) \
597
CallUniversalProc((UniversalProcPtr)(userRoutine), uppUserMessageProcInfo, (message), (messageType), (context))
601
typedef UserMessageProcPtr UserMessageUPP;
603
#define NewUserMessageProc(userRoutine) \
604
((UserMessageUPP) (userRoutine))
606
#define CallUserMessageProc(userRoutine, message, messageType, context) \
607
(*(userRoutine))((message), (messageType), (context))
611
/* 3843779 Structure to detemine consistency of attribute data and
612
* corresponding bit in catalog record. Based on Chinese Remainder
615
typedef struct PrimeBuckets {
629
/* Record last attribute ID checked, used in CheckAttributeRecord, initialized in ScavSetup */
630
typedef struct attributeInfo {
635
unsigned char attrname[XATTR_MAXNAMELEN+1];
636
u_int32_t totalBlocks;
637
u_int32_t calculatedTotalBlocks;
638
u_int64_t logicalSize;
642
VolumeObject encapsulates all infomration about the multiple volume anchor blocks (VHB and MSD)
643
on HFS and HFS+ volumes. An HFS volume will have two MDBs (primary and alternate HFSMasterDirectoryBlock),
644
a pure HFS+ volume will have two VHBs (primary and alternate HFSPlusVolumeHeader), and a wrapped HFS+
645
volume will have two MDBs and two VHBs.
648
/* values for VolumeObject.flags */
650
kVO_Inited = 0x00000001, // this structured has been initialized
651
kVO_PriVHBOK = 0x00000002, // the primary Volume Header Block is valid
652
kVO_AltVHBOK = 0x00000004, // the alternate Volume Header Block is valid
653
kVO_PriMDBOK = 0x00000008, // the primary Master Directory Block is valid
654
kVO_AltMDBOK = 0x00000010, // the alternate Master Directory Block is valid
657
typedef struct VolumeObject {
659
SVCB * vcbPtr; // pointer to VCB used for this volume
660
UInt32 volumeType; // (kHFSVolumeType or kEmbededHFSPlusVolumeType or kPureHFSPlusVolumeType)
661
UInt32 embeddedOffset; // offset of embedded HFS+ (in bytes) volume into HFS wrapper volume
662
// NOTE - UInt32 is OK since we don't support HFS Wrappers on TB volumes
663
UInt32 sectorSize; // size of a sector for this device
664
UInt64 totalDeviceSectors; // total number of sectors for this volume (from GetDeviceSize)
665
UInt64 totalEmbeddedSectors; // total number of sectors for embedded volume
666
// location of all possible volume anchor blocks (MDB and VHB) on this volume. These locations
667
// are the sector offset into the volume. Only wrapped HFS+ volumes use all 4 of these.
668
UInt64 primaryVHB; // not used for HFS volumes
669
UInt64 alternateVHB; // not used for HFS volumes
670
UInt64 primaryMDB; // not used for pure HFS+ volumes
671
UInt64 alternateMDB; // not used for pure HFS+ volumes
672
} VolumeObject, *VolumeObjectPtr;
675
typedef struct SGlob {
676
SInt16 DrvNum; // drive number of target drive
677
SInt16 RepLevel; // repair level, 1 = minor repair, 2 = major repair
678
SInt16 ScavRes; // scavenge result code
679
OSErr ErrCode; // error code
680
OSErr IntErr; // internal error code
681
UInt16 VIStat; // scavenge status flags for volume info
682
UInt16 ABTStat; // scavenge status flags for Attributes BTree
683
UInt16 EBTStat; // scavenge status flags for extent BTree
684
UInt16 CBTStat; // scavenge status flags for catalog BTree
685
UInt16 CatStat; // scavenge status flags for catalog file
686
UInt16 VeryMinorErrorsStat; // scavenge status flags for very minor errors
687
UInt16 JStat; // scavange status flags for journal errors
688
UInt16 PrintStat; // info about messages that should be displayed only once
689
DrvQElPtr DrvPtr; // pointer to driveQ element for target drive
690
UInt32 TarID; // target ID (CNID of data structure being verified)
691
UInt64 TarBlock; // target block/node number being verified
692
SInt16 BTLevel; // current BTree enumeration level
693
SBTPT *BTPTPtr; // BTree path table pointer
694
SInt16 DirLevel; // current directory enumeration level
695
SDPT *DirPTPtr; // directory path table pointer
696
SInt16 CNType; // current CNode type
697
UInt32 ParID; // current parent DirID
698
CatalogName CName; // current CName
699
RepairOrderPtr MinorRepairsP; // ptr to list of problems for later repair
700
MissingThread *missingThreadList;
701
Ptr FCBAPtr; // pointer to scavenger FCB array
702
UInt32 **validFilesList; // List of valid HFS file IDs
704
ExtentsTable **overlappedExtents; // List of overlapped extents
705
FileIdentifierTable **fileIdentifierTable; // List of files for post processing
707
UInt32 inputFlags; // Caller can specify some DFA behaviors
709
UInt32 volumeFeatures; // bit vector of volume and OS features
710
Boolean usersAreConnected; // true if user are connected
711
Boolean fileSharingOn; // true if file sharing is on
712
UInt32 altBlockLocation;
713
Boolean checkingWrapper;
714
SInt16 numExtents; // Number of memory resident extents. 3 or 8
715
OSErr volumeErrorCode;
717
UserCancelUPP userCancelProc;
718
UserMessageUPP userMessageProc;
722
UInt64 itemsToProcess;
723
UInt64 itemsProcessed;
726
UInt16 secondsRemaining;
732
SFCB *calculatedExtentsFCB;
733
SFCB *calculatedCatalogFCB;
734
SFCB *calculatedAllocationsFCB;
735
SFCB *calculatedAttributesFCB;
736
SFCB *calculatedStartupFCB;
737
SFCB *calculatedRepairFCB;
738
BTreeControlBlock *calculatedExtentsBTCB;
739
BTreeControlBlock *calculatedCatalogBTCB;
740
BTreeControlBlock *calculatedRepairBTCB;
741
BTreeControlBlock *calculatedAttributesBTCB;
743
Boolean cleanUnmount;
748
Boolean minorRepairErrors; // indicates some minor repairs failed
749
int canWrite; // we can safely write to the block device
750
int lostAndFoundMode; // used when creating lost+found directory
751
BTScanState scanState;
753
unsigned char volumeName[256]; /* volume name in ASCII or UTF-8 */
755
PrimeBuckets CBTAttrBucket; /* prime number buckets for Attribute bit in Catalog btree */
756
PrimeBuckets CBTSecurityBucket; /* prime number buckets for Security bit in Catalog btree */
757
PrimeBuckets ABTAttrBucket; /* prime number buckets for Attribute bit in Attribute btree */
758
PrimeBuckets ABTSecurityBucket; /* prime number buckets for Security bit in Attribute btree */
759
attributeInfo lastAttrInfo; /* Record last attribute ID checked, used in CheckAttributeRecord, initialized in ScavSetup */
760
UInt16 securityAttrName[XATTR_MAXNAMELEN]; /* Store security attribute name in UTF16, to avoid frequent conversion */
761
size_t securityAttrLen;
767
supportsTrashVolumeCacheFeatureMask = 1,
768
supportsHFSPlusVolsFeatureMask = 2,
769
volumeIsMountedMask = 4
772
/* scavenger flags */
774
/* volume info status flags (contents of VIStat) */
776
#define S_MDB 0x8000 // MDB/VHB damaged
777
#define S_AltMDB 0x4000 // Unused /* alternate MDB damaged */
778
#define S_VBM 0x2000 // volume bit map damaged
779
#define S_WMDB 0x1000 // wrapper MDB is damaged
780
#define S_OverlappingExtents 0x0800 // Overlapping extents found
781
#define S_BadMDBdrAlBlSt 0x0400 // Invalid drAlBlSt field in MDB
782
#define S_InvalidWrapperExtents 0x0200 // Invalid catalog extent start in MDB
784
/* BTree status flags (contents of EBTStat, CBTStat and ABTStat) */
786
#define S_BTH 0x8000 /* BTree header damaged */
787
#define S_BTM 0x4000 /* BTree map damaged */
788
#define S_Indx 0x2000 // Unused /* index structure damaged */
789
#define S_Leaf 0x1000 // Unused /* leaf structure damaged */
790
#define S_Orphan 0x0800 // orphaned file
791
#define S_OrphanedExtent 0x0400 // orphaned extent
792
#define S_ReservedNotZero 0x0200 // the flags or reserved fields are not zero
793
#define S_RebuildBTree 0x0100 // similar to S_Indx, S_Leaf, but if one is bad we stop checking and the other may also be bad.
794
#define S_ReservedBTH 0x0080 // fields in the BTree header should be zero but are not
795
#define S_AttributeCount 0x0040 // incorrect number of xattr in attribute btree in comparison with attribute bit in catalog btree
796
#define S_SecurityCount 0x0020 // incorrect number of security xattrs in attribute btree in comparison with security bit in catalog btree
797
#define S_AttrRec 0x0010 // orphaned/unknown record in attribute BTree
799
/* catalog file status flags (contents of CatStat) */
801
#define S_IllName 0x8000 /* illegal name found */
802
#define S_Valence 0x4000 /* a directory valence is out of sync */
803
#define S_FThd 0x2000 /* dangling file thread records exist */
804
#define S_DFCorruption 0x1000 /* disappearing folder corruption detected */
805
#define S_NoDir 0x0800 /* missing directory record */
806
#define S_LockedDirName 0x0400 // locked dir name
807
#define S_MissingThread 0x0200 /* missing thread record */
808
#define S_UnlinkedFile 0x0100 /* orphaned link node */
809
#define S_LinkCount 0x0080 /* data node link count needs repair */
810
#define S_Permissions 0x0040 /* BSD permissions need repair */
811
#define S_FileAllocation 0x0020 /* peof or leof needs adjustment */
812
#define S_BadExtent 0x0010 /* invalid extent */
814
/* VeryMinorErrorsStat */
816
#define S_BloatedThreadRecordFound 0x8000 // 2210409, excessivly large thread record found
818
/* user file status flags (contents of FilStat) */
820
//#define S_LockedName 0x4000 // locked file name
822
/* Journal status flag (contents of JStat) */
823
#define S_BadJournal 0x8000 /* Bad journal content */
825
/* Print status flag (contents of PrintStat) */
826
#define S_DamagedDir 0x8000 /* message for M_LookDamagedDir already printed */
827
#define S_SymlinkCreate 0x4000 /* message for E_SymlinkCreate already printed */
829
/*------------------------------------------------------------------------------
831
------------------------------------------------------------------------------*/
833
// Command Codes (commands to ScavControl)
836
scavInitialize = 1, // Start initial volume check
837
scavVerify, // Start verify operation
838
scavRepair, // Start repair opeation
839
scavTerminate, // Cleanup after scavenge
846
repairLevelNoProblemsFound = 0,
847
repairLevelRepairIfOtherErrorsExist, // Bloated thread records, ...
848
repairLevelVeryMinorErrors, // Missing Custom Icon, Locked Directory name,..., Errors that don't need fixing from CheckDisk (Installer), Non Volume corruption bugs.
849
repairLevelVolumeRecoverable, // Minor Volume corruption exists
850
repairLevelSomeDataLoss, // Overlapping extents, some data loss but no scavaging will get it back
851
repairLevelWillCauseDataLoss, // Missing leaf nodes, repair will lose nodes without scavaging (proceed at your own risk, check disk with other utils)
852
repairLevelCatalogBtreeRebuild, // Catalog Btree is damaged, repair may lose some data
853
repairLevelUnrepairable // DFA cannot repair volume
857
/* Status messages written to summary */
861
M_CheckingHFSVolume = 1,
862
M_CheckingHFSPlusVolume = 2,
867
M_VolumeBitMapChk = 7,
871
M_RebuildingExtentsBTree = 11,
872
M_RebuildingCatalogBTree = 12,
873
M_RebuildingAttributesBTree = 13,
883
M_CaseSensitive = 23,
884
M_ReRepairFailed = 24,
885
M_LookDamagedDir = 25,
890
/*------------------------------------------------------------------------------
891
Scavenger Result/Error Codes
892
------------------------------------------------------------------------------*/
896
* If negative, they are unrecoverable (scavenging terminates).
897
* If positive, they are recoverable (scavenging continues).
903
E_PEOF = 500, /* Invalid PEOF */
904
E_LEOF = 501, /* Invalid LEOF */
905
E_DirVal = 502, /* Invalid directory valence */
906
E_CName = 503, /* Invalid CName */
907
E_NHeight = 504, /* Invalid node height */
908
E_NoFile = 505, /* Missing file record for file thread */
909
E_ABlkSz = -506, /* Invalid allocation block size */
910
E_NABlks = -507, /* Invalid number of allocation blocks */
911
E_VBMSt = -508, /* Invalid VBM start block */
912
E_ABlkSt = -509, /* Invalid allocation block start */
914
E_ExtEnt = -510, /* Invalid extent entry */
915
E_OvlExt = 511, /* overlapped extent allocation */
916
E_LenBTH = -512, /* Invalid BTH length */
917
E_ShortBTM = -513, /* BT map too short to repair */
918
E_BTRoot = -514, /* Invalid root node number */
919
E_NType = -515, /* Invalid node type */
920
E_NRecs = -516, /* Invalid record count */
921
E_IKey = -517, /* Invalid index key */
922
E_IndxLk = -518, /* Invalid index link */
923
E_SibLk = -519, /* Invalid sibling link */
925
E_BadNode = -520, /* Invalid node structure */
926
E_OvlNode = -521, /* overlapped node allocation */
927
E_MapLk = -522, /* Invalid map node linkage */
928
E_KeyLen = -523, /* Invalid key length */
929
E_KeyOrd = -524, /* Keys out of order */
930
E_BadMapN = -525, /* Invalid map node */
931
E_BadHdrN = -526, /* Invalid header node */
932
E_BTDepth = -527, /* exceeded maximum BTree depth */
933
E_CatRec = -528, /* Invalid catalog record type */
934
E_LenDir = -529, /* Invalid directory record length */
936
E_LenThd = -530, /* Invalid thread record length */
937
E_LenFil = -531, /* Invalid file record length */
938
E_NoRtThd = -532, /* Missing thread record for root directory */
939
E_NoThd = -533, /* Missing thread record */
940
E_NoDir = 534, /* Missing directory record */
941
E_ThdKey = -535, /* Invalid key for thread record */
942
E_ThdCN = -536, /* Invalid parent CName in thread record */
943
E_LenCDR = -537, /* Invalid catalog record length */
944
E_DirLoop = -538, /* loop in directory hierarchy */
945
E_RtDirCnt = 539, /* Invalid root directory count */
947
E_RtFilCnt = 540, /* Invalid root file count */
948
E_DirCnt = 541, /* Invalid volume directory count */
949
E_FilCnt = 542, /* Invalid volume file count */
950
E_CatPEOF = -543, /* Invalid catalog PEOF */
951
E_ExtPEOF = -544, /* Invalid extent file PEOF */
952
E_CatDepth = 545, /* exceeded maximum catalog depth */
953
E_NoFThdFlg = -546, /* file thread flag not set in file record */
954
E_CatalogFlagsNotZero = 547,
955
E_BadFileName = -548, /* Invalid file/folder name problem */
956
E_InvalidClumpSize = 549, /* bad file clump size */
958
E_InvalidBTreeHeader = 550, /* Invalid btree header */
959
E_LockedDirName = 551, /* Inappropriate locked folder name */
960
E_EntryNotFound = -552, /* volume catalog entry not found */
962
E_MDBDamaged = 554, /* MDB Damaged */
963
E_VolumeHeaderDamaged = 555, /* Volume Header Damaged */
964
E_VBMDamaged = 556, /* Volume Bit Map needs minor repair */
965
E_InvalidNodeSize = -557, /* Bad BTree node size */
970
E_VolumeHeaderTooNew = 561,
972
E_InternalFileOverlap = -563, /* This is a serious error */
973
E_InvalidVolumeHeader = -564,
974
E_InvalidMDBdrAlBlSt = 565,
975
E_InvalidWrapperExtents = 566,
976
E_InvalidLinkCount = 567, /* Invalid Hardlink count */
977
E_UnlinkedFile = 568, /* Unlinked file needs to be deleted */
978
E_InvalidPermissions = 569,
982
E_IncorrectNumThdRcd = 572,
983
E_SymlinkCreate = 573,
984
E_IncorrectAttrCount = 574, /* Incorrect attributes in attr btree with attr bits in catalog btree */
985
E_IncorrectSecurityCount= 575, /* Incorrect security attributes in attr btree with security bits in catalog btree */
986
E_PEOAttr = 576, /* Incorrect physical end of extended attribute data */
987
E_LEOAttr = 577, /* Incorrect logical end of extended attribute data */
988
E_AttrRec = 578, /* Invalid attribute record (overflow extent without original extent, unknown type) */
994
/* Internal DFA error codes */
996
errRebuildBtree = -1001 /* BTree requires rebuilding. */
1000
enum { /* extendFileContigMask = 0x0002*/
1001
kEFContigBit = 1, /* force contiguous allocation*/
1002
kEFContigMask = 0x02,
1003
kEFAllBit = 0, /* allocate all requested bytes or none*/
1005
kEFNoClumpBit = 2, /* Don't round up requested size to multiple of clump size*/
1006
kEFNoClumpMask = 0x04, /* TruncateFile option flags*/
1007
kTFTrunExtBit = 0, /* truncate to the extent containing new PEOF*/
1013
// Encoding vs. Index
1015
// For runtime table lookups and for the volume encoding bitmap we
1016
// need to map some encodings to keep them in a reasonable range.
1020
kTextEncodingMacRoman = 0L,
1021
kTextEncodingMacFarsi = 0x8C, /* Like MacArabic but uses Farsi digits*/
1022
/* The following use script code 7, smCyrillic*/
1023
kTextEncodingMacUkrainian = 0x98, /* The following use script code 32, smUnimplemented*/
1025
kIndexMacUkrainian = 48, // MacUkrainian encoding is 152
1026
kIndexMacFarsi = 49 // MacFarsi encoding is 140
1029
#define MapEncodingToIndex(e) \
1030
( (e) < 48 ? (e) : ( (e) == kTextEncodingMacUkrainian ? kIndexMacUkrainian : ( (e) == kTextEncodingMacFarsi ? kIndexMacFarsi : kTextEncodingMacRoman) ) )
1032
#define MapIndexToEncoding(i) \
1033
( (i) == kIndexMacFarsi ? kTextEncodingMacFarsi : ( (i) == kIndexMacUkrainian ? kTextEncodingMacUkrainian : (i) ) )
1035
#define ValidMacEncoding(e) \
1036
( ((e) < 39) || ((e) == kTextEncodingMacFarsi) || ((e) == kTextEncodingMacUkrainian) )
1041
extern void WriteMsg( SGlobPtr GPtr, short messageID, short messageType );
1042
extern void WriteError( SGlobPtr GPtr, short msgID, UInt32 tarID, UInt64 tarBlock );
1043
extern short CheckPause( void );
1045
extern void PrintError(SGlobPtr GPtr, short error, int vargc, ...);
1046
extern void PrintStatus(SGlobPtr GPtr, short status, int vargc, ...);
1049
/* ------------------------------- From SControl.c ------------------------------- */
1051
void ScavCtrl( SGlobPtr GPtr, UInt32 ScavOp, short *ScavRes );
1053
extern short CheckForStop( SGlobPtr GPtr );
1056
/* ------------------------------- From SRepair.c -------------------------------- */
1058
extern OSErr RepairVolume( SGlobPtr GPtr );
1060
extern int FixDFCorruption( const SGlobPtr GPtr, RepairOrderPtr DFOrderP );
1062
extern OSErr ProcessFileExtents( SGlobPtr GPtr, SFCB *fcb, UInt8 forkType, UInt16 flags, Boolean isExtentsBTree, Boolean *hasOverflowExtents, UInt32 *blocksUsed );
1064
/* Function to get return file path/name given an ID */
1065
extern OSErr GetSystemFileName(UInt32 fileID, char *filename, unsigned int *filenamelen);
1066
extern OSErr GetFileNamePathByID(SGlobPtr GPtr, UInt32 fileID, char *fullPath, unsigned int *fullPathLen, char *fileName, unsigned int *fileNameLen, u_int16_t *status);
1067
#define FNAME_BUF2SMALL 0x001 /* filename buffer was too small */
1068
#define FNAME_BIGNAME 0x002 /* filename is greater than NAME_MAX bytes */
1069
#define FPATH_BUF2SMALL 0x010 /* path buffer was too small */
1070
#define FPATH_BIGNAME 0x020 /* intermediate component in path is greater than NAME_MAX bytes */
1071
#define F_RESERVE_FILEID 0x100 /* file ID was less than kHFSFirstUserCatalogNodeID */
1073
/* ------------------------------- From SUtils.c --------------------------------- */
1075
extern int AllocBTN( SGlobPtr GPtr, short FilRefN, UInt32 NodeNum );
1077
extern int IntError( SGlobPtr GPtr, OSErr ErrCode );
1079
extern void RcdError( SGlobPtr GPtr, OSErr ErrCode );
1081
extern RepairOrderPtr AllocMinorRepairOrder( SGlobPtr GPtr, int extraBytes );
1083
extern void SetDFAStage( UInt32 stage );
1084
extern UInt32 GetDFAGlobals( void );
1086
extern void InitializeVolumeObject( SGlobPtr GPtr );
1087
extern void CheckEmbeddedVolInfoInMDBs( SGlobPtr GPtr );
1088
extern VolumeObjectPtr GetVolumeObjectPtr( void );
1089
extern OSErr GetVolumeObjectVHB( BlockDescriptor * theBlockDescPtr );
1090
extern void GetVolumeObjectBlockNum( UInt64 * theBlockNumPtr );
1091
extern OSErr GetVolumeObjectAlternateBlock( BlockDescriptor * theBlockDescPtr );
1092
extern OSErr GetVolumeObjectPrimaryBlock( BlockDescriptor * theBlockDescPtr );
1093
extern void GetVolumeObjectAlternateBlockNum( UInt64 * theBlockNumPtr );
1094
extern void GetVolumeObjectPrimaryBlockNum( UInt64 * theBlockNumPtr );
1095
extern OSErr GetVolumeObjectAlternateMDB( BlockDescriptor * theBlockDescPtr );
1096
extern OSErr GetVolumeObjectPrimaryMDB( BlockDescriptor * theBlockDescPtr );
1097
extern OSErr GetVolumeObjectVHBorMDB( BlockDescriptor * theBlockDescPtr );
1098
extern void PrintName( int theCount, const UInt8 *theNamePtr, Boolean isUnicodeString );
1099
extern void PrintVolumeObject( void );
1100
extern Boolean VolumeObjectIsValid( void );
1101
extern Boolean VolumeObjectIsHFSPlus( void );
1102
extern Boolean VolumeObjectIsHFS( void );
1103
extern Boolean VolumeObjectIsEmbeddedHFSPlus( void );
1104
extern Boolean VolumeObjectIsPureHFSPlus( void );
1105
extern void RecordXAttrBits(SGlobPtr GPtr, UInt16 flags, HFSCatalogNodeID fileid, UInt16 btreetype);
1106
extern int ComparePrimeBuckets(SGlobPtr GPtr, UInt16 BitMask);
1108
extern void InvalidateCalculatedVolumeBitMap( SGlobPtr GPtr );
1110
extern OSErr GetVolumeFeatures( SGlobPtr GPtr );
1112
OSErr FlushAlternateVolumeControlBlock( SVCB *vcb, Boolean isHFSPlus );
1114
extern void ConvertToHFSPlusExtent(const HFSExtentRecord oldExtents, HFSPlusExtentRecord newExtents);
1117
/* ------------------------------- From CatalogCheck.c -------------------------------- */
1119
extern OSErr CheckCatalogBTree( SGlobPtr GPtr ); // catalog btree check
1121
extern int RecordBadAllocation(UInt32 parID, unsigned char * filename, UInt32 forkType, UInt32 oldBlkCnt, UInt32 newBlkCnt);
1123
extern int RecordTruncation(UInt32 parID, unsigned char * filename, UInt32 forkType, UInt64 oldSize, UInt64 newSize);
1125
/* ------------------------------- From SVerify1.c -------------------------------- */
1127
extern OSErr CatFlChk( SGlobPtr GPtr ); // catalog file check
1129
extern OSErr CatHChk( SGlobPtr GPtr ); // catalog hierarchy check
1131
extern OSErr ExtBTChk( SGlobPtr GPtr ); // extent btree check
1133
extern OSErr BadBlockFileExtentCheck( SGlobPtr GPtr ); // bad block file extent check
1135
extern OSErr AttrBTChk( SGlobPtr GPtr ); // attributes btree check
1137
extern OSErr IVChk( SGlobPtr GPtr );
1139
extern int CheckForClean( SGlobPtr GPtr, Boolean markClean );
1141
extern int CheckIfJournaled(SGlobPtr GPtr);
1143
extern OSErr VInfoChk( SGlobPtr GPtr );
1145
extern OSErr VLockedChk( SGlobPtr GPtr );
1147
extern void BuildExtentKey( Boolean isHFSPlus, UInt8 forkType, HFSCatalogNodeID fileNumber, UInt32 blockNumber, void * key );
1149
extern OSErr OrphanedFileCheck( SGlobPtr GPtr, Boolean *problemsFound );
1151
extern int cmpLongs (const void *a, const void *b);
1153
extern int CheckAttributeRecord(SGlobPtr GPtr, const HFSPlusAttrKey *key, const HFSPlusAttrRecord *rec, UInt16 reclen);
1155
extern int FindOrigOverlapFiles(SGlobPtr GPtr);
1157
extern void PrintOverlapFiles (SGlobPtr GPtr);
1159
/* ------------------------------- From SVerify2.c -------------------------------- */
1161
typedef int (* CheckLeafRecordProcPtr)(SGlobPtr GPtr, void *key, void *record, UInt16 recordLen);
1163
extern int BTCheck(SGlobPtr GPtr, short refNum, CheckLeafRecordProcPtr checkLeafRecord);
1165
extern int BTMapChk( SGlobPtr GPtr, short FilRefN );
1167
extern OSErr ChkCName( SGlobPtr GPtr, const CatalogName *name, Boolean unicode ); // check catalog name
1169
extern OSErr CmpBTH( SGlobPtr GPtr, SInt16 fileRefNum );
1171
extern int CmpBTM( SGlobPtr GPtr, short FilRefN );
1173
extern int CmpMDB( SGlobPtr GPtr, HFSMasterDirectoryBlock * mdbP);
1175
extern int CmpVBM( SGlobPtr GPtr );
1177
extern OSErr CmpBlock( void *block1P, void *block2P, UInt32 length ); /* same as 'memcmp', but EQ/NEQ only */
1179
extern OSErr ChkExtRec ( SGlobPtr GPtr, const void *extents , unsigned int *lastExtentIndex);
1182
/* -------------------------- From SRebuildCatalogBTree.c ------------------------- */
1184
extern OSErr RebuildCatalogBTree( SGlobPtr theSGlobPtr );
1187
/* -------------------------- From SCatalog.c ------------------------- */
1189
extern OSErr UpdateFolderCount( SVCB *vcb,
1190
HFSCatalogNodeID pid,
1191
const CatalogName *name,
1194
SInt16 valenceDelta );
1196
/* ------------------------------- From SExtents.c -------------------------------- */
1197
OSErr ZeroFileBlocks( SVCB *vcb, SFCB *fcb, UInt32 startingSector, UInt32 numberOfSectors );
1199
OSErr MapFileBlockC (
1200
SVCB *vcb, // volume that file resides on
1201
SFCB *fcb, // FCB of file
1202
UInt32 numberOfBytes, // number of contiguous bytes desired
1203
UInt32 sectorOffset, // starting offset within file (in 512-byte sectors)
1204
UInt64 *startSector, // first 512-byte volume sector (NOT an allocation block)
1205
UInt32 *availableBytes); // number of contiguous bytes (up to numberOfBytes)
1207
OSErr DeallocateFile(SVCB *vcb, CatalogRecord * fileRec);
1210
SVCB *vcb, // volume that file resides on
1211
SFCB *fcb, // FCB of file to truncate
1212
UInt32 sectorsToAdd, // number of sectors to allocate
1213
UInt32 flags, // EFContig and/or EFAll
1214
UInt32 *actualSectorsAdded); // number of bytes actually allocated
1216
OSErr FlushExtentFile( SVCB *vcb );
1218
void ExtDataRecToExtents(
1219
const HFSExtentRecord oldExtents,
1220
HFSPlusExtentRecord newExtents);
1222
OSErr UpdateExtentRecord (
1225
const HFSPlusExtentKey *extentFileKey,
1226
HFSPlusExtentRecord extentData,
1227
UInt32 extentBTreeHint);
1229
OSErr CheckFileExtents( SGlobPtr GPtr, UInt32 fileNumber, UInt8 forkType, const unsigned char *xattrName,
1230
const void *extents, UInt32 *blocksUsed );
1231
OSErr GetBTreeHeader( SGlobPtr GPtr, SFCB* fcb, BTHeaderRec *header );
1232
OSErr CompareVolumeBitMap( SGlobPtr GPtr, SInt32 whichBuffer );
1233
OSErr CompareVolumeHeader( SGlobPtr GPtr, HFSPlusVolumeHeader *vh );
1234
OSErr CreateExtentsBTreeControlBlock( SGlobPtr GPtr );
1235
OSErr CreateCatalogBTreeControlBlock( SGlobPtr GPtr );
1236
OSErr CreateAttributesBTreeControlBlock( SGlobPtr GPtr );
1237
OSErr CreateExtendedAllocationsFCB( SGlobPtr GPtr );
1240
OSErr CacheWriteInPlace( SVCB *vcb, UInt32 fileRefNum, HIOParam *iopb, UInt64 currentPosition,
1241
UInt32 maximumBytes, UInt32 *actualBytes );
1244
/* Generic B-tree call back routines */
1245
OSStatus GetBlockProc (SFCB *filePtr, UInt32 blockNum, GetBlockOptions options, BlockDescriptor *block);
1246
OSStatus ReleaseBlockProc (SFCB *filePtr, BlockDescPtr blockPtr, ReleaseBlockOptions options);
1247
OSStatus SetEndOfForkProc (SFCB *filePtr, FSSize minEOF, FSSize maxEOF);
1248
OSStatus SetBlockSizeProc (SFCB *filePtr, ByteCount blockSize, ItemCount minBlockCount);
1250
void DFA_PrepareInputName(ConstStr31Param name, Boolean isHFSPlus, CatalogName *catalogName);
1252
extern UInt32 CatalogNameSize( const CatalogName *name, Boolean isHFSPlus);
1254
void SetupFCB( SVCB *vcb, SInt16 refNum, UInt32 fileID, UInt32 fileClumpSize );
1257
extern void CalculateItemCount( SGlob *GPtr, UInt64 *itemCount, UInt64 *onePercent );
1262
extern BTreeControlBlock* GetBTreeControlBlock( short refNum );
1263
#define GetBTreeControlBlock(refNum) ((BTreeControlBlock*) ResolveFCB((refNum))->fcbBtree)
1265
/* The following macro marks a VCB as dirty by setting the upper 8 bits of the flags*/
1266
EXTERN_API_C( void )
1267
MarkVCBDirty (SVCB * vcb);
1269
#define MarkVCBDirty(vcb) ((void) (vcb->vcbFlags |= 0xFF00))
1270
EXTERN_API_C( void )
1271
MarkVCBClean (SVCB * vcb);
1273
#define MarkVCBClean(vcb) ((void) (vcb->vcbFlags &= 0x00FF))
1274
EXTERN_API_C( Boolean )
1275
IsVCBDirty (SVCB * vcb);
1277
#define IsVCBDirty(vcb) ((Boolean) ((vcb->vcbFlags & 0xFF00) != 0))
1280
extern pascal void M_Debugger(void);
1281
extern pascal void M_DebugStr(ConstStr255Param debuggerMsg);
1283
#define M_Debuger() Debugger()
1284
#define M_DebugStr( debuggerMsg ) DebugStr( debuggerMsg )
1287
#define M_DebugStr( debuggerMsg )
1291
/* Test for error and return if error occurred*/
1292
EXTERN_API_C( void )
1293
ReturnIfError (OSErr result);
1295
#define ReturnIfError(result) if ( (result) != noErr ) return (result); else ;
1296
/* Test for passed condition and return if true*/
1297
EXTERN_API_C( void )
1298
ReturnErrorIf (Boolean condition,
1301
#define ReturnErrorIf(condition, error) if ( (condition) ) return( (error) );
1302
/* Exit function on error*/
1303
EXTERN_API_C( void )
1304
ExitOnError (OSErr result);
1306
#define ExitOnError( result ) if ( ( result ) != noErr ) goto ErrorExit; else ;
1308
/* Return the low 16 bits of a 32 bit value, pinned if too large*/
1309
EXTERN_API_C( UInt16 )
1310
LongToShort (UInt32 l);
1312
#define LongToShort( l ) l <= (UInt32)0x0000FFFF ? ((UInt16) l) : ((UInt16) 0xFFFF)
1315
EXTERN_API_C( UInt32 )
1319
DeleteCatalogNode(SVCB *vcb, UInt32 pid, const CatalogName * name, UInt32 hint);
1322
GetCatalogNode(SVCB *vcb, UInt32 pid, const CatalogName * name, UInt32 hint, CatalogRecord *data);
1324
EXTERN_API_C( SInt32 )
1325
CompareCatalogKeys (HFSCatalogKey * searchKey,
1326
HFSCatalogKey * trialKey);
1328
EXTERN_API_C( SInt32 )
1329
CompareExtendedCatalogKeys (HFSPlusCatalogKey * searchKey,
1330
HFSPlusCatalogKey * trialKey);
1331
EXTERN_API_C( SInt32 )
1332
CaseSensitiveCatalogKeyCompare (HFSPlusCatalogKey * searchKey,
1333
HFSPlusCatalogKey * trialKey);
1335
EXTERN_API_C( SInt32 )
1336
CompareExtentKeys (const HFSExtentKey * searchKey,
1337
const HFSExtentKey * trialKey);
1339
EXTERN_API_C( SInt32 )
1340
CompareExtentKeysPlus (const HFSPlusExtentKey * searchKey,
1341
const HFSPlusExtentKey * trialKey);
1342
EXTERN_API_C( SInt32 )
1343
CompareAttributeKeys (const AttributeKey * searchKey, const AttributeKey * trialKey);
1345
ResolveFCB (short fileRefNum);
1347
EXTERN_API_C( OSErr )
1348
ValidVolumeHeader (HFSPlusVolumeHeader * volumeHeader);
1351
/* Old B-tree Manager API (going away soon!) */
1353
EXTERN_API_C( OSErr )
1354
SearchBTreeRecord (SFCB *fcb,
1362
EXTERN_API_C( OSErr )
1363
GetBTreeRecord (SFCB *fcb,
1364
SInt16 selectionIndex,
1370
EXTERN_API_C( OSErr )
1371
InsertBTreeRecord (SFCB *fcb,
1377
EXTERN_API_C( OSErr )
1378
DeleteBTreeRecord (SFCB *fcb,
1381
EXTERN_API_C( OSErr )
1382
ReplaceBTreeRecord (SFCB *fcb,
1389
EXTERN_API_C( void )
1390
InitBTreeHeader (UInt32 fileSize,
1399
EXTERN_API_C( OSErr )
1400
UpdateFreeCount (SVCB * vcb);
1403
EXTERN_API_C(Boolean)
1404
NodesAreContiguous( SFCB *fcb,
1409
UInt32 GetTimeUTC(void);
1410
UInt32 GetTimeLocal(Boolean forHFS);
1412
OSErr FlushVolumeControlBlock( SVCB *vcb );
1414
pascal short ResolveFileRefNum(SFCB * fileCtrlBlockPtr);
1416
extern UInt32 CatalogNameLength( const CatalogName *name, Boolean isHFSPlus);
1418
extern void CopyCatalogName( const CatalogName *srcName, CatalogName *dstName, Boolean isHFSPLus);
1420
extern void UpdateCatalogName( ConstStr31Param srcName, Str31 destName);
1422
extern void BuildCatalogKey( HFSCatalogNodeID parentID, const CatalogName *name, Boolean isHFSPlus,
1425
extern void UpdateVolumeEncodings( SVCB *volume, TextEncoding encoding);
1428
OSErr BlockAllocate (SVCB *vcb, UInt32 startingBlock, UInt32 blocksRequested, UInt32 blocksMaximum,
1429
Boolean forceContiguous, UInt32 *actualStartBlock, UInt32 *actualNumBlocks);
1430
OSErr BlockDeallocate ( SVCB *vcb, UInt32 firstBlock, UInt32 numBlocks);
1431
UInt32 DivideAndRoundUp( UInt32 numerator, UInt32 denominator);
1433
OSErr InitializeBlockCache ( UInt32 blockSize, UInt32 blockCount );
1435
void SetFCBSPtr( Ptr value );
1436
Ptr GetFCBSPtr( void );
1440
* UTF-8 conversion routines
1442
extern int utf_decodestr(const unsigned char *, size_t, u_int16_t *, size_t *);
1443
extern int utf_encodestr(const u_int16_t *, size_t, unsigned char *, size_t *);
1446
* HardLink checking routines
1448
extern int HardLinkCheckBegin(SGlobPtr gp, void** cookie);
1449
extern void HardLinkCheckEnd(void * cookie);
1450
extern void CaptureHardLink(void * cookie, UInt32 linkID);
1451
extern int CheckHardLinks(void *cookie);
1454
* Volume Bitmap checking routines
1456
extern int BitMapCheckBegin(SGlobPtr g);
1457
extern int BitMapCheckEnd(void);
1458
extern int CaptureBitmapBits(UInt32 startBit, UInt32 bitCount);
1459
extern int ReleaseBitmapBits(UInt32 startBit, UInt32 bitCount);
1460
extern int CheckVolumeBitMap(SGlobPtr g, Boolean repair);
1461
extern void UpdateFreeBlockCount(SGlobPtr g);
1462
extern int AllocateContigBitmapBits (SVCB *vcb, UInt32 numBlocks, UInt32 *actualStartBlock);
1468
#endif /* __SCAVENGER__ */