📄 diskmain.cpp
字号:
dwError = dwtemp;
}
}
return dwError;
}
/*------------------------------------------------------------------------------------------*/
BOOL CDisk::PerformIoctl(PIOREQ pIOReq)
{
DWORD dwError = ERROR_SUCCESS;
PUCHAR savedoldptrs[MAX_SG_BUF] ; // This will hold a copy of the user mode pointers that get overwritten
// ValidateSg
DEBUGMSG( ZONE_IOCTL, (TEXT("ATAPI:PerformIoctl: %x DeviceId: %x \r\n"),pIOReq->dwCode, m_dwDeviceId));
//* * * CAMSDB040204 - Added this for testing. (START)
//DEBUGMSG(1, (TEXT("ATAPI:PerformIoctl: %x DeviceId: %x \r\n"),pIOReq->dwCode, m_dwDeviceId));
//* * * CAMSDB040204 - Added this for testing. (END)
if (m_dwDeviceFlags & DFLAGS_DEVICE_PWRDN)
{
SetLastError(ERROR_DEVICE_NOT_AVAILABLE);
return FALSE;
}
if (pIOReq->pBytesReturned)
*(pIOReq->pBytesReturned)=0;
TakeCS();
__try {
switch( pIOReq->dwCode) {
case IOCTL_DISK_GETINFO:
case DISK_IOCTL_GETINFO:
if (IsCDRomDevice())
{
dwError = ERROR_BAD_COMMAND;
}
else
{
dwError = GetDiskInfo(pIOReq);
}
break;
case IOCTL_DISK_DEVICE_INFO:
dwError = GetDeviceInfo(pIOReq);
break;
case DISK_IOCTL_GETNAME :
case IOCTL_DISK_GETNAME :
dwError=GetDiskName(pIOReq);
break;
case DISK_IOCTL_SETINFO :
case IOCTL_DISK_SETINFO :
dwError = SetDiskInfo(pIOReq);
break;
case DISK_IOCTL_READ :
case IOCTL_DISK_READ :
if (!pIOReq->dwInBufSize || !pIOReq->pInBuf) {
dwError = ERROR_INVALID_PARAMETER;
break;
}
if (pIOReq->dwInBufSize >(sizeof(SG_REQ) + ((MAX_SG_BUF) - 1) * sizeof(SG_BUF))) {
dwError = ERROR_INVALID_PARAMETER;
// size of m_pSterileIoRequest is sizeof(SG_REQ) + ((MAX_SG_BUF) - 1) * sizeof(SG_BUF))
break;
}
if (!ValidateSg((PSG_REQ)pIOReq->pInBuf, pIOReq->dwInBufSize, ARG_O_PTR, savedoldptrs ))
{
dwError=ERROR_INVALID_PARAMETER;
break;
}
else if (IsReadDMASupported())
{
dwError = ReadWriteDiskDMA(pIOReq, TRUE);
}
else
{
dwError = ReadWriteDisk(pIOReq, TRUE);
}
//Cleanup:
if (FAILED(UnmapSg(
((PSG_REQ)(pIOReq->pInBuf))->sr_sglist,
savedoldptrs,
((PSG_REQ)(pIOReq->pInBuf))->sr_num_sg,
ARG_I_PTR)))
{
ASSERT(!"Cleanup call to CeCloseCallerBuffer failed unexpectedly");
dwError = ERROR_GEN_FAILURE;
}
break;
case DISK_IOCTL_WRITE:
case IOCTL_DISK_WRITE:
if (!pIOReq->dwInBufSize || !pIOReq->pInBuf) {
dwError = ERROR_INVALID_PARAMETER;
break;
}
if (pIOReq->dwInBufSize >(sizeof(SG_REQ) + ((MAX_SG_BUF) - 1) * sizeof(SG_BUF))) {
dwError = ERROR_INVALID_PARAMETER;
// size of m_pSterileIoRequest is sizeof(SG_REQ) + ((MAX_SG_BUF) - 1) * sizeof(SG_BUF))
break;
}
if (!ValidateSg((PSG_REQ)pIOReq->pInBuf, pIOReq->dwInBufSize, ARG_I_PTR, savedoldptrs))
{
dwError=ERROR_INVALID_PARAMETER;
break;
}
else if (IsWriteDMASupported())
{
dwError = ReadWriteDiskDMA(pIOReq, FALSE);
}
else
{
dwError = ReadWriteDisk(pIOReq, FALSE);
}
//Cleanup:
if (FAILED(UnmapSg(
((PSG_REQ)(pIOReq->pInBuf))->sr_sglist,
savedoldptrs,
((PSG_REQ)(pIOReq->pInBuf))->sr_num_sg,
ARG_I_PTR)))
{
ASSERT(!"Cleanup call to CeCloseCallerBuffer failed unexpectedly");
dwError = ERROR_GEN_FAILURE;
}
break;
case IOCTL_DISK_GET_STORAGEID: // this is a new op, so use new codes //
dwError = GetStorageId(pIOReq);
break;
case DISK_IOCTL_FORMAT_MEDIA:
case IOCTL_DISK_FORMAT_MEDIA:
dwError = ERROR_SUCCESS;
break;;
///////////////////// ATAPI /////////////////////////////////////
case IOCTL_CDROM_READ_SG:
case IOCTL_CDROM_TEST_UNIT_READY:
case IOCTL_CDROM_DISC_INFO:
case IOCTL_CDROM_EJECT_MEDIA:
case IOCTL_CDROM_LOAD_MEDIA:
///////////////////// DVD ///////////////////////////////////////
case IOCTL_DVD_START_SESSION:
case IOCTL_DVD_READ_KEY:
case IOCTL_DVD_END_SESSION:
case IOCTL_DVD_SEND_KEY:
case IOCTL_DVD_GET_REGION:
///////////////////// CDAUDIO ///////////////////////////////////
case IOCTL_CDROM_READ_TOC:
case IOCTL_CDROM_GET_CONTROL:
case IOCTL_CDROM_PLAY_AUDIO_MSF:
case IOCTL_CDROM_SEEK_AUDIO_MSF:
case IOCTL_CDROM_STOP_AUDIO:
case IOCTL_CDROM_PAUSE_AUDIO:
case IOCTL_CDROM_RESUME_AUDIO:
case IOCTL_CDROM_GET_VOLUME:
case IOCTL_CDROM_SET_VOLUME:
case IOCTL_CDROM_READ_Q_CHANNEL:
case IOCTL_CDROM_GET_LAST_SESSION:
case IOCTL_CDROM_RAW_READ:
case IOCTL_CDROM_DISK_TYPE:
case IOCTL_CDROM_SCAN_AUDIO:
case IOCTL_CDROM_ISSUE_INQUIRY:
case IOCTL_SCSI_PASS_THROUGH:
case IOCTL_SCSI_PASS_THROUGH_DIRECT:
if (IsAtapiDevice())
dwError = AtapiIoctl(pIOReq);
else
dwError = ERROR_INVALID_OPERATION;
break;
case IOCTL_DISK_USER_GET_DRIVE_STATS:
if( (pIOReq->pInBuf == NULL) && (pIOReq->dwInBufSize == 0) &&
(pIOReq->pOutBuf) && (pIOReq->dwOutBufSize == sizeof(UserDriveStatistics)))
{
dwError = GetUserDriveStatistics((UserDriveStatistics *)pIOReq->pOutBuf);
*(pIOReq->pBytesReturned) = sizeof(UserDriveStatistics);
}
break;
case IOCTL_DISK_USER_GET_DRIVE_IDENTIFY:
if( (pIOReq->pInBuf == NULL) && (pIOReq->dwInBufSize == 0) &&
(pIOReq->pOutBuf) && (pIOReq->dwOutBufSize == sizeof(IDENTIFY_DATA)))
{
dwError = GetDriveIdentifyData((IDENTIFY_DATA *)pIOReq->pOutBuf);
*(pIOReq->pBytesReturned) = sizeof(IDENTIFY_DATA);
}
break;
case IOCTL_DISK_USER_SET_TRANSFER_MODE:
if( (pIOReq->pInBuf) && (pIOReq->dwInBufSize == sizeof(UserUdmaSettings)) &&
(pIOReq->pOutBuf == NULL) && (pIOReq->dwOutBufSize == 0) )
{
UserUdmaSettings *pSettings = (UserUdmaSettings *)pIOReq->pInBuf;
dwError = ForceTransferMode(pSettings->fUDMAEnable, pSettings->ulBestUDmaModeReg);
}
break;
default:
dwError = ERROR_NOT_SUPPORTED;
break;
}
} __except(EXCEPTION_EXECUTE_HANDLER) {
dwError = ERROR_GEN_FAILURE;
}
ReleaseCS();
if (dwError != ERROR_SUCCESS)
SetLastError( dwError);
return ERROR_SUCCESS == dwError;
}
/*------------------------------------------------------------------------------------------*/
BOOL CDisk::PostInit(PPOST_INIT_BUF pPostInitBuf)
{
DWORD dwError=ERROR_SUCCESS;
DEBUGMSG( ZONEID_INIT, (TEXT("ATAPI: PostInit ( Device :0x%x) \r\n"),m_dwDeviceId));
m_hDevice = pPostInitBuf->p_hDevice;
return dwError == ERROR_SUCCESS;
}
/*------------------------------------------------------------------------------------------*/
DWORD CDisk::GetDiskInfo(PIOREQ pIOReq)
{
DWORD dwError = ERROR_SUCCESS;
DISK_INFO *pInfo = NULL;
// The Call can come in three flavors (BC). Just inbuf is specified, outbuf is specified or both. If both then outbuf is used
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, (TEXT("ATAPI:GetDiskInfo No valid input buffer or output buffer !!!\r\n")));
return ERROR_INVALID_PARAMETER;
}
if (IsRemoveableDevice()) {
}
if (IsAtapiDevice()) {
// TODO:
// 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;
}
/*------------------------------------------------------------------------------------------*/
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;
}
/*------------------------------------------------------------------------------------------*/
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;
wcscpy( psdi->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, (PTSTR *)&psdi->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_HDPROFILE, (PTSTR *)&psdi->szProfile, sizeof(psdi->szProfile))) {
wcscpy( psdi->szProfile, REG_VALUE_HDPROFILE);
}
}
return ERROR_SUCCESS;
}
/*------------------------------------------------------------------------------------------*/
DWORD CDisk::GetDiskName(PIOREQ pIOReq)
{
static PTCHAR szDefaultDiscDrive = TEXT("External Volume");
PTCHAR szDiskName = NULL;
DWORD dwSize;
DEBUGMSG( ZONE_IOCTL, (TEXT("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;
}
/*------------------------------------------------------------------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -