📄 diskmain.cpp
字号:
CDiskPower *pDiskPower = new CDiskPower;
return pDiskPower;
}
// ----------------------------------------------------------------------------
// Function: SetDiskPowerState
// Map a power state to an ATA power management command and issue the
// command
//
// Parameters:
// newDx -
// ----------------------------------------------------------------------------
BOOL
CDisk::SetDiskPowerState(
CEDEVICE_POWER_STATE newDx
)
{
BYTE bCmd;
DEBUGMSG(ZONE_FUNC,(TEXT("CDisk: SetDiskPowerState+\r\n")));
if (ZONE_CELOG) {
DWORD dwDx = (DWORD) newDx;
CeLogData(TRUE, CELID_ATA_SETDEVICEPOWER, &dwDx, sizeof(dwDx), 0, CELZONE_ALWAYSON, 0, FALSE);
}
// on D0 go to IDLE to minimize latency during disk accesses
if(newDx == D0 || newDx == D1) {
bCmd = ATA_CMD_IDLE_IMMEDIATE;
}
else if(newDx == D2) {
bCmd = ATA_CMD_STANDBY_IMMEDIATE;
}
else if(newDx == D3 || newDx == D4) {
bCmd = ATA_CMD_SLEEP;
}
else {
DEBUGMSG(ZONE_WARNING, (_T(
"CDisk::SetDiskPowerState> Invalid power state value(%u)\r\n"
), newDx));
return FALSE;
}
DEBUGMSG(ZONE_FUNC,(TEXT("CDisk: SetDiskPowerState-\r\n")));
// update the disk power state
return SendDiskPowerCommand(bCmd);
}
// ----------------------------------------------------------------------------
// Function: WakeUp
// Wake the device up from sleep
//
// Parameters:
// None
// ----------------------------------------------------------------------------
BOOL
CDisk::WakeUp(
)
{
if (!ResetController(FALSE)) {
return FALSE;
}
return SendIdentifyDevice(IsAtapiDevice());
}
// ----------------------------------------------------------------------------
// Function: MainIoctl
// Process IOCTL_DISK_ and DISK_IOCTL_ I/O controls
//
// Parameters:
// pIOReq -
// ----------------------------------------------------------------------------
DWORD
CDisk::MainIoctl(
PIOREQ pIOReq
)
{
DWORD dwError = ERROR_SUCCESS;
DEBUGMSG(ZONE_FUNC, (TEXT("CDisk: MainIoctl+\r\n")));
#if 0
DEBUGMSG(ZONE_IOCTL, (TEXT(
"Ata!CDisk::MainIoctl> IOCTL(%x), device(%x)\r\n"
), pIOReq->dwCode, m_dwDeviceId));
#endif
// device is powering down; fail
if (m_dwDeviceFlags & DFLAGS_DEVICE_PWRDN) {
SetLastError(ERROR_DEVICE_NOT_AVAILABLE);
return FALSE;
}
switch(pIOReq->dwCode) {
case IOCTL_DISK_GETINFO:
case DISK_IOCTL_GETINFO:
DEBUGMSG(ZONE_FUNC, (TEXT("CDisk: MainIoctl:DISK_IOCTL_GETINFO\r\n")));
if (IsCDRomDevice()) {
dwError = ERROR_BAD_COMMAND;
}
else {
dwError = GetDiskInfo(pIOReq);
}
break;
case IOCTL_DISK_DEVICE_INFO:
DEBUGMSG(ZONE_FUNC, (TEXT("CDisk: MainIoctl:IOCTL_DISK_DEVICE_INFO\r\n")));
dwError = GetDeviceInfo(pIOReq);
break;
case DISK_IOCTL_GETNAME:
case IOCTL_DISK_GETNAME:
DEBUGMSG(ZONE_FUNC, (TEXT("CDisk: MainIoctl:IOCTL_DISK_GETNAME\r\n")));
dwError = GetDiskName(pIOReq);
break;
case DISK_IOCTL_SETINFO:
case IOCTL_DISK_SETINFO:
DEBUGMSG(ZONE_FUNC, (TEXT("CDisk: MainIoctl:IOCTL_DISK_SETINFO\r\n")));
dwError = SetDiskInfo(pIOReq);
break;
case DISK_IOCTL_READ:
case IOCTL_DISK_READ:
DEBUGMSG(ZONE_FUNC, (TEXT("CDisk: MainIoctl:IOCTL_DISK_READ\r\n")));
if (!ValidateSg((PSG_REQ)pIOReq->pInBuf,pIOReq->dwInBufSize)) {
dwError = ERROR_INVALID_PARAMETER;
}
else {
if (IsDMASupported()) {
dwError = ReadWriteDiskDMA(pIOReq, TRUE);
}
else {
dwError = ReadWriteDisk(pIOReq, TRUE);
}
}
break;
case DISK_IOCTL_WRITE:
case IOCTL_DISK_WRITE:
DEBUGMSG(ZONE_FUNC, (TEXT("CDisk: MainIoctl:IOCTL_DISK_WRITE\r\n")));
if (!ValidateSg((PSG_REQ)pIOReq->pInBuf,pIOReq->dwInBufSize)) {
dwError=ERROR_INVALID_PARAMETER;
}
else {
if (IsDMASupported()) {
dwError = ReadWriteDiskDMA(pIOReq, FALSE);
}
else {
dwError = ReadWriteDisk(pIOReq, FALSE);
}
}
break;
case IOCTL_DISK_GET_STORAGEID:
DEBUGMSG(ZONE_FUNC, (TEXT("CDisk: MainIoctl:IOCTL_DISK_GET_STORAGEID\r\n")));
dwError = GetStorageId(pIOReq);
break;
case DISK_IOCTL_FORMAT_MEDIA:
case IOCTL_DISK_FORMAT_MEDIA:
DEBUGMSG(ZONE_FUNC, (TEXT("CDisk: MainIoctl:IOCTL_DISK_FORMAT_MEDIA\r\n")));
dwError = ERROR_SUCCESS;
break;;
case IOCTL_DISK_FLUSH_CACHE:
DEBUGMSG(ZONE_FUNC, (TEXT("CDisk: MainIoctl:IOCTL_DISK_FLUSH_CACHE\r\n")));
dwError = FlushCache();
break;
default:
dwError = ERROR_NOT_SUPPORTED;
break;
}
DEBUGMSG(ZONE_FUNC, (TEXT("CDisk: MainIoctl-\r\n")));
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_FUNC, (TEXT("CDisk: PerformIoctl+\r\n")));
#if 0
DEBUGMSG(ZONE_IOCTL, (TEXT(
"Ata!CDisk::PerformIoctl> IOCTL(%x), device(%x)\r\n"
), pIOReq->dwCode, m_dwDeviceId));
#endif
if (pIOReq->pBytesReturned) {
*(pIOReq->pBytesReturned) = 0;
}
TakeCS();
m_pPort->TakeCS();
if (ZONE_CELOG) CeLogData(TRUE, CELID_ATA_STARTIOCTL, pIOReq, sizeof(*pIOReq), 0, CELZONE_ALWAYSON, 0, FALSE);
__try {
if (pIOReq->dwCode == IOCTL_POWER_CAPABILITIES) {
DEBUGMSG(ZONE_FUNC,(TEXT("CDisk: PerformIoctl:IOCTL_POWER_CAPABILITIES\r\n")));
// instantiate DiskPower object on first use, if necessary
if (m_pDiskPower == NULL) {
CDiskPower *pDiskPower = GetDiskPowerInterface();
if (pDiskPower == NULL) {
DEBUGMSG(ZONE_WARNING, (_T(
"Ata!CDisk::PerformIoctl> Failed to create power management object\r\n"
)));
}
else if (!pDiskPower->Init(this)) {
DEBUGMSG(ZONE_WARNING, (_T(
"Ata!CDisk::PerformIoctl> Failed to initialize power management\r\n"
)));
delete pDiskPower;
}
else {
m_pDiskPower = pDiskPower;
}
}
}
if (m_pDiskPower != NULL) {
// is this a power IOCTL?
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_ATA_COMPLETEIOCTL, &dwError, sizeof(dwError), 0, CELZONE_ALWAYSON, 0, FALSE);
m_pPort->ReleaseCS();
ReleaseCS();
if (dwError != ERROR_SUCCESS) {
SetLastError(dwError);
}
DEBUGMSG(ZONE_FUNC, (TEXT("CDisk: PerformIoctl-\r\n")));
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("Ata!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;
DEBUGMSG(ZONE_FUNC, (TEXT("CDisk: GetDiskInfo+\r\n")));
// 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(
"Ata!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 {
if (0 == CeSafeCopyMemory((LPVOID)pInfo, (LPVOID)&m_DiskInfo, sizeof(DISK_INFO))) {
return ERROR_INVALID_PARAMETER;
}
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;
}
}
DEBUGMSG(ZONE_FUNC, (TEXT("CDisk: GetDiskInfo-\r\n")));
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;
DEBUGMSG(ZONE_FUNC, (TEXT("CDisk: SetDiskInfo+\r\n")));
if ((pIOReq->pInBuf == NULL) || (pIOReq->dwInBufSize != sizeof(DISK_INFO))) {
return ERROR_INVALID_PARAMETER;
}
if (0 == CeSafeCopyMemory((LPVOID)&m_DiskInfo, (LPVOID)pInfo, sizeof(DISK_INFO))) {
return ERROR_INVALID_PARAMETER;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -