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

📄 diskmain.cpp

📁 Samsung公司S3C6400芯片的BSP源码包
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                dwError = ERROR_GEN_FAILURE;
                break;
            }

            DWORD dwIndex = 0, mappedbuffers = 0;
            PUCHAR  savedoldptrs[MAX_SG_BUF] ;  // This will hold a copy of the user mode pointers that get overwritten
                                                // ValidateSg


            // Validate the SG_REQ request and map the caller's sb_bufs into
            // the sterile copy,
            if (FALSE == ValidateSg(m_pSterileIoRequest, pIOReq->dwInBufSize, fRead ? ARG_O_PTR : ARG_I_PTR,savedoldptrs)) {
                dwError = ERROR_INVALID_PARAMETER;
                break;
            }

            // Replace the caller's SG_REQ in the I/O request with the sterile
            // copy.
            pIOReq->pInBuf = (PBYTE)m_pSterileIoRequest;
            // Execute the I/O request.
            if (IsDMASupported()) {
                __try {
                    dwError = ReadWriteDiskDMA(pIOReq, fRead);
                }
                __except(EXCEPTION_EXECUTE_HANDLER) {
                    AbortDMA();
                    dwError = ERROR_INVALID_PARAMETER;
                    m_pSterileIoRequest->sr_status = ERROR_INVALID_PARAMETER;
                    goto Cleanup;
                }
            }
            else {
                // Allocate the double buffer, as required.
                if ((NULL == m_rgbDoubleBuffer) && (0 < m_pPort->m_pDskReg[m_dwDeviceId]->dwDoubleBufferSize)) {
                    DEBUGMSG(ZONE_INIT, (TEXT("Atapi!CDisk::MainIoctl> 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::MainIoctl> Failed to allocate double buffer\r\n")));
                        dwError = ERROR_OUTOFMEMORY;
                        m_pSterileIoRequest->sr_status = ERROR_OUTOFMEMORY;
                        goto Cleanup;
                    }
                }
                // Perform the I/O.
                if (fRead) {
                    dwError = this->ReadDisk(pIOReq);
                }
                else {
                    dwError = this->WriteDisk(pIOReq);
                }
            }

Cleanup:
            if (FAILED(UnmapSg(
                        m_pSterileIoRequest->sr_sglist,
                        savedoldptrs,
                        m_pSterileIoRequest->sr_num_sg,
                        fRead ? ARG_O_PTR : ARG_I_PTR)))
            {
                ASSERT(!"Cleanup call to CeCloseCallerBuffer failed unexpectedly");
                dwError = ERROR_GEN_FAILURE;
            }
                    
            // Copy sr_status from the sterile SG_REQ to the caller's SG_REQ.
            __try {
                pUnsafeInBuf->sr_status = m_pSterileIoRequest->sr_status;
            }
            __except(EXCEPTION_EXECUTE_HANDLER) {
                dwError = ERROR_INVALID_PARAMETER;
            }
            break;
        }
        case IOCTL_DISK_GET_STORAGEID:
            dwError = GetStorageId(pIOReq);
            break;
        case DISK_IOCTL_FORMAT_MEDIA:
        case IOCTL_DISK_FORMAT_MEDIA:
            dwError = ERROR_SUCCESS;
            break;
        case IOCTL_DISK_FLUSH_CACHE:
            dwError = FlushCache();
            break;
        default:
            dwError = ERROR_NOT_SUPPORTED;
            break;
    }
    return dwError;
}

// ----------------------------------------------------------------------------
// Function: PerformIoctl
//     This is the top-most IOCTL processor and is used to trap IOCTL_POWER_
//     I/O controls to pass to the associated power management object
//
// Parameters:
//     pIOReq -
// ----------------------------------------------------------------------------

