Exemple #1
0
static void *GetSectionBaseAddress(const FragToFixInfo *fragToFix, UInt16 sectionIndex)
	// This routine returns the base of the instantiated section
	// whose index is sectionIndex.  This routine is the evil twin
	// of SetupSectionBaseAddresses.  It simply returns the values
	// for section 0 and 1 that we derived in SetupSectionBaseAddresses.
	// In a real implementation, this routine would call CFM API
	// to get this information, and SetupSectionBaseAddresses would
	// not exist, but CFM does not export the necessary APIs to
	// third parties.
{
	void *result;
	
	MoreAssertQ(fragToFix != nil);
	MoreAssertQ(fragToFix->containerHeader.tag1 == kPEFTag1);
	
	switch (sectionIndex) {
		case 0:
			result = fragToFix->section0Base;
			break;
		case 1:
			result = fragToFix->section1Base;
			break;
		default:
			result = nil;
			break;
	}
	return result;
}
Exemple #2
0
pascal void MoreAEDisposeDesc(AEDesc *desc){
	OSStatus junk;

	MoreAssertQ(desc != nil);

	junk = AEDisposeDesc(desc);
	MoreAssertQ(junk == noErr);

	MoreAENullDesc(desc);
}
extern pascal DriveFlagsPtr MoreGetDriveFlags(DrvQElPtr drvQEl)
	// See comment in interface part.
{
	MoreAssertQ(drvQEl != nil);

	return ((DriveFlagsPtr) drvQEl) - 1;
}
static pascal Boolean MoreDriveSupportFileExchangeInternal(DriverRefNum refNum, SInt16 drive)
	// An internal version of MoreDriveSupportFileExchange that allows
	// you to pass in the refNum and the drive number.  You can pass
	// in 0 for either refNum or drive (but not both) and the routine
	// will do the appropriate mapping.
{
    DriverGestaltParam pb;
    Boolean result;

    MoreAssertQ( (refNum < 0 && drive >= 0 && (drive == 0 || MoreGetDriveRefNum(drive) == refNum)) ||
    			 (refNum == 0 && drive > 0) );
    
    if (refNum == 0) {
    	refNum = MoreGetDriveRefNum(drive);
    }
    
    result = false;
    if ( MoreDriveSupportsDriverGestaltInternal(refNum) ) {
        pb.ioVRefNum = drive;
        pb.ioCRefNum = refNum;
        pb.csCode = kDriverGestaltCode;
        pb.driverGestaltSelector = kdgAPI;

        if ( PBStatusSync((ParmBlkPtr) &pb) == noErr 
                && GetDriverGestaltAPIResponse(&pb)->partitionCmds & 0x01 ) {
            result = true;
        }
    }
    return result;
}
Exemple #5
0
//*******************************************************************************
// Initialises desc to the null descriptor (typeNull, nil).
pascal void MoreAENullDesc(AEDesc* desc)
{
	MoreAssertQ(desc != nil);

	desc->descriptorType = typeNull;
	desc->dataHandle     = nil;
}//end MoreAENullDesc
Exemple #6
0
/******************************************************************************
	Returns the name of the process specified by ProcessSerialNumberPtr.
	
	The string pointed to by pProcessName will be untouched if the process
	can't be found. 

	pPSN			input:	The process whose name you want (nil for current).
	pProcessName	input:	Pointer to a Str31 for the process name.
					output:	The process name.
	
	RESULT CODES
	____________
	noErr			   0	No error
	paramErr		 �	Process serial number is invalid
	____________
*/
pascal	OSStatus	MoreProcGetProcessName(
								const ProcessSerialNumberPtr pPSN,
								StringPtr pProcessName)
{
	OSStatus		anErr = noErr;	
	ProcessInfoRec	infoRec;
	ProcessSerialNumber localPSN;

	MoreAssertQ(pProcessName != nil);
		
	infoRec.processInfoLength = sizeof(ProcessInfoRec);
	infoRec.processName = pProcessName;
#ifndef __LP64__
	infoRec.processAppSpec = nil;
#endif
	
	if ( pPSN == nil ) {
		localPSN.highLongOfPSN = 0;
		localPSN.lowLongOfPSN  = kCurrentProcess;
	} else {
		localPSN = *pPSN;
	}
	
	anErr = GetProcessInformation(&localPSN, &infoRec);
	
	return anErr;
}//end MoreProcGetProcessName
extern pascal OSErr MoreUTFindDriveQ(SInt16 drive, DrvQElPtr *foundDrvQEl)
	// See comment in interface part.
{
	OSErr err;
	UInt32 fsmVers;

	MoreAssertQ(drive > 0);
	MoreAssertQ(foundDrvQEl != nil);
	
	// Check to see whether we have a useful version of FSM.  Versions of FSM
	// prior to 1.2 do not support the documented FSM API, so we just treat
	// them as if FSM wasn't installed.
	
	if ((Gestalt(gestaltFSMVersion, (SInt32 *) &fsmVers) == noErr) && (fsmVers >= 0x0120)) {

		// We have FSM, let's call its version of UTFindDrive,
		// and handle the weirdo error we get for non-HFS disks.

		err = MoreUTFindDrive(drive, foundDrvQEl);
		if (err == extFSErr) {
			err = noErr;
		}
	} else {
		DrvQElPtr thisDrv;
	
		// No FSM, let's go poking around in low memory )-:
		
		*foundDrvQEl = nil;

		thisDrv = (DrvQElPtr) GetDrvQHdr()->qHead;
		while (thisDrv != nil && *foundDrvQEl == nil) {
			if (thisDrv->dQDrive == drive) {
				*foundDrvQEl = thisDrv;
			} else {
				thisDrv = (DrvQElPtr) thisDrv->qLink;
			}
		}
		if (*foundDrvQEl == nil) {
			err = nsDrvErr;
		} else {
			err = noErr;
		}
	}
	
	return err;
}
Exemple #8
0
static OSStatus FindImportLibrary(PEFLoaderInfoHeader *loaderSection, const char *libraryName, PEFImportedLibrary **importLibrary)
	// This routine finds the import library description (PEFImportedLibrary)
	// for the import library libraryName in the PEF loader section.
	// It sets *importLibrary to the address of the description.
{
	OSStatus 			err;
	UInt32 				librariesRemaining;
	PEFImportedLibrary 	*thisImportLibrary;
	Boolean 			found;
	
	MoreAssertQ(loaderSection != nil);
	MoreAssertQ(libraryName != nil);
	MoreAssertQ(importLibrary != nil);
	
	// Loop through each import library looking for a matching name.
	
	// Initialise thisImportLibrary to point to the byte after the
	// end of the loader section's header.
	
	thisImportLibrary = (PEFImportedLibrary *) (loaderSection + 1);
	librariesRemaining = loaderSection->importedLibraryCount;
	found = false;
	while ( librariesRemaining > 0 && ! found ) {
		// PEF defines that import library names will have
		// a null terminator, so we can just use strcmp.
		found = (strcmp( libraryName,
						((char *)loaderSection)
						+ loaderSection->loaderStringsOffset 
						+ thisImportLibrary->nameOffset) == 0);
		// *** Remove ANSI strcmp eventually.
		if ( ! found ) {
			thisImportLibrary += 1;
			librariesRemaining -= 1;
		}
	}
	
	if (found) {
		*importLibrary = thisImportLibrary;
		err = noErr;
	} else {
		*importLibrary = nil;
		err = cfragNoLibraryErr;
	}
	return err;
}
extern pascal SInt16 MoreFindFreeDriveNumber(SInt16 firstDrive)
	// See comment in interface part.
{
	SInt16 candidate;
	DrvQElPtr junkDrvQElPtr;
	
	MoreAssertQ(firstDrive >= 5);
	
	candidate = firstDrive;
	while ( MoreUTFindDriveQ(candidate, &junkDrvQElPtr) == noErr ) {
		candidate += 1;
	}
	
	// This post condition checks that we didn't wrap
	// around to a negative drive number.

	MoreAssertQ(candidate >= 5);

	return candidate;
}
Exemple #10
0
static UInt32 DecodeInstrCountValue(const UInt8 *inOpStart, UInt32 *outCount)
	// Given a pointer to the start of an opcode (inOpStart), work out the 
	// count argument for that opcode (*outCount).  Returns the number of 
	// bytes consumed by the opcode and count combination.
{
	MoreAssertQ(inOpStart != nil);
	MoreAssertQ(outCount  != nil);
	
	if (PEFPkDataCount5(*inOpStart) != 0)
	{
		// Simple case, count encoded in opcode.
		*outCount = PEFPkDataCount5(*inOpStart);
		return 1;
	}
	else
	{
		// Variable-length case.
		return 1 + DecodeVCountValue(inOpStart + 1, outCount);
	}
}
Exemple #11
0
static pascal Boolean MoreDriveSupportsDriverGestaltInternal(DriverRefNum refNum)
	// An internal version of MoreDriveSupportsDriverGestalt that allows
	// you to pass in the refNum and the drive number.  You can pass
	// in 0 for either refNum or drive (but not both) and the routine
	// will do the appropriate mapping.
{
    OSErr junk;
    DriverFlags driverFlags;
    
    junk = TradGetDriverInformation(refNum, nil, &driverFlags, nil, nil);
    MoreAssertQ(junk == noErr);
    return TradDriverGestaltIsOn(driverFlags);
}
Exemple #12
0
extern pascal DriverRefNum MoreGetDriveRefNum(SInt16 drive)
	// See comment in interface part.
{
	DrvQElPtr foundDrvQEl;

	MoreAssertQ(drive > 0);
	
	if ( MoreUTFindDriveQ(drive, &foundDrvQEl) == noErr) {
		return foundDrvQEl->dQRefNum;
	} else {
		return 0;
	}
}
Exemple #13
0
extern pascal DrvQElPtr MoreGetIndDrive(SInt16 index)
	// See comment in interface part.
{
	DrvQElPtr thisDrv;
	SInt16    thisDrvIndex;

	MoreAssertQ(index > 0);
	
	thisDrvIndex = 1;
	thisDrv = (DrvQElPtr) GetDrvQHdr()->qHead;
	while (thisDrv != nil && thisDrvIndex != index) {
		thisDrvIndex += 1;
		thisDrv = (DrvQElPtr) thisDrv->qLink;
	}
	return thisDrv;
}
Exemple #14
0
extern pascal Boolean MoreProcIsProcessAtFront(const ProcessSerialNumber *pPSN)
	// See comment in header.
{	
	OSStatus 			anErr;
	ProcessSerialNumber localPSN;
	ProcessSerialNumber frontPSN;
	Boolean  			isSame;
	
	if ( pPSN == nil ) {
		localPSN.highLongOfPSN = 0;
		localPSN.lowLongOfPSN  = kCurrentProcess;
	} else {
		localPSN = *pPSN;
	}
	
	anErr = GetFrontProcess(&frontPSN);
	if (noErr == anErr) {
		anErr = SameProcess(&localPSN, &frontPSN, &isSame);
	}
	MoreAssertQ(noErr == anErr);			// If either of the previous return an error, we want to know why.
	return (noErr == anErr) && isSame;
}
Exemple #15
0
static OSStatus ReadContainerBasics(FragToFixInfo *fragToFix)
	// Reads some basic information from the container of the
	// fragment to fix and stores it in various fields of
	// fragToFix.  This includes:
	//
	// o containerHeader -- The contain header itself.
	// o sectionHeaders  -- The array of section headers (in a newly allocated pointer block).
	// o loaderSection   -- The entire loader section (in a newly allocated pointer block).
	//
	// Also sets disposeSectionPointers to indicate whether
	// the last two pointers should be disposed of.
	//
	// Finally, it leaves the container file open for later
	// folks who want to read data from it.
{
	OSStatus 	err;
	UInt16 		sectionIndex;
	Boolean 	found;

	MoreAssertQ(fragToFix != nil);
	MoreAssertQ(fragToFix->locator.fileSpec != nil);
	MoreAssertQ(fragToFix->connID != nil);
	MoreAssertQ(fragToFix->loaderSection == nil);
	MoreAssertQ(fragToFix->sectionHeaders == nil);
	MoreAssertQ(fragToFix->fileRef == 0);
	
	fragToFix->disposeSectionPointers = true;
	
	// Open up the file, read the container head, then read in
	// all the section headers, then go looking through the
	// section headers for the loader section (PEF defines
	// that there can be only one).
	
	err = FSpOpenDF(fragToFix->locator.fileSpec, fsRdPerm, &fragToFix->fileRef);
	if (err == noErr) {
		err = FSReadAtOffset(fragToFix->fileRef,
								fragToFix->locator.offset,
								sizeof(fragToFix->containerHeader),
								&fragToFix->containerHeader);
		if (err == noErr) {
			if (   fragToFix->containerHeader.tag1 != kPEFTag1
				|| fragToFix->containerHeader.tag2 != kPEFTag2
				|| fragToFix->containerHeader.architecture != kCompiledCFragArch
				|| fragToFix->containerHeader.formatVersion != kPEFVersion) {
				err = cfragFragmentFormatErr;
			}
		}
		if (err == noErr) {
			fragToFix->sectionHeaders = (PEFSectionHeader *) NewPtr(fragToFix->containerHeader.sectionCount * sizeof(PEFSectionHeader));
			err = MemError();
		}
		if (err == noErr) {
			err = FSReadAtOffset(fragToFix->fileRef,
									fragToFix->locator.offset + sizeof(fragToFix->containerHeader),
									fragToFix->containerHeader.sectionCount * sizeof(PEFSectionHeader), 
									fragToFix->sectionHeaders);
		}
		if (err == noErr) {
			sectionIndex = 0;
			found = false;
			while ( sectionIndex < fragToFix->containerHeader.sectionCount && ! found ) {
				found = (fragToFix->sectionHeaders[sectionIndex].sectionKind == kPEFLoaderSection);
				if ( ! found ) {
					sectionIndex += 1;
				}
			}
		}
		if (err == noErr && ! found) {
			err = cfragNoSectionErr;
		}
		
		// Now read allocate a pointer block and read the loader section into it.
		
		if (err == noErr) {
			fragToFix->loaderSection = (PEFLoaderInfoHeader *) NewPtr(fragToFix->sectionHeaders[sectionIndex].containerLength);
			err = MemError();
		}
		if (err == noErr) {
			err = FSReadAtOffset(fragToFix->fileRef, 
									fragToFix->locator.offset + fragToFix->sectionHeaders[sectionIndex].containerOffset,
									fragToFix->sectionHeaders[sectionIndex].containerLength, 
									fragToFix->loaderSection);
		}				
	}
	
	// No clean up.  The client must init fragToFix to zeros and then
	// clean up regardless of whether we return an error.
		
	return err;
}
Exemple #16
0
static OSStatus UnpackPEFDataSection(const UInt8 * const packedData,   UInt32 packedSize,
								           UInt8 * const unpackedData, UInt32 unpackedSize)
{
	OSErr			err;
	UInt32			offset;
	UInt8			opCode;
	UInt8 *			unpackCursor;
	
	MoreAssertQ(packedData != nil);
	MoreAssertQ(unpackedData != nil);
	MoreAssertQ(unpackedSize >= packedSize);

	// The following asserts assume that the client allocated the memory with NewPtr, 
	// which may not always be true.  However, the asserts' value in preventing accidental 
	// memory block overruns outweighs the possible maintenance effort.
	
	MoreAssertQ( packedSize   == GetPtrSize( (Ptr) packedData  ) );
	MoreAssertQ( unpackedSize == GetPtrSize( (Ptr) unpackedData) );
	
	err          = noErr;
	offset       = 0;
	unpackCursor = unpackedData;
	while (offset < packedSize) {
		MoreAssertQ(unpackCursor < &unpackedData[unpackedSize]);
		
		opCode = packedData[offset];
		
		switch (PEFPkDataOpcode(opCode)) {
			case kPEFPkDataZero:
				{
					UInt32	count;
					
					offset += DecodeInstrCountValue(&packedData[offset], &count);
					
					MoreBlockZero(unpackCursor, count);
					unpackCursor += count;
				}
				break;
			
			case kPEFPkDataBlock:
				{
					UInt32	blockSize;
					
					offset += DecodeInstrCountValue(&packedData[offset], &blockSize);
					
					BlockMoveData(&packedData[offset], unpackCursor, blockSize);
					unpackCursor += blockSize;
					offset += blockSize;
				}
				break;
			
			case kPEFPkDataRepeat:
				{
					UInt32	blockSize;
					UInt32	repeatCount;
					UInt32  loopCounter;
					
					offset += DecodeInstrCountValue(&packedData[offset], &blockSize);
					offset += DecodeVCountValue(&packedData[offset], &repeatCount);
					repeatCount += 1;	// stored value is (repeatCount - 1)
					
					for (loopCounter = 0; loopCounter < repeatCount; loopCounter++) {
						BlockMoveData(&packedData[offset], unpackCursor, blockSize);
						unpackCursor += blockSize;
					}
					offset += blockSize;
				}
				break;
			
			case kPEFPkDataRepeatBlock:
				{
					UInt32	commonSize;
					UInt32	customSize;
					UInt32	repeatCount;
					const UInt8 *commonData;
					const UInt8 *customData;
					UInt32 loopCounter;
					
					offset += DecodeInstrCountValue(&packedData[offset], &commonSize);
					offset += DecodeVCountValue(&packedData[offset], &customSize);
					offset += DecodeVCountValue(&packedData[offset], &repeatCount);
					
					commonData = &packedData[offset];
					customData = &packedData[offset + commonSize];
					
					for (loopCounter = 0; loopCounter < repeatCount; loopCounter++) {
						BlockMoveData(commonData, unpackCursor, commonSize);
						unpackCursor += commonSize;
						BlockMoveData(customData, unpackCursor, customSize);
						unpackCursor += customSize;
						customData += customSize;
					}
					BlockMoveData(commonData, unpackCursor, commonSize);
					unpackCursor += commonSize;
					offset += (repeatCount * (commonSize + customSize)) + commonSize;
				}
				break;
			
			case kPEFPkDataRepeatZero:
				{
					UInt32	commonSize;
					UInt32	customSize;
					UInt32	repeatCount;
					const UInt8 *customData;
					UInt32 loopCounter;
					
					offset += DecodeInstrCountValue(&packedData[offset], &commonSize);
					offset += DecodeVCountValue(&packedData[offset], &customSize);
					offset += DecodeVCountValue(&packedData[offset], &repeatCount);
					
					customData = &packedData[offset];
					
					for (loopCounter = 0; loopCounter < repeatCount; loopCounter++) {
						MoreBlockZero(unpackCursor, commonSize);
						unpackCursor += commonSize;
						BlockMoveData(customData, unpackCursor, customSize);
						unpackCursor += customSize;
						customData += customSize;
					}
					MoreBlockZero(unpackCursor, commonSize);
					unpackCursor += commonSize;
					offset += repeatCount * customSize;
				}
				break;
			
			default:
				#if MORE_DEBUG
					DebugStr("\pUnpackPEFDataSection: Unexpected data opcode");
				#endif
				err = cfragFragmentCorruptErr;
				goto leaveNow;
				break;
		}
	}
	
leaveNow:
	return err;
}
Exemple #17
0
static OSStatus SetupSectionBaseAddresses(FragToFixInfo *fragToFix)
	// This routine initialises the section0Base and section1Base
	// base fields of fragToFix to the base addresses of the
	// instantiated fragment represented by the other fields
	// of fragToFix.  The process works in three states:
	//
	// 1. 	Find the contents of the relocated TVector of the 
	//      fragment's initialisation routine, provided to us by 
	//      the caller.
	//
	// 2.	Find the contents of the non-relocated TVector by 
	//      looking it up in the PEF loader info header and then 
	//      using that to read the TVector contents from disk.
	//      This yields the offsets from the section bases for 
	//      the init routine.
	//
	// 3.	Subtract 2 from 3.
{
	OSStatus 			err;
	TVector *			relocatedExport;
	SInt32				initSection;
	UInt32				initOffset;
	PEFSectionHeader *	initSectionHeader;
	Ptr					packedDataSection;
	Ptr					unpackedDataSection;
	TVector 			originalOffsets;

	packedDataSection   = nil;
	unpackedDataSection = nil;
	
	// Step 1.

	// First find the init routine's TVector, which gives us the relocated 
	// offsets of the init routine into the data and code sections.

	relocatedExport = (TVector *) fragToFix->initRoutine;
		
	// Step 2.
	
	// Now find the init routine's TVector's offsets in the data section on 
	// disk.  This gives us the raw offsets from the data and code section 
	// of the beginning of the init routine.
	
	err = noErr;
	initSection = fragToFix->loaderSection->initSection;
	initOffset  = fragToFix->loaderSection->initOffset;
	if (initSection == -1) {
		err = cfragFragmentUsageErr;
	}
	if (err == noErr) {
		MoreAssertQ( initSection >= 0 );		// Negative indexes are pseudo-sections which are just not allowed!
		MoreAssertQ( initSection < fragToFix->containerHeader.sectionCount );

		initSectionHeader = &fragToFix->sectionHeaders[initSection];
		
		// If the data section is packed, unpack it to a temporary buffer and then get the 
		// original offsets from that buffer.  If the data section is unpacked, just read 
		// the original offsets directly off the disk.
		
		if ( initSectionHeader->sectionKind == kPEFPackedDataSection ) {

			// Allocate space for packed and unpacked copies of the section.
			
			packedDataSection = NewPtr(initSectionHeader->containerLength);
			err = MemError();

			if (err == noErr) {
				unpackedDataSection = NewPtr(initSectionHeader->unpackedLength);
				err = MemError();
			}

			// Read the contents of the packed section.
			
			if (err == noErr) {
				err = FSReadAtOffset(	fragToFix->fileRef,
										fragToFix->locator.offset
										+ initSectionHeader->containerOffset,
										initSectionHeader->containerLength,
										packedDataSection);
			}
			
			// Unpack the data into the unpacked section.
			
			if (err == noErr) {
				err = UnpackPEFDataSection( (UInt8 *) packedDataSection,   initSectionHeader->containerLength,
								            (UInt8 *) unpackedDataSection, initSectionHeader->unpackedLength);
			}
			
			// Extract the init routine's TVector from the unpacked section.
			
			if (err == noErr) {
				BlockMoveData(unpackedDataSection + initOffset, &originalOffsets, sizeof(TVector));
			}
			
		} else {
			MoreAssertQ(fragToFix->sectionHeaders[initSection].sectionKind == kPEFUnpackedDataSection);
			err = FSReadAtOffset(fragToFix->fileRef, 
									fragToFix->locator.offset
									+ fragToFix->sectionHeaders[initSection].containerOffset
									+ initOffset,
									sizeof(TVector), 
									&originalOffsets);
		}
	}

	// Step 3.
		
	// Do the maths to subtract the unrelocated offsets from the current address 
	// to get the base address.
	
	if (err == noErr) {
		fragToFix->section0Base = ((char *) relocatedExport->codePtr) - (UInt32) originalOffsets.codePtr;
		fragToFix->section1Base = ((char *) relocatedExport->tocPtr)  - (UInt32) originalOffsets.tocPtr;
	}
	
	// Clean up.
	
	if (packedDataSection != nil) {
		DisposePtr(packedDataSection);
		MoreAssertQ( MemError() == noErr );
	}
	if (unpackedDataSection != nil) {
		DisposePtr(unpackedDataSection);
		MoreAssertQ( MemError() == noErr );
	}
	return err;
}
Exemple #18
0
extern pascal OSErr MoreGetDriveSize(SInt16 drive, UInt32 *sizeInBlocks)
	// See comment in interface part.
{
	OSErr err;
	DrvQElPtr drvQEl;
	CntrlParam pb;
	FormatListRec formatList[kFormatListEntryCount];
	SInt16 formatIndex;
	Boolean foundFormat;
	Str255 driverName;
    DrvSts status;
	
    MoreAssertQ(drive > 0);
    MoreAssertQ(sizeInBlocks != nil);

	// Start by finding the drive queue element for
	// the drive, and by making sure that there's a disk
	// in the drive.
	
	err = MoreUTFindDriveQ(drive, &drvQEl);
	if (err == noErr) {
		if ( MoreGetDriveFlags(drvQEl)->diskInPlace <= 0 ) {
			err = offLinErr;
		}
	}

	// Wow, this is harder than it should be, all because of the
	// silly ".Sony" driver.  The basic problem is that
	// the ".Sony" driver doesn't store the disk size in the
	// drive queue element like every other disk drive on the
	// planet.  The solution is a three step process as described
	// in the comments below.
	
	if (err == noErr) {

		// Step 1.  If the driver supports the kReturnFormatList status call,
		//	  		use it to get a list of formats for the drive and then
		//			return the format marked as current.

		pb.ioNamePtr = nil;
		pb.ioVRefNum = drvQEl->dQDrive;
		pb.ioCRefNum = drvQEl->dQRefNum;
		pb.csCode = kReturnFormatList;
		pb.csParam[0] = kFormatListEntryCount;
		*((FormatListRec **) &pb.csParam[1]) = formatList;
		err = PBStatusSync( (ParmBlkPtr) &pb);
		if (err == noErr) {
			foundFormat = false;
			for (formatIndex = 0; formatIndex < pb.csParam[0]; formatIndex++) {
				if ((formatList[formatIndex].formatFlags & diCIFmtFlagsCurrentMask) != 0) {
					*sizeInBlocks = formatList[formatIndex].volSize;
					foundFormat = true;
				}
			}
			if ( ! foundFormat ) {

				// Hmmm, this isn't good.  The disk driver returned a format
				// list but none of the formats were marked as "current".
				// We handle this correctly but, in debug builds, we'll also
				// drop into MacsBug, just to let you know this is happening.

				MoreAssertQ(false);
				err = paramErr;
			}
		} else {
		
			// ¥¥¥ The logic here is slightly screwed up.  The problem is that
			// I can't tell whether the kReturnFormatList call failed because
			// the driver just doesn't support it, or because the driver failed
			// to get the information for some other reason.  If that driver
			// happens to be the ".Sony" driver, I'm going to take a wrong step
			// next.
			//
			// For example, say that there's a 1.4MB disk in the floppy drive
			// and I call kReturnFormatList and it fails with an error because
			// of a cosmic ray.  I then test the driver name, find that it's
			// ".Sony", call DriveStatus, and then return noErr with a size
			// of either 400KB or 800KB.  Not good.
			// 
			// You might think this is an unlikely occurence, but it's exactly
			// what happens when there's no disk in the floppy drive.  I've
			// special-cased that away above, but the general problem still stands.
			// 
			// What are the alternatives?  I could special case the error
			// result from kReturnFormatList and only run this code if I get
			// statusErr.  But can you guarantee that all ".Sony" drives
			// return statusErr for an unrecognised status code?  I thought not.
			// Beyond that, I can't think of any options.  So this code
			// stands.  It's probably never going to bite anyone, but it's
			// worth noting here, just in case.  Besides, this is what
			// the equivalent routine in MoreFiles does (-:
			//
			// -- Quinn, 3 Mar 1999

			// Step 2.	If that doesn't work, then look at the driver.  If it's
			//    		the ".Sony" driver (and this will be a really old ".Sony" driver
			//    		because new ones support kReturnFormatList), special case
			//    		the possible media types.

			err = TradGetDriverInformation(drvQEl->dQRefNum, nil, nil, driverName, nil);
			if (err == noErr) {
				if ( EqualString(driverName, "\p.Sony", false, true) ) {
					err = DriveStatus(drvQEl->dQDrive, &status);
					if (err == noErr) {
						if ( status.twoSideFmt == 0 ) {
							*sizeInBlocks = 400 * 2;
						} else {
							*sizeInBlocks = 800 * 2;
						}
					}
				} else {

					// Step 3.	If it's not the ".Sony" driver, get the size out of the
					//    		drive queue element.

					if (drvQEl->qType == 0) {

						// Old style drive, with just 16 bits of size information
						// in dQDrvSz.

						*sizeInBlocks = drvQEl->dQDrvSz;
					} else {
					
						// New style drive, with 32 bits of size information spread
						// between dQDrvSz and dQDrvSz2.
						
						*sizeInBlocks = (((UInt32 ) drvQEl->dQDrvSz2) * 65536) + (UInt32 ) drvQEl->dQDrvSz;
					}
				}
			}
Exemple #19
0
extern pascal Boolean MoreDriveSupportFileExchange(SInt16 drive)
	// See comment in interface part.
{
    MoreAssertQ(drive > 0);
	return MoreDriveSupportFileExchangeInternal(0, drive);
}
Exemple #20
0
static OSStatus LookupSymbol(CFMLateImportLookupProc lookup, void *refCon,
							PEFLoaderInfoHeader *loaderSection,
							UInt32 symbolIndex,
							UInt32 *symbolValue)
	// This routine is used to look up a symbol during relocation.
	// "lookup" is a client callback and refCon is its argument.
	// Typically refCon is the CFM connection to the library that is
	// substituting for the weak linked library.  loaderSection
	// is a pointer to the loader section of the fragment to fix up.
	// symbolIndex is the index of the imported symbol in the loader section.
	// The routine sets the word pointed to by symbolValue to the
	// value of the symbol.
	//
	// The routine works by using symbolIndex to index into the imported
	// symbol table to find the offset of the symbol's name in the string
	// table.  It then looks up the symbol by calling the client's "lookup"
	// function and passes the resulting symbol address back in symbolValue.
{
	OSStatus 			err;
	UInt32 				*importSymbolTable;
	UInt32 				symbolStringOffset;
	Boolean 			symbolIsWeak;
	CFragSymbolClass 	symbolClass;
	char 				*symbolStringAddress;
	Str255 				symbolString;
	
	MoreAssertQ(lookup != nil);
	MoreAssertQ(loaderSection != nil);
	MoreAssertQ(symbolIndex < loaderSection->totalImportedSymbolCount);
	MoreAssertQ(symbolValue != nil);
	
	// Find the base of the imported symbol table.
	
	importSymbolTable = (UInt32 *)(((char *)(loaderSection + 1)) + (loaderSection->importedLibraryCount * sizeof(PEFImportedLibrary)));
	
	// Grab the appropriate entry out of the table and
	// extract the information from that entry.
	
	symbolStringOffset = importSymbolTable[symbolIndex];
	symbolClass = PEFImportedSymbolClass(symbolStringOffset);
	symbolIsWeak = ((symbolClass & kPEFWeakImportSymMask) != 0);
	symbolClass = symbolClass & ~kPEFWeakImportSymMask;
	symbolStringOffset = PEFImportedSymbolNameOffset(symbolStringOffset);
	
	// Find the string for the symbol in the strings table and
	// extract it from the table into a Pascal string on the stack.
	
	symbolStringAddress = ((char *)loaderSection) + loaderSection->loaderStringsOffset + symbolStringOffset;
	symbolString[0] = strlen(symbolStringAddress);		// *** remove ANSI strlen
	BlockMoveData(symbolStringAddress, &symbolString[1], symbolString[0]);
	
	// Look up the symbol in substitute library.  If it fails, return
	// a 0 value and check whether the error is fatal (a strong linked
	// symbol) or benign (a weak linked symbol).
	
	err = lookup(symbolString, symbolClass, (void **) symbolValue, refCon);
	if (err != noErr) {
		*symbolValue = 0;
		if (symbolIsWeak) {
			err = noErr;
		}
	}
	return err;
}