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

📄 cpgpdiskimpdrv98.cpp

📁 PGP8.0源码 请认真阅读您的文件包然后写出其具体功能
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	return error;
}

CComboError
CPGPdiskImpDrv98::PerformPremountTasks()
{
	CComboError	error;

	// Save contents of boot block.
	error = mFile.Read(mBootBlock, mFirstDataBlock*kPGPdiskBlockSize, 
		kPGPdiskBlockSize);

	if (error.IsntError())
		error = mCipherContext.DecryptCFB(0, 1, mBootBlock, mBootBlock);

	// Massage FileSystem IO requests on 98 to prevent hangs.
	if (error.IsntError())
	{
		mBufferToWatchFor = mBuffer;

		error = CDriverSubsystemsDrv98::FilesystemWatcher().WatchForBuffer(
			mBuffer);
	}

	return error;
}

PGPUInt16 
CPGPdiskImpDrv98::ProcessIorGenIoctl(CIop& iop)
{
	pgpAssert(IsMounted());

	CComboError	error;
	PGPUInt32	ioctlStatus	= 0;
	PGPUInt32	iopStatus	= 0;

	UDebug::DebugOut("PGPdisk: Ioctl - function=%x minor %x\n", 
		iop.IoctlFunction(), iop.IoctlControlParam() & 0xff);

	// We only process some 440D functions and the 4411 function.
	switch (iop.IoctlFunction())
	{

	case 0x440D:
		switch (UMath::GetLowByte(UMath::GetLowWord(
			iop.IoctlControlParam())))
		{

		case 0x40:			// Set Device Parameters
		{
			// We don't actually have to 'do' anything here. The system
			// will set these parameters when it writes the boot block,
			// which is where we get them from anyways.

			ioctlStatus = ERROR_SUCCESS;
			iopStatus = IORS_SUCCESS;
			break;
		}

		case 0x41:			// Write Track on Logical Drive
		{
			FileSys::RwBlock	*pRWB	= static_cast<FileSys::RwBlock *>(
				iop.IoctlBuffer());
			pgpAssertAddrValid(pRWB, RwBlock);

			// Calculate the starting sector.
			PGPUInt64	pos	= pRWB->rwCylinder * FileSys::kSizeCyl;

			pos	+= pRWB->rwHead * FileSys::kSizeHead;
			pos	+= pRWB->rwFirstSector;

			// Calculate the number of blocks to write.
			PGPUInt32	nBlocks	= pRWB->rwSectors;

			// Calculate the buffer address.
			void	*buf	= Map16BitAddrToLinear(
				UMath::GetHighWord(pRWB->rwBuffer), 
				UMath::GetLowWord(pRWB->rwBuffer));

			// Perform the write.
			error = Write(buf, pos, nBlocks);

			ioctlStatus = (error.IsntError() ? ERROR_SUCCESS : 
				ERROR_INVALID_FUNCTION);
			iopStatus = IORS_SUCCESS;
			break;
		}

		case 0x42:			// Format Track on Logical Drive
		{		
			// Don't actually do anything, since PGPdisks aren't physical
			// drives that need any special treatment of sectors before
			// being written to.

			FileSys::FvBlock	*pFVB	= static_cast<FileSys::FvBlock *>(
				iop.IoctlBuffer());
			pgpAssertAddrValid(pFVB, FvBlock);

			if (pFVB->fvSpecFunc == 1)
				pFVB->fvSpecFunc = 0;

			ioctlStatus = ERROR_SUCCESS;
			iopStatus = IORS_SUCCESS;
			break;
		}

		case 0x60:			// Get Device Parameters
		{
			switch (UMath::GetHighByte(UMath::GetLowWord(
				iop.IoctlControlParam())))
			{
			case 0x08:
			{
				FileSys::DevParamsFat16	*pDp16	= static_cast<
					FileSys::DevParamsFat16 *>(iop.IoctlBuffer());

				pgpAssertAddrValid(pDp16, DevParamsFat16);
				error = GetDevParamsFat16(*pDp16);
			}
			break;

			case 0x48:
			{
				FileSys::DevParamsFat32	*pDp32	= static_cast<
					FileSys::DevParamsFat32 *>(iop.IoctlBuffer());

				pgpAssertAddrValid(pDp32, DevParamsFat32);
				error = GetDevParamsFat32(*pDp32);
			}
			}

			ioctlStatus = (error.IsntError() ? ERROR_SUCCESS : 
				ERROR_INVALID_FUNCTION);
			iopStatus = IORS_SUCCESS;
			break;
		}

		case 0x61:			// Read Track on Logical Drive
		{
			FileSys::RwBlock	*pRWB	= static_cast<FileSys::RwBlock *>(
				iop.IoctlBuffer());
			pgpAssertAddrValid(pRWB, RwBlock);

			// Calculate the starting sector.
			PGPUInt64	pos	= pRWB->rwCylinder * FileSys::kSizeCyl;
			pos	+= pRWB->rwHead * FileSys::kSizeHead;
			pos	+= pRWB->rwFirstSector;

			// Calculate the number of blocks to read.
			PGPUInt32	nBlocks	= pRWB->rwSectors;

			// Calculate the buffer address.
			void	*buf	= Map16BitAddrToLinear(
				UMath::GetHighWord(pRWB->rwBuffer), 
				UMath::GetLowWord(pRWB->rwBuffer));

			// Perform the read.
			error = Read(buf, pos, nBlocks);

			ioctlStatus = (error.IsntError() ? ERROR_SUCCESS : 
				ERROR_INVALID_FUNCTION);
			iopStatus = IORS_SUCCESS;
			break;
		}

		case 0x66:			// Get Media ID
		{	
			FileSys::MID	*pMid	= static_cast<FileSys::MID *>(
				iop.IoctlBuffer());

			error = GetMID(*pMid);

			ioctlStatus = (error.IsntError() ? ERROR_SUCCESS : 
				ERROR_INVALID_FUNCTION);
			iopStatus = IORS_SUCCESS;
			break;
		}

		default:
			ioctlStatus = ERROR_INVALID_FUNCTION;
			iopStatus = IORS_INVALID_COMMAND;
			break;
		}
		break;

	case 0x4411:		// Query if we handle specified 440D code
		switch (UMath::GetLowByte(UMath::GetLowWord(
			iop.IoctlControlParam())))
		{
		case 0x40:
		case 0x41:
		case 0x42:
		case 0x60:
		case 0x61:
		case 0x66:
			ioctlStatus = ERROR_SUCCESS;
			iopStatus = IORS_SUCCESS;
			break;

		default:
			ioctlStatus = ERROR_INVALID_FUNCTION;
			iopStatus = IORS_SUCCESS;
			break;
		}
		break;

	default:
		ioctlStatus = ERROR_INVALID_FUNCTION;
		iopStatus = IORS_INVALID_COMMAND;
		break;
	}

	iop.IoctlReturn() = ioctlStatus;

	return static_cast<PGPUInt16>(iopStatus);
}

PGPUInt16 
CPGPdiskImpDrv98::ProcessIorReadWrite(CIop& iop)
{
	pgpAssert(IsMounted());

	CComboError	error;
	PGPBoolean	isAWrite	= (iop.Func() == IOR_WRITE);

	if (isAWrite && IsReadOnly())
		return IORS_WRITE_PROTECT;

	if (!error.HaveNonPGPError())
	{
		PGPUInt32	pos	= static_cast<PGPUInt32>(iop.StartAddress());

		// Requests can either be in pieces (scatter/gather) or not.
		if (iop.IsScatterGather())
		{
			PBDSGD	pBDSGD;

			pBDSGD = static_cast<PBDSGD>(iop.Buffer());
			pgpAssertAddrValid(pBDSGD, BDSGD);

			while (TRUE)
			{
				PGPUInt32	nBlocks	= pBDSGD->SG_buff_size;

				if (nBlocks == 0)
					break;

				if (iop.IsInBytes())
				{
					pgpAssert(nBlocks % kPGPdiskBlockSize == 0);
					nBlocks /= kPGPdiskBlockSize;
				}

				void	*buf	= reinterpret_cast<void *>(
					pBDSGD->SG_buff_ptr);
				pgpAssertAddrValid(buf, VoidAlign);

				if (isAWrite)
					error = Write(buf, pos, nBlocks);
				else
					error = Read(buf, pos, nBlocks);

				pos += nBlocks;
				pBDSGD++;

				if (error.IsError())
					break;
			}
		}
		else
		{
			PGPUInt32	nBlocks	= iop.TransferCount();

			if (iop.IsInBytes())
			{
				pgpAssert(nBlocks % kPGPdiskBlockSize == 0);
				nBlocks /= kPGPdiskBlockSize;
			}

			void	*buf	= iop.Buffer();
			pgpAssertAddrValid(buf, VoidAlign);

			if (isAWrite)
				error = Write(buf, pos, nBlocks);
			else
				error = Read(buf, pos, nBlocks);
		}
	}

	if (error.IsntError())
		return IORS_SUCCESS;
	else
		return IORS_MEDIA_ERROR;
}

void 
CPGPdiskImpDrv98::ProcessIopCallbackAux(CIop& iop)
{
	pgpAssert(IsMounted());

	CComboError	error;
	PGPUInt16	iorFunc		= iop.Func();
	PGPUInt32	iopAddress	= reinterpret_cast<PGPUInt32>(
		static_cast<PIOP>(iop));

	UDebug::DebugOut("PGPdisk: Processing an %s address %X.", 
		UConstantNamesDrv98::NameIorFunction(iorFunc), iopAddress);

	// Process the IOP according to function.
	switch (iorFunc)
	{
	case IOR_READ:
 	case IOR_WRITE:
		error.err = ProcessIorReadWrite(iop);
		break;

	default:
		pgpAssert(FALSE);
		error.err = IORS_INVALID_COMMAND;
		break;
	}

	iop.Callback(static_cast<PGPUInt16>(error.err));

	UDebug::DebugOut("PGPdisk: Done processing an %s address %X status %X.", 
		UConstantNamesDrv98::NameIorFunction(iorFunc), iopAddress, error.err);
}

void 
CPGPdiskImpDrv98::ProcessIopCallback(void *refPtr)
{
	CIop	iop(static_cast<PIOP>(refPtr));

	CPGPdiskImpDrv98	*pImp	= reinterpret_cast<CPGPdiskImpDrv98 *>(
		iop.PrivatePort());
	pgpAssertAddrValid(pImp, CPGPdiskImpDrv98);

	pImp->ProcessIopCallbackAux(iop);
}

CComboError 
CPGPdiskImpDrv98::QueueIopToIoThread(CIop& iop)
{
	CComboError	error;
	
	iop.PrivatePort() = reinterpret_cast<unsigned long>(this);
	mIoThread->PerformAsyncCallback(ProcessIopCallback, iop.Get());

	return error;
}

PGPUInt32 
CPGPdiskImpDrv98::ProcessExternalIo(void *ioPacket, PGPBoolean& wasCompleted)
{
	pgpAssert(IsMounted());

	// This is going to be an IOP.
	CComboError	error;
	CIop		iop(static_cast<PIOP>(ioPacket));
	PGPBoolean	completeNow	= TRUE;
	PGPUInt16	iorFunc		= iop.Func();
	PGPUInt32	iopAddress	= reinterpret_cast<PGPUInt32>(ioPacket);

	UDebug::DebugOut("PGPdisk: Seeing an %s address %X.", 
		UConstantNamesDrv98::NameIorFunction(iorFunc), iopAddress);

	switch (iorFunc)
	{
	case IOR_GEN_IOCTL:
		// NEVER SCHEDULE IOCTL REQUESTS. ALWAYS PROCESS IN SAME CONTEXT IN
		// WHICH THEY ARE RECEIVED.

		error.err = ProcessIorGenIoctl(iop);
		break;

	case IOR_READ:
	case IOR_WRITE:
		// Queue the IOP to the thread.
		error = QueueIopToIoThread(iop);

		if (error.IsError())
			error.err = IORS_MEMORY_ERROR;
		else
			completeNow = FALSE;

		break;

	default:
		error.err = IORS_INVALID_COMMAND;
		break;
	}

	// Complete if not scheduled.
	if (completeNow)
	{
		iop.Callback(static_cast<PGPUInt16>(error.err));
		wasCompleted = TRUE;

		UDebug::DebugOut("PGPdisk: Completed an %s address %X status %X.", 
			UConstantNamesDrv98::NameIorFunction(iorFunc), 
			iopAddress, static_cast<PGPUInt32>(error.err));
	}
	else
	{
		UDebug::DebugOut("PGPdisk: Scheduled an %s IOP address %X.", 
			UConstantNamesDrv98::NameIorFunction(iorFunc), iopAddress);
	}

	return error.err;
}

⌨️ 快捷键说明

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