BOOL
CDisk::PerformIoctl(
    PIOREQ pIOReq
    )
{
    DWORD dwError = ERROR_SUCCESS;

    DEBUGMSG(ZONE_IOCTL, (TEXT(
        "Atapi!CDisk::PerformIoctl> IOCTL(%x), device(%x)\r\n"
        ), pIOReq->dwCode, m_dwDeviceId));

    if (pIOReq->pBytesReturned) {
        *(pIOReq->pBytesReturned) = 0;
    }

    TakeCS();
    m_pPort->TakeCS();

    if (ZONE_CELOG) CeLogData(TRUE, CELID_ATAPI_STARTIOCTL, pIOReq, sizeof(*pIOReq), 0, CELZONE_ALWAYSON, 0, FALSE);

    __try {

        if (pIOReq->dwCode == IOCTL_POWER_CAPABILITIES) {

            // instantiate DiskPower object on first use, if necessary

            if (m_pDiskPower == NULL) {
                CDiskPower *pDiskPower = GetDiskPowerInterface();
                if (pDiskPower == NULL) {
                    DEBUGMSG(ZONE_WARNING, (_T(
                        "Atapi!CDisk::PerformIoctl> Failed to create power management object\r\n"
                        )));
                }
                else if (!pDiskPower->Init(this)) {
                    DEBUGMSG(ZONE_WARNING, (_T(
                        "Atapi!CDisk::PerformIoctl> Failed to initialize power management\r\n"
                        )));
                    delete pDiskPower;
                }
                else {
                    m_pDiskPower = pDiskPower;
                }
            }
        }

        if (m_pDiskPower != NULL) {

            // is this a power IOCTL? if an exception occurs, then we'll catch
            // it below
            dwError = m_pDiskPower->DiskPowerIoctl(pIOReq);
            if (dwError != ERROR_NOT_SUPPORTED) {
                goto done;
            }

            // request that the disk spin up (if it's not up already)
            if (!m_pDiskPower->RequestDevice()) {
                // the disk is powered down
                dwError = ERROR_RESOURCE_DISABLED;
                goto done;
            }
        }

        // call the driver
        dwError = MainIoctl(pIOReq);

        // indicate we're done with the disk
        if (m_pDiskPower != NULL) {
            m_pDiskPower->ReleaseDevice();
        }

done:;

    } __except(EXCEPTION_EXECUTE_HANDLER) {
        dwError = ERROR_GEN_FAILURE;
    }

    if (ZONE_CELOG) CeLogData(TRUE, CELID_ATAPI_COMPLETEIOCTL, &dwError, sizeof(dwError), 0, CELZONE_ALWAYSON, 0, FALSE);

    m_pPort->ReleaseCS();
    ReleaseCS();

    if (dwError != ERROR_SUCCESS) {
        SetLastError(dwError);
    }

    return (ERROR_SUCCESS == dwError);
}

// ----------------------------------------------------------------------------
// Function: PostInit
//     This function facilitates backward compatibility
//
// Parameters:
//     pPostInitBuf -
// ----------------------------------------------------------------------------

BOOL
CDisk::PostInit(
    PPOST_INIT_BUF pPostInitBuf
    )
{
    DWORD dwError = ERROR_SUCCESS;

    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
    )
{

    if ((pIOReq->dwInBufSize == 0) || (pIOReq->pInBuf == NULL)) {
        return ERROR_INVALID_PARAMETER;
    }

    if (pIOReq->dwInBufSize < sizeof(STORAGEDEVICEINFO)) {
        return ERROR_INSUFFICIENT_BUFFER;
    }
        
    ASSERT(m_storagedeviceinfo.cbSize == sizeof(STORAGEDEVICEINFO));

    PSTORAGEDEVICEINFO psdi = (PSTORAGEDEVICEINFO)pIOReq->pInBuf;

    *psdi = m_storagedeviceinfo;
        
    if (pIOReq->pBytesReturned) {
        *(pIOReq->pBytesReturned) = sizeof(STORAGEDEVICEINFO);
    }

    return ERROR_SUCCESS;

}

// ----------------------------------------------------------------------------
// Function: GetDeviceInfo
//     IOCTL_DISK_DEVICE_INFO
//     This function queries the registry and must be called only in the INIT
//     routines to prevent deadlocks, as this method will end up acquiring
//     the registry lock. Otherwise the registry lock, mapped file sections
//     global lock and block driver lock can possibly deadlock. Ideally mapped file
//     sections shouldn't have a global lock. m_szDeviceKey must be set before this
//     method is called
//
// Parameters:
//     PSTORAGEDEVICEINFO -
// ----------------------------------------------------------------------------

DWORD
CDisk::GetDeviceInfo(
    PSTORAGEDEVICEINFO psdi
    )
{
    HKEY hKey;

    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->dwDevic

⌨️ 快捷键说明

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