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

📄 cd.c

📁 s3c2440在wince4.2下的SDK,实时操作系统用
💻 C
字号:
//
// 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.
//
/*++

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.

Module Name:

    cd.c

Abstract:

    bInterfaceSubClass = 0x02 : SFF8020i (ATAPI) CD-ROM

--*/

#include <ntcompat.h>
#include <pkfuncs.h>

#include "usbmsc.h"
#include "scsi2.h"

DWORD
ScsiCDRead(
    PSCSI_DEVICE pDevice,
    PCDROM_READ  pReadInfo,
    PULONG       pdwBytesTransferred
    )
{
    DWORD   dwErr, i;
    DWORD   dwBytesTransferred = 0;
    UCHAR   RequestBuffer[sizeof(SG_REQ) + (sizeof(SG_BUF)*(MAX_SG_BUF-1))] = {0};
    PSG_REQ pSgReq = (PSG_REQ)RequestBuffer;

    DEBUGMSG(ZONE_CDROM,(TEXT("USBMSC>ScsiCDRead\n")));

    if ( !pReadInfo || !pdwBytesTransferred ||
         !pReadInfo->TransferLength ||
         !pReadInfo->sgcount || pReadInfo->sgcount > MAX_SG_BUF)
    {
        TEST_TRAP();   
        return ERROR_INVALID_PARAMETER;
    } 

    // TrackMode is TBD
    if ( CDDA == pReadInfo->TrackMode ||
         pReadInfo->StartAddr.Mode != CDROM_ADDR_LBA || // TODO: convert address
         pReadInfo->bRawMode ) 
    {
        TEST_TRAP();
        return ERROR_NOT_SUPPORTED;
    }

    // Convert CDROM_READ to SG_REQ
    pSgReq->sr_start    = pReadInfo->StartAddr.Address.lba;
    pSgReq->sr_num_sec  = pReadInfo->TransferLength;
    pSgReq->sr_num_sg   = pReadInfo->sgcount;
    for (i = 0; i < pSgReq->sr_num_sg; i++) {
        pSgReq->sr_sglist[i].sb_buf = pReadInfo->sglist[i].sb_buf;
        pSgReq->sr_sglist[i].sb_len = pReadInfo->sglist[i].sb_len;
    }

    *pdwBytesTransferred = ScsiRWSG(pDevice, pSgReq, pDevice->Lun, TRUE);

    dwErr = pSgReq->sr_status;

    DEBUGMSG(ZONE_CDROM,(TEXT("USBMSC<ScsiCDRead:%d\n"),dwErr));
    
    return dwErr;
}


DWORD 
ScsiCDAudio(
    PSCSI_DEVICE pDevice,
    DWORD        Ioctl,
    PUCHAR       pInBuf,
    DWORD        InBufLen,
    PUCHAR       pOutBuf,
    DWORD        OutBufLen,
    PDWORD       pdwBytesTransferred
    )
{
    TRANSPORT_COMMAND tCommand = {0};
    TRANSPORT_DATA    tData = {0};
    UCHAR             bCDB[MAX_CDB];
    
    DWORD dwErr;
    
    DEBUGMSG(ZONE_CDROM,(TEXT("USBDISK6>ScsiCDAudio\n")));

    dwErr = AcquireRemoveLock(&pDevice->RemoveLock, NULL);
    if ( ERROR_SUCCESS != dwErr) {
        return dwErr;
    }

    tCommand.Flags   = DATA_OUT;
    tCommand.Timeout = pDevice->Timeouts.ScsiCommandTimeout;
    tCommand.Length  = USBMSC_SUBCLASS_SCSI == pDevice->DiskSubClass ?
                       SCSI_CDB_6 : UFI_CDB;
    tCommand.CommandBlock = bCDB;

    memset( bCDB, 0, sizeof(bCDB));
    ASSERT(pDevice->Lun <= 0x7);
    bCDB[1] = ((pDevice->Lun & 0x7) << 5);

    switch(Ioctl) 
    {
        case IOCTL_CDROM_READ_TOC: 
        {
            DEBUGMSG(ZONE_CDROM, (TEXT("IOCTL_CDROM_READ_TOC\n")));

            if ( !pOutBuf || OutBufLen < sizeof(CDROM_TOC) ) 
            {
                dwErr = ERROR_INVALID_PARAMETER;

            } else {
                tCommand.Flags = DATA_IN;

                tData.TransferLength = 0;
                tData.RequestLength = OutBufLen;
                tData.DataBlock = pOutBuf;
                
                bCDB[0] = SCSI_CD_READ_TOC;
                bCDB[1] |= 0x2; // use MSF format
                //bCDB[6] = 0;  // starting track
                bCDB[7] = (BYTE)((sizeof(CDROM_TOC)>> 8) &0x0FF);    //3
                bCDB[7] = (BYTE)(sizeof(CDROM_TOC) &0x0FF);          // 24
            }
        
        } break;


        case IOCTL_CDROM_PLAY_AUDIO:
            {
                PCDROM_READ    pCdRead;

                DEBUGMSG(ZONE_CDROM, (TEXT("IOCTL_CDROM_PLAY_AUDIO\n")));

                if (!pInBuf || InBufLen < sizeof(CDROM_READ)) {
                    dwErr = ERROR_INVALID_PARAMETER;
                } else {
                    pCdRead = (PCDROM_READ)pInBuf;

                    bCDB[0] = SCSI_CD_PLAY10;

                    ASSERT(pCdRead->StartAddr.Mode == CDROM_ADDR_LBA);
                    
                    // Logical Block Address
                    SetDWORD( &bCDB[2], pCdRead->StartAddr.Address.lba);

                    // TransferLength (in sectors)
                    SetWORD( &bCDB[7], (WORD)pCdRead->TransferLength);
                }
            }    
            break;

        case IOCTL_CDROM_PLAY_AUDIO_MSF:
            {
                PCDROM_PLAY_AUDIO_MSF    pPlayMSF;

                DEBUGMSG(ZONE_CDROM, (TEXT("IOCTL_CDROM_PLAY_AUDIO_MSF\n")));

                if (!pInBuf || InBufLen < sizeof(CDROM_PLAY_AUDIO_MSF)) {
                    dwErr = ERROR_INVALID_PARAMETER;
                } else {
                    pPlayMSF = (PCDROM_PLAY_AUDIO_MSF)pInBuf;
                    bCDB[0] = SCSI_CD_PLAY_MSF;
                    bCDB[3] = pPlayMSF->StartingM;
                    bCDB[4] = pPlayMSF->StartingS;
                    bCDB[5] = pPlayMSF->StartingF;
                    bCDB[6] = pPlayMSF->EndingM;
                    bCDB[7] = pPlayMSF->EndingS;
                    bCDB[8] = pPlayMSF->EndingF;
                }
            }    
            break;

        case IOCTL_CDROM_SEEK_AUDIO_MSF:
            DEBUGMSG(ZONE_ERR,(TEXT("IOCTL_CDROM_SEEK_AUDIO_MSF\n")));
            dwErr = ERROR_NOT_SUPPORTED;
            break;

        case IOCTL_CDROM_STOP_AUDIO:
            DEBUGMSG(ZONE_CDROM,(TEXT("IOCTL_CDROM_STOP_AUDIO\n")));
            bCDB[0] = SCSI_CD_STOP;
            break;

        case IOCTL_CDROM_PAUSE_AUDIO:
            DEBUGMSG(ZONE_CDROM,(TEXT("IOCTL_CDROM_PAUSE_AUDIO\n")));
            bCDB[0] = SCSI_CD_PAUSE_RESUME;
            bCDB[8] = 0;
            break;

        case IOCTL_CDROM_RESUME_AUDIO:
            DEBUGMSG(ZONE_CDROM,(TEXT("IOCTL_CDROM_RESUME_AUDIO\n")));
            bCDB[0] = SCSI_CD_PAUSE_RESUME;
            bCDB[8] = 1;
            break;

        default:
            DEBUGMSG(ZONE_ERR,(TEXT("Unhandeled CDDA Command: 0x%x\n"), Ioctl));
            dwErr = ERROR_NOT_SUPPORTED;
            break;
    }
    
    if (ERROR_SUCCESS == dwErr) 
    {
        dwErr = UsbsDataTransfer(pDevice->hUsbTransport,
                                 &tCommand,
                                 &tData );

        if ( dwErr != ERROR_SUCCESS ) {

            dwErr = ScsiGetSenseData( pDevice, pDevice->Lun );

            DEBUGMSG(ZONE_ERR,(TEXT("ScsiCDAudio ERROR:%d\n"), dwErr));

            SetLastError(dwErr);

        } else {
            //        
            // handle any post command processing here ...
            //
        }

        if (pdwBytesTransferred) {
            *pdwBytesTransferred = tData.TransferLength;
        }
    }

    ReleaseRemoveLock(&pDevice->RemoveLock, NULL);
    
    DEBUGMSG(ZONE_CDROM,(TEXT("USBDISK6<ScsiCDAudio:%d\n"), dwErr));

    return dwErr;
}

// EOF

⌨️ 快捷键说明

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