#define SHOW_ELAPSED_TIMES 0
#if SHOW_ELAPSED_TIMES
#include <sys/time.h>
#endif
#include "Scavenger.h"
#define DisplayTimeRemaining 0
int gGUIControl;
static void printVerifyStatus( SGlobPtr GPtr );
static Boolean IsBlueBoxSharedDrive ( DrvQElPtr dqPtr );
static int ScavSetUp( SGlobPtr GPtr );
static int ScavTerm( SGlobPtr GPtr );
int cancelProc(UInt16 progress, UInt16 secondsRemaining, Boolean progressChanged, UInt16 stage, void *context)
{
if (progressChanged)
plog("(%d %%)\n", progress);
fflush(stdout);
return 0;
}
int
CheckHFS( const char *rdevnode, int fsReadRef, int fsWriteRef, int checkLevel,
int repairLevel, int logLevel, int guiControl, int lostAndFoundMode,
int canWrite, int *modified, int liveMode )
{
SGlob dataArea; short temp;
FileIdentifierTable *fileIdentifierTable = nil;
OSErr err = noErr;
OSErr scavError = 0;
int scanCount = 0;
int isJournaled = 0;
Boolean autoRepair;
autoRepair = (fsWriteRef != -1 && repairLevel != kNeverRepair);
DoAgain:
ClearMemory( &dataArea, sizeof(SGlob) );
dataArea.itemsProcessed = 0; dataArea.itemsToProcess = 1;
dataArea.chkLevel = checkLevel;
dataArea.repairLevel = repairLevel;
dataArea.logLevel = logLevel;
dataArea.canWrite = canWrite;
dataArea.writeRef = fsWriteRef;
dataArea.lostAndFoundMode = lostAndFoundMode;
dataArea.DrvNum = fsReadRef;
dataArea.liveVerifyState = liveMode;
dataArea.scanCount = scanCount;
if (strlcpy(dataArea.deviceNode, rdevnode, sizeof(dataArea.deviceNode)) != strlen(rdevnode)) {
dataArea.deviceNode[0] = '\0';
}
dataArea.volumeName[ 0 ] = ' ';
dataArea.volumeName[ 1 ] = '\0';
if (guiControl) {
dataArea.guiControl = true;
dataArea.userCancelProc = cancelProc;
}
ScavCtrl( &dataArea, scavInitialize, &scavError );
if ( checkLevel == kNeverCheck || (checkLevel == kDirtyCheck && dataArea.cleanUnmount) ||
scavError == R_NoMem || scavError == R_BadSig) {
goto termScav;
}
isJournaled = CheckIfJournaled( &dataArea, false );
if (isJournaled != 0
&& scanCount == 0
&& checkLevel != kForceCheck
&& !(checkLevel == kPartialCheck && repairLevel == kForceRepairs)) {
if (!guiControl) {
plog("fsck_hfs: Volume is journaled. No checking performed.\n");
plog("fsck_hfs: Use the -f option to force checking.\n");
}
scavError = 0;
goto termScav;
}
dataArea.calculatedVCB->vcbDriveNumber = fsReadRef;
dataArea.calculatedVCB->vcbDriverWriteRef = fsWriteRef;
if ( scavError == noErr )
ScavCtrl( &dataArea, scavVerify, &scavError );
if (scavError == noErr && logLevel >= kDebugLog)
printVerifyStatus(&dataArea);
if (scanCount >= kMaxReScan && (dataArea.RepLevel != repairLevelNoProblemsFound)) {
PrintStatus(&dataArea, M_ReRepairFailed, 1, dataArea.volumeName);
scavError = R_RFail;
goto termScav;
}
if ( dataArea.RepLevel == repairLevelUnrepairable )
err = cdUnrepairableErr;
if ( !autoRepair &&
(dataArea.RepLevel == repairLevelVolumeRecoverable ||
dataArea.RepLevel == repairLevelCatalogBtreeRebuild ||
dataArea.RepLevel == repairLevelVeryMinorErrors) ) {
PrintStatus(&dataArea, M_NeedsRepair, 1, dataArea.volumeName);
scavError = R_VFail;
goto termScav;
}
if ( scavError == noErr && dataArea.RepLevel == repairLevelNoProblemsFound ) {
if (scanCount == 0) {
PrintStatus(&dataArea, M_AllOK, 1, dataArea.volumeName);
} else {
PrintStatus(&dataArea, M_RepairOK, 1, dataArea.volumeName);
}
}
if ( dataArea.RepLevel == repairLevelNoProblemsFound && repairLevel == kForceRepairs )
{
dataArea.CBTStat |= S_RebuildBTree;
dataArea.RepLevel = repairLevelCatalogBtreeRebuild;
}
if ( ((scavError == noErr) || (scavError == errRebuildBtree)) &&
(autoRepair == true) &&
(dataArea.RepLevel != repairLevelUnrepairable) &&
(dataArea.RepLevel != repairLevelNoProblemsFound) )
{
if ( dataArea.canWrite == 0 ) {
scavError = R_WrErr;
PrintStatus( &dataArea, M_RepairOtherWriters, 0 );
}
else
ScavCtrl( &dataArea, scavRepair, &scavError );
if ( scavError == noErr )
{
*modified = 1;
ScavCtrl( &dataArea, scavTerminate, &temp );
repairLevel = kMajorRepairs;
checkLevel = kAlwaysCheck;
PrintStatus(&dataArea, M_Rescan, 0);
scanCount++;
goto DoAgain;
}
else
PrintStatus(&dataArea, M_RepairFailed, 1, dataArea.volumeName);
}
else if ( scavError != noErr ) {
PrintStatus(&dataArea, M_CheckFailed, 0);
if ( logLevel >= kDebugLog )
plog("volume check failed with error %d \n", scavError);
}
if ( (autoRepair == true) && (dataArea.fileIdentifierTable != nil) )
{
fileIdentifierTable = (FileIdentifierTable *) AllocateMemory( GetHandleSize( (Handle) dataArea.fileIdentifierTable ) );
CopyMemory( *(dataArea.fileIdentifierTable), fileIdentifierTable, GetHandleSize( (Handle) dataArea.fileIdentifierTable ) );
}
if ( fileIdentifierTable != nil )
{
DisposeMemory( fileIdentifierTable );
}
termScav:
if (err == noErr) {
err = scavError;
}
if ( logLevel >= kDebugLog &&
(err != noErr || dataArea.RepLevel != repairLevelNoProblemsFound) )
PrintVolumeObject();
if (fsWriteRef != -1) {
Boolean update;
if (scavError) {
CheckForClean(&dataArea, kMarkVolumeDirty, &update);
} else {
CheckForClean(&dataArea, kMarkVolumeClean, &update);
}
if (update) {
*modified = 1;
}
}
ScavCtrl( &dataArea, scavTerminate, &temp );
return( err );
}
void ScavCtrl( SGlobPtr GPtr, UInt32 ScavOp, short *ScavRes )
{
OSErr result;
unsigned int stat;
#if SHOW_ELAPSED_TIMES
struct timeval myStartTime;
struct timeval myEndTime;
struct timeval myElapsedTime;
struct timezone zone;
#endif
result = noErr; *ScavRes = 0;
GPtr->ScavRes = 0;
switch ( ScavOp )
{
case scavInitialize: {
Boolean modified;
int clean;
if ( ( result = ScavSetUp( GPtr ) ) ) break;
if ( IsBlueBoxSharedDrive( GPtr->DrvPtr ) )
break;
if ( ( result = CheckForStop( GPtr ) ) ) break;
clean = CheckForClean(GPtr, kCheckVolume, &modified);
if ((GPtr->chkLevel == kDirtyCheck) || (GPtr->chkLevel == kNeverCheck)) {
if (clean == 1) {
GPtr->cleanUnmount = true;
break;
}
if (GPtr->chkLevel == kNeverCheck) {
if (clean == -1)
result = R_BadSig;
else if (clean == 0) {
if (CheckIfJournaled(GPtr, false))
GPtr->cleanUnmount = true;
else
result = R_Dirty;
}
break;
}
}
if (CheckIfJournaled(GPtr, false)
&& GPtr->chkLevel != kForceCheck
&& !(GPtr->chkLevel == kPartialCheck && GPtr->repairLevel == kForceRepairs)
&& !(GPtr->chkLevel == kAlwaysCheck && GPtr->repairLevel == kMajorRepairs)) {
break;
}
if (GPtr->liveVerifyState) {
PrintStatus(GPtr, M_LiveVerify, 0);
} else if (GPtr->canWrite == 0) {
PrintStatus(GPtr, M_VerifyOtherWriters, 0);
}
if ((GPtr->scanCount == 0) &&
(CheckIfJournaled(GPtr, true) == 1) &&
(GPtr->canWrite == 1) && (GPtr->writeRef != -1)) {
result = journal_replay(GPtr);
if (GPtr->logLevel >= kDebugLog) {
if (result) {
plog ("\tJournal replay returned error = %d\n", result);
} else {
plog ("\tJournal replayed successfully or journal was empty\n");
}
}
}
result = IVChk( GPtr );
break;
}
case scavVerify: {
#if SHOW_ELAPSED_TIMES
gettimeofday( &myStartTime, &zone );
#endif
if ( BitMapCheckBegin(GPtr) != 0)
break;
#if SHOW_ELAPSED_TIMES
gettimeofday( &myEndTime, &zone );
timersub( &myEndTime, &myStartTime, &myElapsedTime );
plog( "\n%s - BitMapCheck elapsed time \n", __FUNCTION__ );
plog( "########## secs %d msecs %d \n\n",
myElapsedTime.tv_sec, myElapsedTime.tv_usec );
#endif
if ( IsBlueBoxSharedDrive( GPtr->DrvPtr ) )
break;
if ( ( result = CheckForStop( GPtr ) ) )
break;
#if SHOW_ELAPSED_TIMES
gettimeofday( &myStartTime, &zone );
#endif
if ( ( result = CreateExtentsBTreeControlBlock( GPtr ) ) )
break;
if ( ( result = CreateCatalogBTreeControlBlock( GPtr ) ) )
break;
if ( ( result = CreateAttributesBTreeControlBlock( GPtr ) ) )
break;
if ( ( result = CreateExtendedAllocationsFCB( GPtr ) ) )
break;
#if SHOW_ELAPSED_TIMES
gettimeofday( &myEndTime, &zone );
timersub( &myEndTime, &myStartTime, &myElapsedTime );
plog( "\n%s - create control blocks elapsed time \n", __FUNCTION__ );
plog( ">>>>>>>>>>>>> secs %d msecs %d \n\n",
myElapsedTime.tv_sec, myElapsedTime.tv_usec );
#endif
CalculateItemCount( GPtr, &GPtr->itemsToProcess, &GPtr->onePercent );
GPtr->itemsProcessed += GPtr->onePercent;
if ( ( result = VLockedChk( GPtr ) ) )
break;
GPtr->itemsProcessed += GPtr->onePercent; WriteMsg( GPtr, M_ExtBTChk, kStatusMessage );
#if SHOW_ELAPSED_TIMES
gettimeofday( &myStartTime, &zone );
#endif
if ((result = ExtBTChk(GPtr)))
break;
#if SHOW_ELAPSED_TIMES
gettimeofday( &myEndTime, &zone );
timersub( &myEndTime, &myStartTime, &myElapsedTime );
plog( "\n%s - ExtBTChk elapsed time \n", __FUNCTION__ );
plog( ">>>>>>>>>>>>> secs %d msecs %d \n\n",
myElapsedTime.tv_sec, myElapsedTime.tv_usec );
#endif
if ((result = CheckForStop(GPtr)))
break;
GPtr->itemsProcessed += GPtr->onePercent;
if ((result = BadBlockFileExtentCheck(GPtr)))
break;
if ((result = CheckForStop(GPtr)))
break;
GPtr->itemsProcessed += GPtr->onePercent; GPtr->itemsProcessed += GPtr->onePercent;
WriteMsg( GPtr, M_CatBTChk, kStatusMessage );
#if SHOW_ELAPSED_TIMES
gettimeofday( &myStartTime, &zone );
#endif
if ( GPtr->chkLevel == kPartialCheck )
{
GPtr->CBTStat |= S_RebuildBTree;
result = errRebuildBtree;
break;
}
if ((result = CheckCatalogBTree(GPtr)))
break;
#if SHOW_ELAPSED_TIMES
gettimeofday( &myEndTime, &zone );
timersub( &myEndTime, &myStartTime, &myElapsedTime );
plog( "\n%s - CheckCatalogBTree elapsed time \n", __FUNCTION__ );
plog( ">>>>>>>>>>>>> secs %d msecs %d \n\n",
myElapsedTime.tv_sec, myElapsedTime.tv_usec );
#endif
if ((result = CheckForStop(GPtr)))
break;
WriteMsg( GPtr, M_CatHChk, kStatusMessage );
#if SHOW_ELAPSED_TIMES
gettimeofday( &myStartTime, &zone );
#endif
if ((result = CatHChk(GPtr)))
break;
#if SHOW_ELAPSED_TIMES
gettimeofday( &myEndTime, &zone );
timersub( &myEndTime, &myStartTime, &myElapsedTime );
plog( "\n%s - CatHChk elapsed time \n", __FUNCTION__ );
plog( ">>>>>>>>>>>>> secs %d msecs %d \n\n",
myElapsedTime.tv_sec, myElapsedTime.tv_usec );
#endif
if ((result = CheckForStop(GPtr)))
break;
if (VolumeObjectIsHFSX(GPtr)) {
result = CheckFolderCount(GPtr);
if (result)
break;
if ((result=CheckForStop(GPtr)))
break;
}
if ((result = AttrBTChk(GPtr)))
break;
if ((result = CheckForStop(GPtr)))
break;
if (GPtr->VIStat & S_OverlappingExtents) {
result = FindOrigOverlapFiles(GPtr);
if (result) {
break;
}
(void) PrintOverlapFiles(GPtr);
}
result = dirhardlink_check(GPtr);
if ((result != 0) || (GPtr->CatStat & S_LinkErrNoRepair)) {
if (result == 0) {
result = -1;
}
break;
}
WriteMsg( GPtr, M_VolumeBitMapChk, kStatusMessage );
#if SHOW_ELAPSED_TIMES
gettimeofday( &myStartTime, &zone );
#endif
if ((result = CheckVolumeBitMap(GPtr, false)))
break;
#if SHOW_ELAPSED_TIMES
gettimeofday( &myEndTime, &zone );
timersub( &myEndTime, &myStartTime, &myElapsedTime );
plog( "\n%s - CheckVolumeBitMap elapsed time \n", __FUNCTION__ );
plog( ">>>>>>>>>>>>> secs %d msecs %d \n\n",
myElapsedTime.tv_sec, myElapsedTime.tv_usec );
#endif
if ((result = CheckForStop(GPtr)))
break;
WriteMsg( GPtr, M_VInfoChk, kStatusMessage );
#if SHOW_ELAPSED_TIMES
gettimeofday( &myStartTime, &zone );
#endif
if ((result = VInfoChk(GPtr)))
break;
#if SHOW_ELAPSED_TIMES
gettimeofday( &myEndTime, &zone );
timersub( &myEndTime, &myStartTime, &myElapsedTime );
plog( "\n%s - VInfoChk elapsed time \n", __FUNCTION__ );
plog( ">>>>>>>>>>>>> secs %d msecs %d \n\n",
myElapsedTime.tv_sec, myElapsedTime.tv_usec );
#endif
stat = GPtr->VIStat | GPtr->ABTStat | GPtr->EBTStat | GPtr->CBTStat |
GPtr->CatStat | GPtr->JStat;
if ( stat != 0 )
{
if ( (GPtr->RepLevel == repairLevelNoProblemsFound) || (GPtr->RepLevel == repairLevelVolumeRecoverable) )
{
unsigned int minorErrors = (GPtr->CatStat & ~S_LockedDirName) |
GPtr->VIStat | GPtr->ABTStat | GPtr->EBTStat | GPtr->CBTStat | GPtr->JStat;
if ( minorErrors == 0 )
GPtr->RepLevel = repairLevelVeryMinorErrors;
else
GPtr->RepLevel = repairLevelVolumeRecoverable;
}
}
else if ( GPtr->RepLevel == repairLevelNoProblemsFound )
{
}
GPtr->itemsProcessed = GPtr->itemsToProcess;
result = CheckForStop(GPtr); break;
}
case scavRepair: {
if ( IsBlueBoxSharedDrive( GPtr->DrvPtr ) )
break;
if ( ( result = CheckForStop(GPtr) ) )
break;
if ( GPtr->CBTStat & S_RebuildBTree )
WriteMsg( GPtr, M_RebuildingCatalogBTree, kTitleMessage );
else
WriteMsg( GPtr, M_Repair, kTitleMessage );
result = RepairVolume( GPtr );
break;
}
case scavTerminate: {
result = ScavTerm(GPtr);
break;
}
}
if ( (result < 0) || (result > Max_RCode) )
{
switch ( ScavOp )
{
case scavInitialize:
case scavVerify:
if ( result == ioErr )
result = R_RdErr;
else if ( result == errRebuildBtree )
{
GPtr->RepLevel = repairLevelCatalogBtreeRebuild;
break;
}
else
result = R_VFail;
GPtr->RepLevel = repairLevelUnrepairable;
break;
case scavRepair:
result = R_RFail;
break;
default:
result = R_IntErr;
}
}
GPtr->ScavRes = result;
*ScavRes = result;
}
short CheckForStop( SGlob *GPtr )
{
OSErr err = noErr; long ticks = TickCount();
UInt16 dfaStage = (UInt16) GetDFAStage();
if ( GPtr->userCancelProc != nil )
{
UInt64 progress = 0;
Boolean progressChanged;
if ( dfaStage != kRepairStage )
{
progress = GPtr->itemsProcessed * 100;
progress /= GPtr->itemsToProcess;
progressChanged = ( progress != GPtr->lastProgress );
GPtr->lastProgress = progress;
#if( DisplayTimeRemaining )
if ( (progressChanged) && (progress > 5) )
{
elapsedTicks = TickCount() - GPtr->startTicks;
GPtr->secondsRemaining = ( ( ( 100 * elapsedTicks ) / progress ) - elapsedTicks ) / 60;
}
#endif
err = CallUserCancelProc( GPtr->userCancelProc, (UInt16)progress, (UInt16)GPtr->secondsRemaining, progressChanged, dfaStage, GPtr->userContext );
}
else
{
(void) CallUserCancelProc( GPtr->userCancelProc, (UInt16)progress, 0, false, dfaStage, GPtr->userContext );
}
}
if ( err != noErr )
err = R_UInt;
#if 0
if ( GPtr->realVCB ) if ( GPtr->realVCB->vcbWrCnt != GPtr->wrCnt )
err = R_Modified; #endif
GPtr->lastTickCount = ticks;
return ( err );
}
struct ScavStaticStructures {
SVCB vcb;
SFCB fcbList[6];
BTreeControlBlock btcb[4]; SDPT dirPath; SBTPT btreePath; };
typedef struct ScavStaticStructures ScavStaticStructures;
static int ScavSetUp( SGlob *GPtr)
{
OSErr err;
SVCB * vcb;
#if !BSD
DrvQEl *drvP;
short ioRefNum;
#endif
GPtr->MinorRepairsP = nil;
GPtr->itemsProcessed = 0;
GPtr->lastProgress = 0;
GPtr->startTicks = TickCount();
{
ScavStaticStructures *pointer;
pointer = (ScavStaticStructures *) AllocateClearMemory( sizeof(ScavStaticStructures) );
if ( pointer == nil ) {
if ( GPtr->logLevel >= kDebugLog ) {
plog( "\t error %d - could not allocate %ld bytes of memory \n",
R_NoMem, sizeof(ScavStaticStructures) );
}
return( R_NoMem );
}
GPtr->calculatedVCB = vcb = &pointer->vcb;
vcb->vcbGPtr = GPtr;
GPtr->FCBAPtr = (Ptr) &pointer->fcbList;
GPtr->calculatedExtentsFCB = &pointer->fcbList[0];
GPtr->calculatedCatalogFCB = &pointer->fcbList[1];
GPtr->calculatedAllocationsFCB = &pointer->fcbList[2];
GPtr->calculatedAttributesFCB = &pointer->fcbList[3];
GPtr->calculatedStartupFCB = &pointer->fcbList[4];
GPtr->calculatedRepairFCB = &pointer->fcbList[5];
GPtr->calculatedExtentsBTCB = &pointer->btcb[0];
GPtr->calculatedCatalogBTCB = &pointer->btcb[1];
GPtr->calculatedRepairBTCB = &pointer->btcb[2];
GPtr->calculatedAttributesBTCB = &pointer->btcb[3];
GPtr->BTPTPtr = (SBTPT*) &pointer->btreePath;
GPtr->DirPTPtr = (SDPT*) &pointer->dirPath;
}
SetDFAStage( kVerifyStage );
SetFCBSPtr( GPtr->FCBAPtr );
GPtr->DrvPtr = 0;
#if !BSD
err = FindDrive( &ioRefNum, &(GPtr->DrvPtr), GPtr->DrvNum );
#endif
if ( IsBlueBoxSharedDrive( GPtr->DrvPtr ) )
return noErr;
err = GetVolumeFeatures( GPtr );
#if !BSD
if ( GPtr->DrvPtr == NULL ) return ( R_NoVol );
else
drvP = GPtr->DrvPtr;
if ( GPtr->volumeFeatures & volumeIsMountedMask )
{
FlushVol( nil, GPtr->realVCB->vcbVRefNum ); GPtr->wrCnt = GPtr->realVCB->vcbWrCnt; }
#endif
#if BSD
InitBlockCache(vcb);
vcb->vcbDriveNumber = GPtr->DrvNum;
vcb->vcbDriverReadRef = GPtr->DrvNum;
vcb->vcbDriverWriteRef = -1;
#else
vcb->vcbDriveNumber = drvP->dQDrive;
vcb->vcbDriverReadRef = drvP->dQRefNum;
vcb->vcbDriverWriteRef = drvP->dQRefNum;
vcb->vcbFSID = drvP->dQFSID;
#endif
{
SFCB *fcb;
fcb = GPtr->calculatedExtentsFCB;
fcb->fcbFileID = kHFSExtentsFileID;
fcb->fcbVolume = vcb;
fcb->fcbBtree = GPtr->calculatedExtentsBTCB;
vcb->vcbExtentsFile = fcb;
fcb = GPtr->calculatedCatalogFCB;
fcb->fcbFileID = kHFSCatalogFileID;
fcb->fcbVolume = vcb;
fcb->fcbBtree = GPtr->calculatedCatalogBTCB;
vcb->vcbCatalogFile = fcb;
fcb = GPtr->calculatedAllocationsFCB;
fcb->fcbFileID = kHFSAllocationFileID;
fcb->fcbVolume = vcb;
fcb->fcbBtree = NULL; vcb->vcbAllocationFile = fcb;
fcb = GPtr->calculatedAttributesFCB;
fcb->fcbFileID = kHFSAttributesFileID;
fcb->fcbVolume = vcb;
fcb->fcbBtree = GPtr->calculatedAttributesBTCB;
vcb->vcbAttributesFile = fcb;
fcb = GPtr->calculatedStartupFCB;
fcb->fcbFileID = kHFSStartupFileID;
fcb->fcbVolume = vcb;
fcb->fcbBtree = NULL;
vcb->vcbStartupFile = fcb;
}
{
BTreeControlBlock *btcb;
btcb = GPtr->calculatedExtentsBTCB; btcb->fcbPtr = GPtr->calculatedExtentsFCB;
btcb->getBlockProc = GetFileBlock;
btcb->releaseBlockProc = ReleaseFileBlock;
btcb->setEndOfForkProc = SetEndOfForkProc;
btcb = GPtr->calculatedCatalogBTCB; btcb->fcbPtr = GPtr->calculatedCatalogFCB;
btcb->getBlockProc = GetFileBlock;
btcb->releaseBlockProc = ReleaseFileBlock;
btcb->setEndOfForkProc = SetEndOfForkProc;
btcb = GPtr->calculatedAttributesBTCB; btcb->fcbPtr = GPtr->calculatedAttributesFCB;
btcb->getBlockProc = GetFileBlock;
btcb->releaseBlockProc = ReleaseFileBlock;
btcb->setEndOfForkProc = SetEndOfForkProc;
}
GPtr->RepLevel = repairLevelNoProblemsFound;
GPtr->ErrCode = 0;
GPtr->IntErr = noErr;
GPtr->VIStat = 0;
GPtr->ABTStat = 0;
GPtr->EBTStat = 0;
GPtr->CBTStat = 0;
GPtr->CatStat = 0;
GPtr->VeryMinorErrorsStat = 0;
GPtr->JStat = 0;
GPtr->cleanUnmount = false;
InitializeVolumeObject( GPtr );
if (VolumeObjectIsValid() == false) {
return (R_BadSig);
}
GPtr->validFilesList = (UInt32**)NewHandle( 0 );
if ( GPtr->validFilesList == nil ) {
if ( GPtr->logLevel >= kDebugLog ) {
plog( "\t error %d - could not allocate file ID list \n", R_NoMem );
}
return( R_NoMem );
}
(void) utf_decodestr((unsigned char *)KAUTH_FILESEC_XATTR, strlen(KAUTH_FILESEC_XATTR), GPtr->securityAttrName, &GPtr->securityAttrLen, sizeof(GPtr->securityAttrName));
return( noErr );
}
static int ScavTerm( SGlobPtr GPtr )
{
SFCB *fcbP;
BTreeControlBlock *btcbP;
RepairOrderPtr rP;
OSErr err;
ExtentsTable **extentsTableH;
ExtentInfo *curExtentInfo;
int i;
(void) BitMapCheckEnd();
while( (rP = GPtr->MinorRepairsP) != nil ) {
GPtr->MinorRepairsP = rP->link; DisposeMemory(rP);
err = MemError();
}
if( GPtr->validFilesList != nil )
DisposeHandle( (Handle) GPtr->validFilesList );
if( GPtr->overlappedExtents != nil ) {
extentsTableH = GPtr->overlappedExtents;
for (i=0; i<(**extentsTableH).count; i++) {
curExtentInfo = &((**extentsTableH).extentInfo[i]);
if (curExtentInfo->attrname) {
free(curExtentInfo->attrname);
}
}
DisposeHandle( (Handle) GPtr->overlappedExtents );
}
if( GPtr->fileIdentifierTable != nil )
DisposeHandle( (Handle) GPtr->fileIdentifierTable );
if( GPtr->calculatedVCB == nil ) return( noErr );
fcbP = GPtr->calculatedExtentsFCB; if ( fcbP != nil )
{
btcbP = (BTreeControlBlock*)fcbP->fcbBtree;
if ( btcbP != nil)
{
if( btcbP->refCon != (UInt32)nil )
{
if(((BTreeExtensionsRec*)btcbP->refCon)->BTCBMPtr != nil)
{
DisposeMemory(((BTreeExtensionsRec*)btcbP->refCon)->BTCBMPtr);
err = MemError();
}
DisposeMemory( (Ptr)btcbP->refCon );
err = MemError();
btcbP->refCon = (UInt32)nil;
}
fcbP = GPtr->calculatedCatalogFCB; btcbP = (BTreeControlBlock*)fcbP->fcbBtree;
if( btcbP->refCon != (UInt32)nil )
{
if(((BTreeExtensionsRec*)btcbP->refCon)->BTCBMPtr != nil)
{
DisposeMemory(((BTreeExtensionsRec*)btcbP->refCon)->BTCBMPtr);
err = MemError();
}
DisposeMemory( (Ptr)btcbP->refCon );
err = MemError();
btcbP->refCon = (UInt32)nil;
}
}
}
DisposeMemory( GPtr->calculatedVCB ); err = MemError();
GPtr->calculatedVCB = nil;
return( noErr );
}
#define BLUE_BOX_SHARED_DRVR_NAME "\p.BlueBoxShared"
#define BLUE_BOX_FLOPPY_WHERE_STRING "\pdisk%d (Shared)"
#define SONY_DRVR_NAME "\p.Sony"
struct IconAndStringRec {
char icon[ 256 ];
Str255 string;
};
typedef struct IconAndStringRec IconAndStringRec, * IconAndStringRecPtr;
Boolean IsBlueBoxSharedDrive ( DrvQElPtr dqPtr )
{
#if 0
Str255 blueBoxSharedDriverName = BLUE_BOX_SHARED_DRVR_NAME;
Str255 blueBoxFloppyWhereString = BLUE_BOX_FLOPPY_WHERE_STRING;
Str255 sonyDriverName = SONY_DRVR_NAME;
DCtlHandle driverDCtlHandle;
DCtlPtr driverDCtlPtr;
DRVRHeaderPtr drvrHeaderPtr;
StringPtr driverName;
if ( dqPtr == NULL )
return false;
driverDCtlHandle = GetDCtlEntry(dqPtr->dQRefNum);
driverDCtlPtr = *driverDCtlHandle;
if((((driverDCtlPtr->dCtlFlags) & Is_Native_Mask) == 0) && (driverDCtlPtr->dCtlDriver != nil))
{
if (((driverDCtlPtr->dCtlFlags) & Is_Ram_Based_Mask) == 0)
{
drvrHeaderPtr = (DRVRHeaderPtr)driverDCtlPtr->dCtlDriver;
}
else
{
HLock((Handle)(driverDCtlPtr)->dCtlDriver);
drvrHeaderPtr = (DRVRHeaderPtr)*((Handle)(driverDCtlPtr->dCtlDriver));
}
driverName = (StringPtr)&(drvrHeaderPtr->drvrName);
if (!(IdenticalString(driverName,blueBoxSharedDriverName,nil)))
{
return( true );
}
if (!(IdenticalString(driverName,sonyDriverName,nil)))
{
CntrlParam paramBlock;
paramBlock.ioCompletion = nil;
paramBlock.ioNamePtr = nil;
paramBlock.ioVRefNum = dqPtr->dQDrive;
paramBlock.ioCRefNum = dqPtr->dQRefNum;
paramBlock.csCode = kDriveIcon;
if ( noErr == PBControlSync( (ParmBlkPtr) ¶mBlock ) )
{
IconAndStringRecPtr iconAndStringRecPtr;
StringPtr whereStringPtr;
iconAndStringRecPtr = * (IconAndStringRecPtr*) & paramBlock.csParam;
whereStringPtr = (StringPtr) & iconAndStringRecPtr->string;
if (!(IdenticalString(whereStringPtr,blueBoxFloppyWhereString,nil)))
{
return( true );
}
}
}
}
#endif
return false;
}
static
void printVerifyStatus(SGlobPtr GPtr)
{
UInt32 stat;
stat = GPtr->VIStat | GPtr->ABTStat | GPtr->EBTStat | GPtr->CBTStat | GPtr->CatStat;
if ( stat != 0 ) {
plog(" Verify Status: VIStat = 0x%04x, ABTStat = 0x%04x EBTStat = 0x%04x\n",
GPtr->VIStat, GPtr->ABTStat, GPtr->EBTStat);
plog(" CBTStat = 0x%04x CatStat = 0x%08x\n",
GPtr->CBTStat, GPtr->CatStat);
}
}