?? cd.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
Notes:
CDDA not supported
--*/
#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\r\n")));
if ( !pReadInfo || !pdwBytesTransferred ||
!pReadInfo->TransferLength ||
!pReadInfo->sgcount || pReadInfo->sgcount > MAX_SG_BUF)
{
return ERROR_INVALID_PARAMETER;
}
// TrackMode is TBD
if ( CDDA == pReadInfo->TrackMode ||
pReadInfo->StartAddr.Mode != CDROM_ADDR_LBA ||
pReadInfo->bRawMode )
{
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\r\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\r\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;
tCommand.dwLun=pDevice->Lun;
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\r\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);
bCDB[8] = (BYTE)(sizeof(CDROM_TOC) &0x0FF); // 24
}
}
break;
case IOCTL_CDROM_PLAY_AUDIO:
{
PCDROM_READ pCdRead;
DEBUGMSG(ZONE_CDROM, (TEXT("IOCTL_CDROM_PLAY_AUDIO\r\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\r\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\r\n")));
dwErr = ERROR_NOT_SUPPORTED;
break;
case IOCTL_CDROM_STOP_AUDIO:
DEBUGMSG(ZONE_CDROM,(TEXT("IOCTL_CDROM_STOP_AUDIO\r\n")));
bCDB[0] = SCSI_CD_STOP;
break;
case IOCTL_CDROM_PAUSE_AUDIO:
DEBUGMSG(ZONE_CDROM,(TEXT("IOCTL_CDROM_PAUSE_AUDIO\r\n")));
bCDB[0] = SCSI_CD_PAUSE_RESUME;
bCDB[8] = 0;
break;
case IOCTL_CDROM_RESUME_AUDIO:
DEBUGMSG(ZONE_CDROM,(TEXT("IOCTL_CDROM_RESUME_AUDIO\r\n")));
bCDB[0] = SCSI_CD_PAUSE_RESUME;
bCDB[8] = 1;
break;
default:
DEBUGMSG(ZONE_ERR,(TEXT("Unsupported CDDA command(0x%x)\r\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 );
if (ERROR_SUCCESS == dwErr) {
dwErr = ERROR_GEN_FAILURE;
}
DEBUGMSG(ZONE_ERR,(TEXT("USBDISK6!ScsiCDAudio: CD-ROM command failed (%d)\r\n"), dwErr));
SetLastError(dwErr);
}
if (tData.RequestLength != tData.TransferLength) {
DEBUGMSG(ZONE_ERR,(TEXT("USBDISK6!ScsiCDAudio: Transfer length (%d) request length (%d) mismatch\r\n"), tData.TransferLength, tData.RequestLength));
dwErr = ERROR_GEN_FAILURE;
}
if (pdwBytesTransferred) {
*pdwBytesTransferred = tData.TransferLength;
}
}
ReleaseRemoveLock(&pDevice->RemoveLock, NULL);
DEBUGMSG(ZONE_CDROM,(TEXT("USBDISK6<ScsiCDAudio:%d\r\n"), dwErr));
return dwErr;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -