📄 diskmain.cpp
字号:
if (pIOReq->pInBuf) {
if (pIOReq->dwInBufSize != sizeof(DISK_INFO))
return ERROR_INVALID_PARAMETER;
pInfo = (DISK_INFO *)pIOReq->pInBuf;
}
if (pIOReq->pOutBuf) {
if (pIOReq->dwOutBufSize!= sizeof(DISK_INFO))
return ERROR_INVALID_PARAMETER;
pInfo = (DISK_INFO *)pIOReq->pOutBuf;
}
if (!pInfo) {
DEBUGMSG( ZONE_ERROR | ZONE_IOCTL, (TEXT("ATAPI:GetDiskInfo No valid input buffer or output buffer !!!\r\n")));
return ERROR_INVALID_PARAMETER;
}
if (IsRemoveableDevice()) {
}
if (IsAtapiDevice()) {
// TODO:
// AtapiGetDiskInfo();
}
if (ERROR_SUCCESS == dwError) {
__try {
memcpy( pInfo, &m_DiskInfo, sizeof(DISK_INFO));
pInfo->di_flags |= DISK_INFO_FLAG_PAGEABLE;
pInfo->di_flags &= ~DISK_INFO_FLAG_UNFORMATTED;
if (pIOReq->pBytesReturned)
*(pIOReq->pBytesReturned) = sizeof(DISK_INFO);
} __except(EXCEPTION_EXECUTE_HANDLER) {
dwError = ERROR_INVALID_PARAMETER;
}
}
return dwError;
}
/*------------------------------------------------------------------------------------------*/
DWORD CDisk::SetDiskInfo(PIOREQ pIOReq)
{
DWORD dwError = ERROR_SUCCESS;
DISK_INFO *pInfo = (DISK_INFO *)pIOReq->pInBuf;
if ((pIOReq->pInBuf == NULL) ||
(pIOReq->dwInBufSize != sizeof(DISK_INFO))) {
return ERROR_INVALID_PARAMETER;
}
memcpy( &m_DiskInfo, pInfo, sizeof(DISK_INFO));
return dwError;
}
/*------------------------------------------------------------------------------------------*/
DWORD CDisk::GetDeviceInfo(PIOREQ pIOReq)
{
PSTORAGEDEVICEINFO psdi = (PSTORAGEDEVICEINFO)pIOReq->pInBuf;
HKEY hKey;
if ((pIOReq->dwInBufSize== 0) ||
(pIOReq->pInBuf== NULL))
{
return ERROR_INVALID_PARAMETER;
}
if (pIOReq->pBytesReturned)
*(pIOReq->pBytesReturned) = sizeof(STORAGEDEVICEINFO);
psdi->dwDeviceClass = 0;
psdi->dwDeviceType = 0;
psdi->dwDeviceFlags = 0;
wcscpy( psdi->szProfile, L"Default");
if (ERROR_SUCCESS != RegOpenKeyEx( HKEY_LOCAL_MACHINE, m_szDeviceKey, 0, 0, &hKey)) {
hKey = NULL;
}
if (IsAtapiDevice() && IsCDRomDevice()) {
psdi->dwDeviceClass = STORAGE_DEVICE_CLASS_MULTIMEDIA;
psdi->dwDeviceType |= STORAGE_DEVICE_TYPE_REMOVABLE_MEDIA;
psdi->dwDeviceType |= STORAGE_DEVICE_TYPE_ATAPI;
psdi->dwDeviceType |= STORAGE_DEVICE_TYPE_PCIIDE;
psdi->dwDeviceFlags |= STORAGE_DEVICE_FLAG_MEDIASENSE;
psdi->dwDeviceFlags |= STORAGE_DEVICE_FLAG_READONLY;
if (!hKey || !AtaGetRegistryString( hKey, REG_VALUE_CDPROFILE, (PTSTR *)&psdi->szProfile, sizeof(psdi->szProfile))) {
wcscpy( psdi->szProfile, REG_VALUE_CDPROFILE);
}
} else {
psdi->dwDeviceClass = STORAGE_DEVICE_CLASS_BLOCK;
psdi->dwDeviceType |= STORAGE_DEVICE_TYPE_PCIIDE;
psdi->dwDeviceType |= STORAGE_DEVICE_TYPE_ATA;
psdi->dwDeviceFlags |= STORAGE_DEVICE_FLAG_READWRITE;
if (!hKey || !AtaGetRegistryString( hKey, REG_VALUE_HDPROFILE, (PTSTR *)&psdi->szProfile, sizeof(psdi->szProfile))) {
wcscpy( psdi->szProfile, REG_VALUE_HDPROFILE);
}
}
return ERROR_SUCCESS;
}
/*------------------------------------------------------------------------------------------*/
DWORD CDisk::GetDiskName(PIOREQ pIOReq)
{
static PTCHAR szDefaultDiscDrive = TEXT("External Volume");
PTCHAR szDiskName = NULL;
DWORD dwSize;
DEBUGMSG( ZONE_IOCTL, (TEXT("ATAPI:GeDisktName\r\n")));
if ((pIOReq->pBytesReturned == NULL) ||
(pIOReq->dwOutBufSize == 0) ||
(pIOReq->pOutBuf == NULL) )
{
return ERROR_INVALID_PARAMETER;
}
*(pIOReq->pBytesReturned) = 0;
if (m_szDiskName)
{
if (wcslen( m_szDiskName))
{
szDiskName = m_szDiskName;
}
else
{
return ERROR_NOT_SUPPORTED;
}
}
else
{
szDiskName = szDefaultDiscDrive;
}
dwSize = (wcslen( szDiskName)+1) * sizeof(TCHAR);
if (pIOReq->dwOutBufSize < dwSize)
{
return ERROR_INSUFFICIENT_BUFFER;
}
wcscpy( (PTCHAR) pIOReq->pOutBuf, szDiskName);
*(pIOReq->pBytesReturned) = dwSize;
return ERROR_SUCCESS;
}
/*------------------------------------------------------------------------------------------*/
DWORD CDisk::ReadWriteDisk(PIOREQ pIOReq, BOOL fRead)
{
DWORD dwError = ERROR_SUCCESS;
PBYTE pBuffer;
PSG_REQ pSgReq = (PSG_REQ)pIOReq->pInBuf;
DWORD dwStartSector, dwNumSectors, dwSectorsToTransfer, dwSectorsPerBlock, dwSgLeft, dwSgLen;
DWORD dwMaxPerBlock = m_bSectorsPerBlock;
PSG_BUF pSgBuf;
BYTE bCmd = fRead ? m_bReadCommand : m_bWriteCommand;
//* * * CAMSDB040504 - Changed the debug port. (START)
//DEBUGMSG( ZONE_IOCTL, (TEXT("ATAPI:ReadWriteDisk Entered\r\n")));
//DEBUGMSG( 1, (TEXT("ATAPI:ReadWriteDisk Entered\r\n")));
//* * * CAMSDB040504 - Changed the debug port. (START)
//* * * Manual BREAK (START) * * *
//DebugBreak();
//* * * Manual BREAK (END) * * *
if ((pSgReq == NULL) ||
(pIOReq->dwInBufSize < sizeof(SG_REQ)))
{
return ERROR_INVALID_PARAMETER;
}
if ((pSgReq->sr_num_sec == 0) ||
(pSgReq->sr_num_sg == 0))
{
return ERROR_INVALID_PARAMETER;
}
//
// Gets the status and calls Interrupt Done.
//
EnableInterrupt();
dwSgLeft = pSgReq->sr_num_sg; // The number of SG segments
dwNumSectors = pSgReq->sr_num_sec;
dwStartSector = pSgReq->sr_start; // Get the Start Sector
pSgBuf = &(pSgReq->sr_sglist[0]);
dwSgLen = pSgBuf->sb_len;
pBuffer = (PBYTE)MapPtrToProcess((LPVOID)pSgBuf->sb_buf, GetCallerProcess());
/*
if( fRead )
RETAILMSG( 1, (TEXT("ATAPI: READ StartSector=%ld NumSectors=%ld NumSg=%ld\r\n"),
dwStartSector, dwNumSectors, dwSgLeft));
else
RETAILMSG( 1, (TEXT("ATAPI: WRITE StartSector=%ld NumSectors=%ld NumSg=%ld\r\n"),
dwStartSector, dwNumSectors, dwSgLeft));
RETAILMSG( 1, (TEXT("ATAPI:ReadWriteDisk SG len %d\r\n"), dwSgLen));
*/
m_wNextByte = 0xFFFF;
DEBUGMSG( ZONE_IO, (TEXT("ATAPI:ReadWriteDisk StartSector=%ld NumSectors=%ld NumSg=%ld\r\n"), dwStartSector, dwNumSectors, dwSgLeft));
while(dwNumSectors)
{
if (dwNumSectors > dwMaxPerBlock)
dwSectorsToTransfer = dwMaxPerBlock;
// The Maximal Number of Sectors per Command is 256.
// if (dwNumSectors > MAX_SECT_PER_COMMAND)
// dwSectorsToTransfer = MAX_SECT_PER_COMMAND;
else
dwSectorsToTransfer = dwNumSectors;
dwNumSectors -= dwSectorsToTransfer;
if (!SendIOCommand(dwStartSector,dwSectorsToTransfer, bCmd))
{
HardResetAndForcePIOMode();
//
// Interrupt gets set during atapi reset.
// Gets the status and calls Interrupt Done.
//
EnableInterrupt();
if (!SendIOCommand(dwStartSector,dwSectorsToTransfer, bCmd))
{
dwError = fRead ? ERROR_READ_FAULT : ERROR_WRITE_FAULT;
//RETAILMSG( 1, (TEXT("ATAPI:ReadWriteDisk SendCommand Failed\r\n")));
break;
}
}
dwStartSector += dwSectorsToTransfer;
// The read command expects an interrupt before data transfer.
// The write command, on the other side, expects an interrupt after
// dwSectorsPerBlock = dwMaxPerBlock;
while(dwSectorsToTransfer && (dwSgLeft > 0))
{
dwSectorsPerBlock = MIN( dwMaxPerBlock, dwSectorsToTransfer );
/*
if (dwSectorsPerBlock > dwSectorsToTransfer)
{
dwSectorsPerBlock = dwSectorsToTransfer;
}
*/
dwSectorsToTransfer -= dwSectorsPerBlock;
if (fRead && m_fInterruptSupported)
{
if (!WaitForInterrupt(DISK_IO_TIME_OUT) || (CheckIntrState() == ATA_INTR_ERROR))
{
DEBUGMSG( ZONE_IO, (TEXT("ATAPI:ReadWrite- WaitforInterrupt failed (DevId %x) \r\n"),m_dwDeviceId));
RETAILMSG( 1, (TEXT("ATAPI:ReadWriteDisk SendCommand Failed 22222\r\n")));
dwError = ERROR_READ_FAULT;
break;
}
}
if (!WaitForDRQ())
{
DEBUGMSG( ZONE_IO, (TEXT("ATAPI:ReadWrite- WaitforDRQ failed (DevId %x) \r\n"),m_dwDeviceId));
dwError = ERROR_READ_FAULT;
//RETAILMSG( 1, (TEXT("ATAPI:ReadWriteDisk SendCommand Failed 333333\r\n")));
break;
}
DWORD dwBytesPerBlock = dwSectorsPerBlock * m_DiskInfo.di_bytes_per_sect;
while ((dwBytesPerBlock>0) && (dwSgLeft >0))
{
DWORD dwReadThisTime = MIN(dwSgLen, dwBytesPerBlock); //(dwSgLen < dwBytesPerBlock) ? dwSgLen : dwBytesPerBlock;
//RETAILMSG( 1, (TEXT("ATAPI:get %d (len %d--%d)\r\n"), dwReadThisTime,dwSgLen,dwBytesPerBlock));
dwSgLen -= dwReadThisTime;
dwBytesPerBlock -= dwReadThisTime;
fRead ? ReadBuffer(pBuffer,dwReadThisTime)
: WriteBuffer(pBuffer,dwReadThisTime);
pBuffer += dwReadThisTime; //
// Go to the next scatter/gather if no more space left
if ((dwSgLen == 0) && ( --dwSgLeft > 0)) {
pSgBuf++;
pBuffer = (PBYTE)MapPtrToProcess((LPVOID)pSgBuf->sb_buf, GetCallerProcess());
dwSgLen = pSgBuf->sb_len;
//RETAILMSG( 1, (TEXT("ATAPI:ReadWriteDisk SG len %d\r\n"), dwSgLen));
}
}
if (fRead) {
while (dwBytesPerBlock > 0) {
(void) ReadWord();
dwBytesPerBlock-=2 ;
}
}
}
if (ERROR_SUCCESS != dwError)
break;
// In case of write command an interrupt is generated upon each block.
// We can either wait for the interrupt or simply ignore it.
// However this is danger because an interrupt is pending and blocks all
// other interrupts on the same or lower level.
if ( !fRead && m_fInterruptSupported) {
if (!WaitForInterrupt(DISK_IO_TIME_OUT) || (CheckIntrState() == ATA_INTR_ERROR)) {
DEBUGMSG( ZONE_IO, (TEXT("ATAPI:ReadWrite- WaitforInterrupt failed (DevId %x) \r\n"),m_dwDeviceId));
//RETAILMSG( 1, (TEXT("ATAPI:ReadWriteDisk SendCommand Failed 44444\r\n")));
dwError = ERROR_WRITE_FAULT;
break;
}
}
}
// if (ERROR_SUCCESS != dwError)
// {
//
// TODO TODO TODO - Reset Device and setup the dma again.
//
// ResetController();
//if (!(m_Id.Capabilities & 0x0200) && m_fLBAMode)
//{
// m_fLBAMode = FALSE;
// dwError = ReadWriteDisk(pIOReq, fRead);
//}
//else
//{
//}
// }
pSgReq->sr_status = dwError;
return dwError;
}
/*------------------------------------------------------------------------------------------*/
DWORD CDisk::ReadWriteDiskDMA(PIOREQ pIOReq, BOOL fRead)
{
DWORD dwError = ERROR_SUCCESS;
PSG_REQ pSgReq = (PSG_REQ)pIOReq->pInBuf;
DWORD dwSectorsToTransfer;
SG_BUF CurBuffer[MAX_SG_BUF];
BYTE bCmd;
BOOL bRetryUsingPIO = FALSE;
ULONG ulWaitReturn;
BOOL bRet;
DEBUGMSG( ZONE_DMA, (TEXT("+CDisk::ReadWriteDiskDMA\r\n")));
if ((pSgReq == NULL) || (pIOReq->dwInBufSize < sizeof(SG_REQ)))
{
return ERROR_INVALID_PARAMETER;
}
if ((pSgReq->sr_num_sec == 0) ||
(pSgReq->sr_num_sg == 0))
{
return ERROR_INVALID_PARAMETER;
}
DEBUGMSG
(
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -