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

📄 diskmain.cpp

📁 3sc2443的CF卡IDE源代码,肯定好用.
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    DEBUGMSG(ZONEID_INIT, (TEXT("Atapi!CDisk::PostInit> device(%d)\r\n"), m_dwDeviceId));

    m_hDevice = pPostInitBuf->p_hDevice;

    return (dwError == ERROR_SUCCESS);
}

// ----------------------------------------------------------------------------
// Function: GetDiskInfo
//     Implement IOCTL_DISK_GETINFO
//
// Parameters:
//     pIOReq -
// ----------------------------------------------------------------------------

DWORD
CDisk::GetDiskInfo(
    PIOREQ pIOReq
    )
{
    DWORD dwError = ERROR_SUCCESS;
    DISK_INFO *pInfo = NULL;

    // for B/C, this call has three forms; only pInBuf, only pOutBuf, or both
    // if both, then use pOutBuf

    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, (_T(
            "Atapi!CDisk::GetDiskInfo> bad argument; pInBuf/pOutBuf null\r\n")));
        return ERROR_INVALID_PARAMETER;
    }

    // TODO: if device is ATAPI, call 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;
}

// ----------------------------------------------------------------------------
// Function: SetDiskInfo
//     Implement IOCTL_DISK_SETINFO
//
// Parameters:
//     pSgReq -
//     InBufLen -
// ----------------------------------------------------------------------------

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;
}

// ----------------------------------------------------------------------------
// Function: GetDeviceInfo
//     IOCTL_DISK_DEVICE_INFO
//
// Parameters:
//     pIOReq -
// ----------------------------------------------------------------------------

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;

    PTSTR szProfile = psdi->szProfile;

    wcscpy(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, &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_2443_CFPROFILE, &szProfile, sizeof(psdi->szProfile))) {
            wcscpy(psdi->szProfile, REG_VALUE_2443_CFPROFILE);
        }

    }

    return ERROR_SUCCESS;
}

// ----------------------------------------------------------------------------
// Function: GetDiskName
//     Implement IOCTL_DISK_GETNAME
//
// Parameters:
//     pIOReq -
// ----------------------------------------------------------------------------

DWORD
CDisk::GetDiskName(
    PIOREQ pIOReq
    )
{
    static PTCHAR szDefaultDiscDrive = (_T("External Volume"));
    PTCHAR szDiskName = NULL;
    DWORD dwSize;

    DEBUGMSG(ZONE_IOCTL, (_T("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;
}

// ----------------------------------------------------------------------------
// Function: ReadWriteDisk
//     Implement ATA/ATAPI-6 R3B 8.34 (READ SECTOR(S)) and 8.62 (WRITE SECTOR(S)).
//     Implement ATA/ATAPI-6 R3B 9.5 (PIO data-in command protocol) and 9.6
//     (PIO data-out command protocol).
//     This function reads from/writes to an ATA device.
//
// Parameters:
//     pIOReq -
//     fRead -
//
// Notes:
//     READ SECTOR(S) and WRITE SECTOR(S) can transfer up to 256 sectors; however,
//     every transfer is segmented, as per the PIO data-in/out protocol.  A segment
//     of a multiple-block transfer is called a "DRQ data block" and is the length
//     of a sector; see ATA/ATAPI-6 R3B 9.5 and 9.6 for more information.
// ----------------------------------------------------------------------------

DWORD
CDisk::ReadWriteDisk(
    PIOREQ pIOReq,
    BOOL fRead
    )
{
    DWORD dwError = ERROR_SUCCESS; // result

    PSG_REQ pSgReq = (PSG_REQ) pIOReq->pInBuf; // scatter/gather request
    PSG_BUF pSgBuf;                            // scatter/gather buffer

    BYTE bStatus; // device Status register

    BYTE bCmd = fRead ? m_bReadCommand : m_bWriteCommand; // command

    DWORD dwCurBufNum;           // current scatter/gather buffer
    DWORD dwCurBufPos;           // current position in current scatter/gather buffer
    PBYTE pBuffer;               // pointer to current address of current scatter/gather buffer
    DWORD dwCurDoubleBufPos;     // current position in current double buffer
    DWORD dwCurDoubleBufLen;     // length of current double buffer (for reads)
    PBYTE pDoubleBuffer;         // pointer to current address of double buffer
    DWORD dwCurByte;             // current byte (to increment current sector of transfer) of "global" transfer
    DWORD dwCurSec;              // current sector of "global" transfer
    DWORD dwCurDRQDataBlockByte; // current byte of current DRQ data block transfer
    BOOL fWriteComplete;         // to facilitate PIO data-out protocol, flag transfer complete
	DWORD dwCount;	    
	DWORD dwBufferLengthAlign = TRUE;

    // validate arguments
    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;
    }
    if ((pSgReq->sr_start + pSgReq->sr_num_sec) > m_DiskInfo.di_total_sectors) {
        return ERROR_SECTOR_NOT_FOUND;
    }

    // do we have to allocate the double buffer?
    if (NULL == m_rgbDoubleBuffer) {
        DEBUGMSG(ZONE_INIT, (TEXT(
            "Atapi!CDisk::ReadWriteDisk> Allocating double buffer [first use]\r\n"
            )));
        m_rgbDoubleBuffer = (PBYTE)LocalAlloc(LPTR, m_pPort->m_pDskReg[m_dwDeviceId]->dwDoubleBufferSize);
        if (NULL == m_rgbDoubleBuffer) {
            DEBUGMSG(ZONE_ERROR, (TEXT(
                "Atapi!CDisk::ReadWriteDisk> Failed to allocate double buffer\r\n"
                )));
            dwError = ERROR_OUTOFMEMORY;
            goto exit;
        }
    }

    // clear interrupt, if set
    // TODO: Is this necessary?
    // GetBaseStatus();

    // initialize "global" transfer state
    dwCurSec = pSgReq->sr_start;
    dwCurByte = 0;

    // fetch first scatter/gather buffer
    dwCurBufNum = 0;
    dwCurBufPos = 0;
    pSgBuf = &(pSgReq->sr_sglist[0]);
    // map nested pointer and test for security violation
    pBuffer = (PBYTE)MapCallerPtr((LPVOID)pSgBuf->sb_buf, pSgBuf->sb_len);
    
    if (pSgBuf->sb_buf != NULL && pBuffer == NULL) {
        // security violation
        DEBUGMSG(ZONE_ERROR, (TEXT(
            "Atapi!CDisk::ReadWriteDisk> Failed to map pointer to caller\r\n"
            )));
        return ERROR_INVALID_PARAMETER;
    }
/*    
	RETAILMSG(1, (_T(
				"ReadWrite()::: this is %d start sec 0x%x num sec 0x%x\r\n"
			),bCmd,dwCurSec,pSgReq->sr_num_sec));
*/
    // is this a read or a write?

    if ( ((pSgBuf->sb_len )% BYTES_PER_SECTOR != 0) || (pSgReq->sr_num_sg > 1) || ((UINT32)pBuffer % 4 != 0))
    	dwBufferLengthAlign = FALSE;
    	
    if (fRead) {

        // --------------------------------------------------------------------
        // ATA/ATAPI-6 R3B 9.5 (PIO data-in protocol)
        // --------------------------------------------------------------------

        // Host_Idle
        // ---------
        // issue command
PIO_Data_In_Read_Command:;
        // determine size of transfer
        if ((((pSgReq->sr_start + pSgReq->sr_num_sec) - dwCurSec) * m_DiskInfo.di_bytes_per_sect) > m_pPort->m_pDskReg[m_dwDeviceId]->dwDoubleBufferSize) {
            dwCurDoubleBufLen = m_pPort->m_pDskReg[m_dwDeviceId]->dwDoubleBufferSize;
        }
        else {
            dwCurDoubleBufLen = ((pSgReq->sr_start + pSgReq->sr_num_sec) - dwCurSec) * m_DiskInfo.di_bytes_per_sect;
        }

        // issue command
		if ( m_pPort->m_pDskReg[m_dwDeviceId]->dwEnableUDMA && dwBufferLengthAlign )
		{
//			RETAILMSG(1, (_T(
//				"### Before SendIOCommand() 0x%x 0x%x \r\n"),dwCurSec,dwCurDoubleBufLen));		
			if (!SendIOCommand(dwCurSec, dwCurDoubleBufLen / m_DiskInfo.di_bytes_per_sect, 0xc8)) {
				DEBUGMSG(ZONE_ERROR, (_T(
					"Atapi!CDisk::ReadWriteDisk> Failed to issue read/write command\r\n"
				)));
				RETAILMSG(1, (_T(
					"Atapi!CDisk::ReadWriteDisk> Failed to issue read command\r\n"
				)));			
			dwError = fRead ? ERROR_READ_FAULT : ERROR_WRITE_FAULT;
			goto exit;
			}		
		}
		
		
		else
		{
			if (!SendIOCommand(dwCurSec, dwCurDoubleBufLen / m_DiskInfo.di_bytes_per_sect, bCmd)) {
				DEBUGMSG(ZONE_ERROR, (_T(
					"Atapi!CDisk::ReadWriteDisk> Failed to issue read/write command\r\n"
				)));
				RETAILMSG(1, (_T(
					"Atapi!CDisk::ReadWriteDisk> Failed to issue read command\r\n"
				)));			
			dwError = fRead ? ERROR_READ_FAULT : ERROR_WRITE_FAULT;
			goto exit;
			}
		}

		pDoubleBuffer = m_rgbDoubleBuffer;
		dwCurDoubleBufPos = 0;		
        // INTRQ_Wait
        // ----------
        // wait for interrupt if nIEN=0 (i.e., if interrupt enabled)
HPIOI_INTRQ_Wait:;
        // if nIEN=0 (interrupt enabled), wait for interrupt
        if (m_fInterruptSupported) {
     
            if (!WaitForInterrupt(m_dwDiskIoTimeOut) || (CheckIntrState() == ATA_INTR_ERROR)) {
                DEBUGMSG(ZONE_IO|ZONE_WARNING, (_T(
                    "Atapi!CDisk::ReadWriteDisk> Failed to wait for interrupt (m_dwDeviceId=%d)\r\n"
                    ), m_dwDeviceId));                    
                RETAILMSG(1, (_T(
                   "Atapi!CDisk::ReadWriteDisk> Failed to wait for interrupt (m_dwDeviceId=%d)\r\n"
                   ), m_dwDeviceId));
                dwError = ERROR_READ_FAULT;
                goto exit;
            }
            //goto HPIOI_Transfer_Data_Setup;
        }

        // Check_Status
        // ------------
        // if BSY=0 and DRQ=0, transition to Host_Idle
        // if BSY=1, re-enter this state
        // if BSY=0 and DRQ=1, transition to Transfer_Data
HPIOI_Check_Status:;
        bStatus = GetAltStatus();               

⌨️ 快捷键说明

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