#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)
printf("(%d %%)\n", progress);
fflush(stdout);
return 0;
}
extern void printIOstats(void);
int
CheckHFS(int fsReadRef, int fsWriteRef, int checkLevel, int repairLevel, int logLevel, int guiControl, int *modified)
{
SGlob dataArea; short temp;
FileIdentifierTable *fileIdentifierTable = nil;
OSErr err = noErr;
OSErr scavError = 0;
OSErr unmountResult = nsvErr;
int didRebuild = 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.DrvNum = fsReadRef;
if (guiControl) {
dataArea.guiControl = true;
dataArea.userCancelProc = cancelProc;
}
ScavCtrl( &dataArea, scavInitialize, &scavError );
dataArea.calculatedVCB->vcbDriveNumber = fsReadRef;
dataArea.calculatedVCB->vcbDriverWriteRef = fsWriteRef;
if (checkLevel == kNeverCheck || (checkLevel == kDirtyCheck && dataArea.cleanUnmount)) {
goto termScav;
}
if (CheckIfJournaled(&dataArea)
&& didRebuild == 0
&& checkLevel != kForceCheck
&& !(checkLevel == kPartialCheck && repairLevel == kForceRepairs)) {
printf("fsck_hfs: Volume is journaled. No checking performed.\n");
printf("fsck_hfs: Use the -f option to force checking.\n");
scavError = 0;
goto termScav;
}
if ( scavError == noErr )
ScavCtrl( &dataArea, scavVerify, &scavError );
if (scavError == noErr && logLevel >= kDebugLog)
printVerifyStatus(&dataArea);
if (scavError == noErr && !dataArea.cleanUnmount && fsWriteRef != -1)
CheckForClean(&dataArea, true);
if ( dataArea.RepLevel == repairLevelUnrepairable )
err = cdUnrepairableErr;
if ( !autoRepair &&
(dataArea.RepLevel == repairLevelVolumeRecoverable ||
dataArea.RepLevel == repairLevelCatalogBtreeRebuild ||
dataArea.RepLevel == repairLevelUnrepairable) )
PrintStatus(&dataArea, M_NeedsRepair, 1, dataArea.volumeName);
if ( dataArea.volumeName[0] &&
dataArea.RepLevel == repairLevelNoProblemsFound )
PrintStatus(&dataArea, M_AllOK, 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) )
{
ScavCtrl( &dataArea, scavRepair, &scavError );
if ( scavError == noErr )
{
*modified = 1;
if ( dataArea.RepLevel == repairLevelCatalogBtreeRebuild && didRebuild++ == 0 )
{
ScavCtrl( &dataArea, scavTerminate, &temp );
repairLevel = kMajorRepairs;
checkLevel = kAlwaysCheck;
goto DoAgain;
}
}
}
else if ( (dataArea.RepLevel == repairLevelVeryMinorErrors) &&
(unmountResult != noErr) &&
(scavError == noErr) &&
(autoRepair) )
{
err = noErr;
}
else if ( (dataArea.RepLevel == repairLevelVolumeRecoverable) ||
(dataArea.RepLevel == repairLevelVeryMinorErrors) )
{
err = cdNeedsRepairsErr;
}
if ( (autoRepair == true) && (dataArea.fileIdentifierTable != nil) )
{
fileIdentifierTable = (FileIdentifierTable *) AllocateMemory( GetHandleSize( (Handle) dataArea.fileIdentifierTable ) );
CopyMemory( *(dataArea.fileIdentifierTable), fileIdentifierTable, GetHandleSize( (Handle) dataArea.fileIdentifierTable ) );
#if 0
if ( dataArea.realVCB != nil )
vRefNum = dataArea.realVCB->vcbVRefNum;
#endif
}
if ( fileIdentifierTable != nil )
{
#if 0
if ( mountErr != cdReMountErr )
{
StringHandle directoryNameH;
directoryNameH = GetString( rDamagedFilesDirSTRid );
if ( (directoryNameH != nil) && (*directoryNameH[0] != 0) )
{
HLock( (Handle) directoryNameH );
(void) CreateAliases( vRefNum, fileIdentifierTable, *directoryNameH );
HUnlock( (Handle) directoryNameH );
ReleaseResource( (Handle) directoryNameH );
}
}
#endif
DisposeMemory( fileIdentifierTable );
}
termScav:
err = scavError;
ScavCtrl( &dataArea, scavTerminate, &temp );
if (logLevel >= kDebugLog)
printIOstats();
return( err );
}
void ScavCtrl( SGlobPtr GPtr, UInt32 ScavOp, short *ScavRes )
{
OSErr result;
short 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: if ( result = ScavSetUp( GPtr ) ) break;
if ( IsBlueBoxSharedDrive( GPtr->DrvPtr ) )
break;
if ( result = CheckForStop( GPtr ) ) break;
if (GPtr->chkLevel == kNeverCheck || GPtr->chkLevel == kDirtyCheck) {
int clean;
clean = CheckForClean(GPtr, false);
if (clean == 1)
GPtr->cleanUnmount = true;
if (GPtr->chkLevel == kNeverCheck) {
if (clean == -1)
result = R_BadSig;
else if (clean == 0)
result = R_Dirty;
break;
}
if (GPtr->cleanUnmount)
break;
}
if (CheckIfJournaled(GPtr)
&& GPtr->chkLevel != kForceCheck
&& !(GPtr->chkLevel == kPartialCheck && GPtr->repairLevel == kForceRepairs)
&& !(GPtr->chkLevel == kAlwaysCheck && GPtr->repairLevel == kMajorRepairs)) {
break;
}
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 );
printf( "\n%s - BitMapCheck elapsed time \n", __FUNCTION__ );
printf( "########## 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 );
printf( "\n%s - create control blocks elapsed time \n", __FUNCTION__ );
printf( ">>>>>>>>>>>>> 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;
if ( ! IsWrapperVolume( GPtr->volumeType, GPtr->inputFlags ) )
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 );
printf( "\n%s - ExtBTChk elapsed time \n", __FUNCTION__ );
printf( ">>>>>>>>>>>>> secs %d msecs %d \n\n",
myElapsedTime.tv_sec, myElapsedTime.tv_usec );
#endif
if (result = CheckForStop(GPtr))
break;
GPtr->itemsProcessed += GPtr->onePercent;
if (result = ExtFlChk(GPtr))
break;
if (result = CheckForStop(GPtr))
break;
GPtr->itemsProcessed += GPtr->onePercent; GPtr->itemsProcessed += GPtr->onePercent;
if ( ! IsWrapperVolume( GPtr->volumeType, GPtr->inputFlags ) )
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 );
printf( "\n%s - CheckCatalogBTree elapsed time \n", __FUNCTION__ );
printf( ">>>>>>>>>>>>> secs %d msecs %d \n\n",
myElapsedTime.tv_sec, myElapsedTime.tv_usec );
#endif
if (result = CheckForStop(GPtr))
break;
if ( ! IsWrapperVolume( GPtr->volumeType, GPtr->inputFlags ) )
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 );
printf( "\n%s - CatHChk elapsed time \n", __FUNCTION__ );
printf( ">>>>>>>>>>>>> secs %d msecs %d \n\n",
myElapsedTime.tv_sec, myElapsedTime.tv_usec );
#endif
if (result = CheckForStop(GPtr))
break;
if (result = AttrBTChk(GPtr))
break;
if (result = CheckForStop(GPtr))
break;
if ( ! IsWrapperVolume( GPtr->volumeType, GPtr->inputFlags ) )
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 );
printf( "\n%s - CheckVolumeBitMap elapsed time \n", __FUNCTION__ );
printf( ">>>>>>>>>>>>> secs %d msecs %d \n\n",
myElapsedTime.tv_sec, myElapsedTime.tv_usec );
#endif
if (result = CheckForStop(GPtr))
break;
if ( ! IsWrapperVolume( GPtr->volumeType, GPtr->inputFlags ) )
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 );
printf( "\n%s - VInfoChk elapsed time \n", __FUNCTION__ );
printf( ">>>>>>>>>>>>> secs %d msecs %d \n\n",
myElapsedTime.tv_sec, myElapsedTime.tv_usec );
#endif
stat = GPtr->VIStat | GPtr->ABTStat | GPtr->EBTStat | GPtr->CBTStat |
GPtr->CatStat;
if ( stat != 0 )
{
if ( (GPtr->RepLevel == repairLevelNoProblemsFound) || (GPtr->RepLevel == repairLevelVolumeRecoverable) )
{
short minorErrors = (GPtr->CatStat & ~S_LockedDirName) |
GPtr->VIStat | GPtr->ABTStat | GPtr->EBTStat | GPtr->CBTStat;
if ( minorErrors == 0 )
GPtr->RepLevel = repairLevelVeryMinorErrors;
else
GPtr->RepLevel = repairLevelVolumeRecoverable;
}
}
else if ( GPtr->RepLevel == repairLevelNoProblemsFound )
{
#if 0
if ( GPtr->isHFSPlus == true )
{ if ( (GPtr->volumeFeatures & volumeIsMountedMask) && (GPtr->volumeFeatures & supportsHFSPlusVolsFeatureMask) )
GetDateTime( &(GPtr->realVCB->checkedDate) );
}
#endif
}
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 )
return( R_NoMem );
GPtr->calculatedVCB = vcb = &pointer->vcb;
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->validFilesList = (UInt32**)NewHandle( 0 );
if ( GPtr->validFilesList == nil )
return( R_NoMem );
return( noErr );
}
static int ScavTerm( SGlobPtr GPtr )
{
SFCB *fcbP;
BTreeControlBlock *btcbP;
RepairOrderPtr rP;
OSErr err;
(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 )
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)
{
UInt16 stat;
stat = GPtr->VIStat | GPtr->ABTStat | GPtr->EBTStat | GPtr->CBTStat | GPtr->CatStat;
if ( stat != 0 ) {
printf(" Verify Status: VIStat = 0x%04x, ABTStat = 0x%04x EBTStat = 0x%04x\n",
GPtr->VIStat, GPtr->ABTStat, GPtr->EBTStat);
printf(" CBTStat = 0x%04x CatStat = 0x%04x\n",
GPtr->CBTStat, GPtr->CatStat);
}
}