⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pgpmacbinary.c

📁 vc环境下的pgp源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*____________________________________________________________________________
	Copyright (C) 1997 Network Associates Inc. and affiliated companies.
	All rights reserved.

	$Id: pgpMacBinary.c,v 1.21 1999/03/10 02:52:58 heller Exp $
____________________________________________________________________________*/

#include "pgpConfig.h"
#include <string.h>

#include "pgpMem.h"
#include "pgpErrors.h"

#include "pgpIO.h"
#include "pgpLineEndIO.h"
#include "pgpIOUtilities.h"
#include "pgpFileUtilities.h"
#include "pgpMacBinary.h"
#include "pgpMacFileMapping.h"
#include "pgpStrings.h"

#include "pgpEndianConversion.h"



#define RawToUInt16( data )	PGPEndianToUInt16( kPGPBigEndian, data )
#define RawToUInt32( data )	PGPEndianToUInt32( kPGPBigEndian, data )

/*____________________________________________________________________________
	Convert the raw bytes of the header into an in-memory structure.  Fields
	in the structure use the approprite endian-ness.
	
	For example, the file type will be big-endian on a Mac and little-endian
	on a PC.
____________________________________________________________________________*/
	static void
sRawDataToHeader(
	PGPByte const *		rawData,
	MacBinaryHeader *	header
	)
{
	pgpClearMemory( header, sizeof( *header ) );
	
	header->oldVersion	= rawData[ kMacBinaryOffset_Version ];
	
	pgpCopyMemory( &rawData[ kMacBinaryOffset_NameLength ], header->name, 64 );
	
	header->info1.fdType	=
		RawToUInt32( &rawData[ kMacBinaryOffset_FileType ] );
		
	header->info1.fdCreator	=
		RawToUInt32( &rawData[ kMacBinaryOffset_FileCreator ] );
		
	header->info1.fdFlags	=
		RawToUInt16( &rawData[ kMacBinaryOffset_FinderFlags ] );
		
	header->info1.fdLocation.v	=
		RawToUInt16( &rawData[ kMacBinaryOffset_VPos ] );
		
	header->info1.fdLocation.h	=
		RawToUInt16( &rawData[ kMacBinaryOffset_HPos ] );
		
	header->info1.fdFldr	=
		RawToUInt16( &rawData[ kMacBinaryOffset_Folder ] );
	
	header->protectedBit	= rawData[ kMacBinaryOffset_ProtectedBit ];
	
	header->zero1		= rawData[ kMacBinaryOffset_Zero1 ];
	
	header->dLength		=
		RawToUInt32( &rawData[ kMacBinaryOffset_DataForkLength ] );
	
	header->rLength		=
		RawToUInt32( &rawData[ kMacBinaryOffset_ResForkLength ] );
	
	header->creationDate		=
		RawToUInt32( &rawData[ kMacBinaryOffset_CreationDate ] );
	
	header->modificationDate		=
		RawToUInt32( &rawData[ kMacBinaryOffset_ModificationDate ] );
	
	header->crc1		= rawData[ kMacBinaryOffset_crc1 ];
	header->crc2		= rawData[ kMacBinaryOffset_crc2 ];
}



	static PGPUInt16
sCalcCRC16Continue(
	PGPUInt16		crc,
	const void *	data,
	PGPInt32		len)
{
	const char *	dp	= (const char *)data;

	while(len--)
	{
		PGPInt16		i;
	
		crc ^= (PGPUInt16)(*dp++) << 8;
		for (i = 0; i < 8; ++i)
		{
			if (crc & 0x8000)
				crc = (crc << 1) ^ 0x1021;
			else
				crc <<= 1;
		}
	}
	return(crc);
}

	static PGPUInt16
sCalcCRC16(
	const void *data, PGPInt32 len)
{
	return sCalcCRC16Continue( 0, data, len);
}


/*____________________________________________________________________________
	Return TRUE if the raw header bytes are valid (CRC matches)
____________________________________________________________________________*/
	static PGPBoolean
sHeaderIsValid(
	const PGPByte *rawBytes )
{
	PGPUInt16	crc;
	PGPBoolean	isValid	= FALSE;
	
	/* CRCs don't include themselves */
	#define kLengthOfDataToCRC		( kPGPMacBinaryHeaderSize - (2+2) )
	crc	= sCalcCRC16( rawBytes, kLengthOfDataToCRC );
	
	isValid	= ( ( crc >> 8) == rawBytes[ kMacBinaryOffset_crc1 ] &&
		(crc & 0xFF) == rawBytes[ kMacBinaryOffset_crc2 ] );
	if ( ! isValid )
	{
		/* we can be more liberal, but our code always sets the CRC */
		/* so we may as well require that the CRC be valid */
	}
	
	return( isValid );
}


/*____________________________________________________________________________
	Read the header into a structure.  The struct
	produced is an in-memory representation; not necessarily the exact
	byte order on disk (primarily for big/little endian reasons, but also
	because different compilers on different platforms may pad structures
	differently).
____________________________________________________________________________*/
	static PGPError
sReadMacBinaryHeader(
	PFLFileSpecRef		spec,
	MacBinaryHeader *	header,
	PGPBoolean *		isValid
	)
{
	PGPError	err	= kPGPError_NoErr;
	PGPIORef	io;
	
	*isValid	= FALSE;
	
	err	= PGPOpenFileSpec( spec,
			kPFLFileOpenFlags_ReadOnly, (PGPFileIORef *)&io );
	if ( IsntPGPError( err ) )
	{
		PGPByte	buffer[ kPGPMacBinaryHeaderSize ];
		
		err	= PGPIORead( io, sizeof( buffer ), buffer, NULL );
		if ( IsntPGPError( err ) )
		{
			*isValid	= sHeaderIsValid( buffer );
			/* convert, even if not valid */
			sRawDataToHeader( buffer, header );
		}
		
		PGPFreeIO( io );
		io	= NULL;
	}
	
	return( err );
}



#if PGP_MACINTOSH	/* PGP_MACINTOSH [ */

#include <Script.h>

#include "pgpFileSpecMac.h"
#include "MacFiles.h"
#include "MacErrors.h"
#include "MacStrings.h"

/*____________________________________________________________________________
	Mac Version
	
	Create a file from the MacBinary original
____________________________________________________________________________*/
	static OSStatus
sCreateFromMacBinary(
	PGPMemoryMgrRef			memoryMgr,
	short					fileRef,
	MacBinaryHeader	const *	header,
	const FSSpec *			tempSpec )
{
	OSStatus	err;
	CInfoPBRec	cpb;
	
	err	= FSpCreate( tempSpec,
					header->info1.fdCreator, header->info1.fdType,
					smSystemScript );
	
	if ( IsntErr( err ) && header->dLength != 0 )
	{
		short	outRef;
		
		err	= FSpOpenDF( tempSpec, fsRdWrPerm, &outRef );
		if ( IsntErr( err ) )
		{
			err	= FSCopyBytes( memoryMgr, fileRef, kPGPMacBinaryHeaderSize,
					outRef, 0, header->dLength );
			
			FSClose( outRef );
		}
	}
	
	if ( IsntErr( err ) && header->rLength != 0 )
	{
		short	outRef;
		
		err	= FSpOpenRF( tempSpec, fsRdWrPerm, &outRef );
		if ( IsntErr( err ) )
		{
			err	= FSCopyBytes( memoryMgr, fileRef,
					kPGPMacBinaryHeaderSize + header->dLength,
					outRef, 0, header->rLength );
			
			FSClose( outRef );
		}
	}
	
	/* set file meta information */
	if ( IsntErr( err ) )
	{
		err	= FSpGetCatInfo( tempSpec, &cpb );
		if ( IsntErr( err ))
		{
			#define kFinderFlagsIgnoreMask	 \
				( kHasBeenInited | kNameLocked | kIsInvisible | kIsOnDesk )
			cpbFInfo( &cpb ).fdFlags	=
				header->info1.fdFlags & ~kFinderFlagsIgnoreMask;
			cpbFInfo( &cpb ).fdLocation	= header->info1.fdLocation;
				
			cpbModificationDate( &cpb )	= header->modificationDate;
			cpbCreationDate( &cpb )		= header->creationDate;
				
			err	= FSpSetCatInfo( tempSpec, &cpb );
		}
	}
	
	/* cleanup if error */
	if ( IsErr( err ) )
	{
		(void)FSpDelete( tempSpec );
	}
	
	return( err );
}

			
/*____________________________________________________________________________
	Mac Version
____________________________________________________________________________*/
	static PGPError
sDeMacBinarize(
	PFLFileSpecRef				inSpec,
	MacBinaryHeader const *		header,
	PFLFileSpecRef *			outSpec )
{
	PGPError	err	= kPGPError_NoErr;
	FSSpec		fsSpec;
	
	*outSpec	= kInvalidPFLFileSpecRef;
	
	err	= PFLGetFSSpecFromFileSpec( inSpec, &fsSpec );
	if ( IsntPGPError( err ) )
	{
		short		fileRef;
		OSStatus	macErr;
		
		macErr	= FSpOpenDF( &fsSpec, fsRdPerm, &fileRef );
		if ( IsntErr( macErr ) )
		{
			FSSpec	tempSpec;
			
			macErr	= FSpGetUniqueSpec( &fsSpec, &tempSpec );
			if ( IsntErr( macErr ) )
			{
				macErr = sCreateFromMacBinary(
								PFLGetFileSpecMemoryMgr( inSpec ), fileRef,
								header, &tempSpec );
			}
			
			FSClose( fileRef );
			fileRef	= 0;
			
			if ( IsntErr( macErr ) )
			{
				const unsigned char	kBinExtension[]	= "\p.bin";
				
				/* delete original and move output into its place */
				(void)FSpDelete( &fsSpec );
				
				if ( PStringHasSuffix( fsSpec.name, kBinExtension, FALSE ) )
				{
					fsSpec.name[ 0 ]	-= StrLength( kBinExtension );
					
					macErr	= FSpGetUniqueSpec( &fsSpec, &fsSpec );
				}
				
				if ( IsntErr( macErr ) )
					macErr	= FSpRename( &tempSpec, fsSpec.name );
			}
		}
		
		err	= MacErrorToPGPError( macErr );
	}
	
	if ( IsntPGPError( err ) )
	{
		err	= PFLNewFileSpecFromFSSpec(
			PFLGetFileSpecMemoryMgr( inSpec ), &fsSpec, outSpec );
	}
	
	return( err );
}


#else	/* ] PGP_MACINTOSH [ */


/*____________________________________________________________________________
	Non-Mac Version
	
	Copy from input to output, converting mac line endings to PC line endings.
____________________________________________________________________________*/
	static PGPError
sCopyAndLineEndConvert(
	PGPIORef				inRef,
	PGPSize					requestCount,
	PGPIORef				outRef)
{
	PGPLineEndIORef		convertIO	= NULL;
	PGPError			err	= kPGPError_NoErr;
	ConvertLineEndType	toType;
	
	/* wrap a PGPLineEndIO around the given IO */
#if PGP_UNIX
	toType	= kLFLineEndType;
#elif PGP_WIN32
	toType	= kCRLFLineEndType;
#else
	#error unknown platform

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -