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

📄 cdio.cpp

📁 CIRRUS 93XX系列windows mobile 6.0 BSP
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//**********************************************************************
//                                                                      
// Filename: cdio.cpp
//                                                                      
// Description: 
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Use of this source code is subject to the terms of the Cirrus end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to 
// use this source code. For a copy of the EULA, please see the 
// EULA.RTF on your install media.
//
// Copyright(c) Cirrus Logic Corporation 2005, All Rights Reserved
//                                                                      
//**********************************************************************
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
//**********************************************************************


#include <atamain.h>
#include <CEDDK.h>
#include <oalintr.h>
#include <hwdefs.h>
#include <dbgapi.h>
/*
#define DEBUG 
#undef DEBUGMSG
#define DEBUGMSG  RETAILMSG

#define ZONE_IOCTL 1
#define ZONE_IO         1
#define ZONE_ERROR 1 
#define ZONE_CDROM 1
#define ZONE_DMA       1

*/
DWORD CDisk::AtapiIoctl(PIOREQ pIOReq)
{
    DWORD dwError = ERROR_SUCCESS;
    DWORD dwBytesReturned = 0;
    BOOL fUserMode = ::GetDirectCallerProcessId() != ::GetCurrentProcessId();
    BOOL fIsDVD = FALSE;
    DEBUGMSG( ZONE_IOCTL, (TEXT("ATAPI:PerformIoctl: %x DeviceId: %x \r\n"),pIOReq->dwCode, m_dwDeviceId));

    switch( pIOReq->dwCode) 
    {
        case IOCTL_SCSI_PASS_THROUGH:
        {
            SCSI_PASS_THROUGH PassThrough = { 0 };
            SENSE_DATA SenseData = { 0 };
            PSENSE_DATA pSenseData = NULL;
            DWORD dwSenseSize = 0;
            BOOL fDataIn = FALSE;
            SGX_BUF SgxBuf = { 0 };
            
            //
            // Validate buffers.
            //
            if( NULL == pIOReq->pInBuf ) 
            {
                dwError = ERROR_INVALID_PARAMETER;
                break;
            }
            
            if( pIOReq->dwInBufSize < sizeof(SCSI_PASS_THROUGH) )
            {
                dwError = ERROR_INVALID_PARAMETER;
                break;
            }
            
            //
            // The pass through buffer could be changed at any time and we need
            // to make sure that we don't puke if this happens.
            //
            if( !CeSafeCopyMemory( &PassThrough, 
                                   pIOReq->pInBuf, 
                                   sizeof(SCSI_PASS_THROUGH) ) )
            {
                dwError = ERROR_INVALID_PARAMETER;
                break;
            }

            SgxBuf.sb_buf = pIOReq->pInBuf + PassThrough.DataBufferOffset;
            SgxBuf.sb_len = PassThrough.DataTransferLength;

            fDataIn = PassThrough.DataIn != 0;

            //
            // The Test Unit Ready commmand is neither data in/out and will
            // have a size of zero.  So allow zero length data in.
            //
//            if( fDataIn && SgxBuf.sb_len == 0 )
//            {
//                dwError = ERROR_INVALID_PARAMETER;
//                break;
//           }

            //
            // Validate that the data buffer looks correct.
            //
            if( PassThrough.DataTransferLength &&
                PassThrough.DataBufferOffset < sizeof(SCSI_PASS_THROUGH) )
            {
                dwError = ERROR_INVALID_PARAMETER;
                break;
            }

            if( PassThrough.DataTransferLength > 
                pIOReq->dwInBufSize - sizeof(SCSI_PASS_THROUGH) )
            {
                dwError = ERROR_INVALID_PARAMETER;
                break;
            }

            if( pIOReq->dwInBufSize - PassThrough.DataTransferLength <
                PassThrough.DataBufferOffset )
            {
                dwError = ERROR_INVALID_PARAMETER;
                break;
            }
            
            //
            // Validate that the sense buffer and the data buffer don't
            // overlap.
            //
            if( PassThrough.DataBufferOffset < PassThrough.SenseInfoOffset &&
                PassThrough.DataBufferOffset + PassThrough.DataTransferLength > PassThrough.SenseInfoOffset )
            {
                dwError = ERROR_INVALID_PARAMETER;
                break;
            }

            if( PassThrough.SenseInfoOffset < PassThrough.DataBufferOffset &&
                PassThrough.SenseInfoOffset + PassThrough.SenseInfoLength > PassThrough.DataBufferOffset )
            {
                dwError = ERROR_INVALID_PARAMETER;
                break;
            }

            if( PassThrough.SenseInfoOffset == PassThrough.DataBufferOffset &&
                PassThrough.SenseInfoOffset != 0  &&
                PassThrough.DataTransferLength != 0 )
            {
                dwError = ERROR_INVALID_PARAMETER;
                break;
            }

            if( pIOReq->dwInBufSize - 
                sizeof(SCSI_PASS_THROUGH) - 
                PassThrough.DataTransferLength < 
                PassThrough.SenseInfoLength )
            {
                dwError = ERROR_INVALID_PARAMETER;
                break;
            }

            if( PassThrough.SenseInfoLength &&
                PassThrough.SenseInfoOffset < sizeof(SCSI_PASS_THROUGH) )
            {
                dwError = ERROR_INVALID_PARAMETER;
                break;
            }

            //
            // Determine the size of the sense info to return.
            //
            dwSenseSize = PassThrough.SenseInfoLength;
            if( pIOReq->dwInBufSize - sizeof(SCSI_PASS_THROUGH) < dwSenseSize )
            {
                dwError = ERROR_INVALID_PARAMETER;
                break;
            }

            pSenseData = (PSENSE_DATA)(pIOReq->pInBuf + PassThrough.SenseInfoOffset);

            if (FALSE == AtapiIsUnitReadyEx()) {
                dwError = ERROR_NOT_READY;

                //
                // We need to let the Load medium pass through, as well as
                // GET CONFIGURATION.
                //
                if( ((PassThrough.Cdb[0] != SCSIOP_START_STOP_UNIT) ||
                     (PassThrough.Cdb[4] & 1 ) == 0 ) &&
                    (PassThrough.Cdb[0] != SCSIOP_GET_CONFIGURATION) )
                {
                    if( dwSenseSize && AtapiGetSenseInfo( &SenseData ) )
                    {
                        CeSafeCopyMemory( pSenseData, &SenseData, dwSenseSize );
                    }

                    break;
                }
            }

            dwError = ScsiPassThrough( PassThrough, 
                                       &SgxBuf, 
                                       &SenseData, 
                                       &dwBytesReturned,
                                       SgxBuf.sb_len == 0 );
            if( dwError != ERROR_SUCCESS )
            {
                if( dwSenseSize )
                {
                    CeSafeCopyMemory( pSenseData, &SenseData, dwSenseSize );
                }
            }

            CeSafeCopyMemory( pIOReq->pBytesReturned, &dwBytesReturned, sizeof(dwBytesReturned) );
            break;
        }
        case IOCTL_SCSI_PASS_THROUGH_DIRECT:
        {
            PSCSI_PASS_THROUGH_DIRECT pPassThroughDirect = NULL;
            PSENSE_DATA pSenseData = NULL;
            DWORD dwSenseSize = 0;
            SENSE_DATA SenseData = { 0 };
            SGX_BUF SgxBuf = { 0 };
            BOOL fDataIn = FALSE;

            //
            // Validate buffers.
            //
            if( NULL == pIOReq->pInBuf ) 
            {
                dwError = ERROR_INVALID_PARAMETER;
                break;
            }
            
            if( pIOReq->dwInBufSize < sizeof(SCSI_PASS_THROUGH_DIRECT) )
            {
                dwError = ERROR_INVALID_PARAMETER;
                break;
            }

            pPassThroughDirect = (PSCSI_PASS_THROUGH_DIRECT)pIOReq->pInBuf;

            //
            // The pass through buffer could be changed at any time and we need
            // to make sure that we don't puke if this happens.
            //
            __try
            {
                SgxBuf.sb_buf = (PUCHAR)pPassThroughDirect->DataBuffer;
                SgxBuf.sb_len = pPassThroughDirect->DataTransferLength;

                fDataIn = pPassThroughDirect->DataIn != 0;
                
                if( fUserMode && !::IsValidUsrPtr( SgxBuf.sb_buf, 
                                                   SgxBuf.sb_len, 
                                                   fDataIn ? TRUE : FALSE ) )
                {
                    dwError = ERROR_INVALID_PARAMETER;
                    break;
                }

                dwSenseSize = pPassThroughDirect->SenseInfoLength;
                if( pIOReq->dwInBufSize - sizeof(SCSI_PASS_THROUGH_DIRECT) < dwSenseSize )
                {
                    dwError = ERROR_INVALID_PARAMETER;
                    break;
                }

                pSenseData = (PSENSE_DATA)(pIOReq->pInBuf + pPassThroughDirect->SenseInfoOffset);

                if( dwSenseSize > sizeof(SENSE_DATA) )
                {
                    dwSenseSize = sizeof(SENSE_DATA);
                }
                
                if (FALSE == AtapiIsUnitReadyEx()) {
                //
                // We need to let the Load medium pass through, as well as
                // GET CONFIGURATION.
                //
                if( ((pPassThroughDirect->Cdb[0] != SCSIOP_START_STOP_UNIT) ||
                     (pPassThroughDirect->Cdb[4] & 1 ) == 0 ) &&
                    (pPassThroughDirect->Cdb[0] != SCSIOP_GET_CONFIGURATION) )
                {
                        dwError = ERROR_NOT_READY;

                        if( dwSenseSize && AtapiGetSenseInfo( &SenseData ) )
                        {
                            CeSafeCopyMemory( pSenseData, &SenseData, dwSenseSize );
                        }

                        break;
                    }
                }

                if( !AtapiSendCommand( (PATAPI_COMMAND_PACKET)pPassThroughDirect->Cdb, 
                                        0, 
                                        FALSE ) )
                {
                    if( dwSenseSize )
                    {
                        AtapiGetSenseInfo( &SenseData );
                        CopyMemory( pSenseData, &SenseData, dwSenseSize );
                    }
                    
                    AtapiDumpSenseData();
                    dwError = ERROR_GEN_FAILURE;
                    break;
                }

                if (fDataIn)
                {
                    if( !AtapiReceiveData( &SgxBuf, 
                                           1, 
                                           &dwBytesReturned
                                            ) ) 
                    {
                        if( dwSenseSize )
                        {
                            AtapiGetSenseInfo( &SenseData );
                            CopyMemory( pSenseData, &SenseData, dwSenseSize );
                            AtapiDumpSenseData( );
                        } else {
                        
                            AtapiDumpSenseData();
                        }
                        dwError =  ERROR_GEN_FAILURE;
                        break;
                    }
                }
                else
                {
                    if( !AtapiSendData( &SgxBuf, 
                                        1, 
                                        &dwBytesReturned ) )
                    {
                        if( dwSenseSize )
                        {
                            AtapiGetSenseInfo( &SenseData );
                            CopyMemory( pSenseData, &SenseData, dwSenseSize );
                            AtapiDumpSenseData();
                        } else {
                        
                            AtapiDumpSenseData();
                        }
                        dwError =  ERROR_GEN_FAILURE;
                        break;
                    }

                }
            }
            __except( EXCEPTION_EXECUTE_HANDLER )
            {
                dwError = ERROR_INVALID_PARAMETER;
                break;
            }
            
            CeSafeCopyMemory( pIOReq->pBytesReturned, 
                              &dwBytesReturned, 
                              sizeof(dwBytesReturned) );

⌨️ 快捷键说明

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