📄 disk.c
字号:
pBuf = pInBuf;
dwBufLen = InBufLen;
break;
case IOCTL_DISK_READ: // new ioctls
case IOCTL_DISK_WRITE:
bRead = IOCTL_DISK_READ == Ioctl ? TRUE : FALSE;
break;
case DISK_IOCTL_READ: // old ioctls
case DISK_IOCTL_WRITE:
bRead = DISK_IOCTL_READ == Ioctl ? TRUE : FALSE;
break;
default:
break;
}
switch (Ioctl)
{
//
// Disk IOCTLs...
//
case IOCTL_DISK_INITIALIZED:
case DISK_IOCTL_INITIALIZED:
DEBUGMSG(ZONE_DSK_IOCTL,(TEXT("IOCTL_INITIALIZED\n")));
//
// Try to mount the FSD, which could fail if there is
// no media, etc.
//
if (!IsStorageManagerRunning() && pInBuf && InBufLen >= sizeof(PPOST_INIT_BUF)) {
MountUpperDriver(pDevice, (PPOST_INIT_BUF)pInBuf);
bRc = TRUE;
} else {
DEBUGMSG(ZONE_TRACE, (L"Usbdisk6!DSK_IOControl> Not loading FSD, Storage Manager exists\r\n"));
}
break;
case IOCTL_DISK_DEVICE_INFO:
if ((InBufLen== 0) || (pInBuf== NULL))
{
dwErr = ERROR_INVALID_PARAMETER;
LeaveCriticalSection(&pDevice->Lock);
return FALSE;
} else {
dwErr = GetDeviceInfo(pDevice, (STORAGEDEVICEINFO *)pInBuf);
if (dwErr == ERROR_SUCCESS) {
if (pdwBytesTransferred)
*(pdwBytesTransferred) = sizeof(STORAGEDEVICEINFO);
bRc = TRUE;
}
}
break;
case IOCTL_DISK_GETINFO:
case DISK_IOCTL_GETINFO:
{
DWORD dwSize = sizeof(DISK_INFO);
DEBUGMSG(ZONE_DSK_IOCTL,(TEXT("IOCTL_GETINFO\n")));
if ( !pBuf || dwBufLen < dwSize ) {
dwErr = ERROR_INVALID_PARAMETER;
} else {
// return cached disk geometry, if possible, otherwise,
// query device
if (pDevice->Flags.MediumPresent &&
0 != pDevice->DiskInfo.di_total_sectors &&
0 != pDevice->DiskInfo.di_bytes_per_sect)
{
memcpy(pBuf, &pDevice->DiskInfo, dwSize);
if (pdwBytesTransferred) {
*pdwBytesTransferred = dwSize;
}
bRc = TRUE;
}
else {
DWORD dwBytesTransferred;
dwBytesTransferred = GetDiskInfo(pDevice, (PDISK_INFO)pBuf, pDevice->Lun);
if (0 == dwBytesTransferred) {
// We failed to fetch the medium's device info. A device
// may not be attached or may not contain media.
DEBUGMSG(ZONE_ERR, (TEXT("USBDISK6>DSK_IOControl> A device is not attached or does not contain media\r\n")));
// Reset our cached copy of the device's disk info.
memset((PVOID)&pDevice->DiskInfo, sizeof(DISK_INFO), 0);
// let the caller know by returning the zeroed DiskInfo
memset((PVOID)pBuf, sizeof(DISK_INFO), 0);
bRc = TRUE;
}
else {
if (dwSize == dwBytesTransferred) {
// the device returned geometry data, thus, a medium
// is present
pDevice->Flags.FSDMounted = TRUE;
pDevice->Flags.MediumChanged = FALSE;
bRc = TRUE;
}
else {
if (pDevice->Flags.MediumPresent == FALSE) {
DEBUGMSG(ZONE_ERR, (TEXT(
"Usbdisk6!DSK_IOControl> IOCTL_GET_INFO; media not present\r\n"
)));
memset((PVOID)&pDevice->DiskInfo, sizeof(DISK_INFO), 0);
memcpy((PVOID)pBuf, (PVOID)&pDevice->DiskInfo, sizeof(DISK_INFO));
bRc = TRUE;
}
}
}
if (pdwBytesTransferred) {
*pdwBytesTransferred = dwBytesTransferred;
}
}
}
}
break;
case IOCTL_DISK_SETINFO:
case DISK_IOCTL_SETINFO:
{
DWORD dwSize = sizeof(DISK_INFO);
DEBUGMSG(ZONE_DSK_IOCTL,(TEXT("IOCTL_SETINFO\n")));
if ( !pInBuf || InBufLen < dwSize ) {
dwErr = ERROR_INVALID_PARAMETER;
} else {
if ( 0 != memcmp(&pDevice->DiskInfo, pInBuf, dwSize) ) {
//
// There is a descrepency in the disk information that
// was provided to the file system
//
PDISK_INFO pDiskInfo = (PDISK_INFO)pInBuf;
if (pDiskInfo->di_total_sectors && pDiskInfo->di_bytes_per_sect) {
memcpy( &pDevice->DiskInfo, pDiskInfo, dwSize);
if (pdwBytesTransferred)
*pdwBytesTransferred = dwSize;
}
}
ASSERT( 0 != pDevice->DiskInfo.di_total_sectors );
ASSERT( 0 != pDevice->DiskInfo.di_bytes_per_sect );
bRc = TRUE;
}
}
break;
case IOCTL_DISK_READ:
case IOCTL_DISK_WRITE:
case DISK_IOCTL_READ:
case DISK_IOCTL_WRITE:
{
PSG_REQ pSgReq = (PSG_REQ)pInBuf;
DEBUGMSG(ZONE_DSK_IOCTL, (bRead ? TEXT("IOCTL_READ\n"):TEXT("IOCTL_WRITE\n")));
if ( !pSgReq ||
InBufLen < (sizeof(SG_REQ) + sizeof(SG_BUF) * (pSgReq->sr_num_sg - 1)))
{
TEST_TRAP();
dwErr = ERROR_INVALID_PARAMETER;
} else {
// Check caller buffer access
if (PSLGetCallerTrust() != OEM_CERTIFY_TRUST) {
DWORD dwIndex;
for (dwIndex=0; dwIndex < pSgReq -> sr_num_sg; dwIndex++) {
pSgReq->sr_sglist[dwIndex].sb_buf =
MapCallerPtr((LPVOID)pSgReq->sr_sglist[dwIndex].sb_buf,pSgReq->sr_sglist[dwIndex].sb_len);
}
}
if (!bRead && pDevice->Flags.WriteProtect) {
DEBUGMSG(ZONE_ERR,(TEXT("ERROR_WRITE_PROTECT\n")));
TEST_TRAP();
dwErr = ERROR_WRITE_PROTECT;
bRc = FALSE;
} else {
pDevice->Flags.MediumChanged=FALSE;
{
DWORD dwBytesTransferred= ScsiRWSG(pDevice, pSgReq, pDevice->Lun, bRead);
if (pdwBytesTransferred)
*pdwBytesTransferred=dwBytesTransferred;
dwErr = pSgReq->sr_status;
bRc = (ERROR_SUCCESS == pSgReq->sr_status);
}
}
}
}
break;
case IOCTL_DISK_FORMAT_MEDIA:
case DISK_IOCTL_FORMAT_MEDIA:
DEBUGMSG(ZONE_DSK_IOCTL,(TEXT("!! CodeMe : IOCTL_FORMAT_MEDIA !!\n")));
bRc = TRUE;
break;
case IOCTL_DISK_GETNAME:
case DISK_IOCTL_GETNAME:
DEBUGMSG(ZONE_DSK_IOCTL,(TEXT("IOCTL_GETNAME\n")));
if (pOutBuf == NULL) {
dwErr = ERROR_INVALID_PARAMETER;
bRc = FALSE;
} else {
WCHAR buff[] = DEFAULT_FOLDER_SZ;
memcpy( pOutBuf, buff, sizeof(DEFAULT_FOLDER_SZ) );
if (pdwBytesTransferred)
*pdwBytesTransferred = sizeof(DEFAULT_FOLDER_SZ)+2;
bRc = TRUE;
}
break;
//
// SCSI Passthrough...
//
case IOCTL_SCSI_PASSTHROUGH:
DEBUGMSG(ZONE_DSK_IOCTL,(TEXT("IOCTL_SCSI_PASSTHROUGH\n")));
if ( !pInBuf || InBufLen < sizeof(TRANSPORT_COMMAND) ||
!pOutBuf || OutBufLen < sizeof(TRANSPORT_DATA))
{
dwErr = ERROR_INVALID_PARAMETER;
} else {
dwErr = ScsiPassthrough(pDevice, (PTRANSPORT_COMMAND)pInBuf, (PTRANSPORT_DATA)pOutBuf);
if (pdwBytesTransferred)
*pdwBytesTransferred = ((PTRANSPORT_DATA)(pOutBuf))->TransferLength;
bRc = TRUE;
}
break;
//
// CD-ROM
//
case IOCTL_CDROM_READ_SG:
{
PCDROM_READ pRead = (PCDROM_READ)pInBuf;
DEBUGMSG(ZONE_CDROM,(TEXT("IOCTL_CDROM_READ_SG\n")));
if ( !pRead ||
InBufLen < (sizeof(CDROM_READ) + sizeof(SGX_BUF) * (pRead->sgcount - 1)))
{
TEST_TRAP();
dwErr = ERROR_INVALID_PARAMETER;
} else if (pDevice->DeviceType != SCSI_DEVICE_CDROM) {
DEBUGMSG(ZONE_ERR,(TEXT("Device is not a CD-ROM\n")));
dwErr = ERROR_NOT_SUPPORTED;
} else if (!pDevice->Flags.Busy) {
pDevice->Flags.Busy = TRUE;
if (PSLGetCallerTrust()!= OEM_CERTIFY_TRUST) {
CDROM_READ * pCdrom=pRead;
DWORD dwIndex;
for (dwIndex=0; dwIndex < pCdrom-> sgcount; dwIndex++) {
pCdrom->sglist[dwIndex].sb_buf =
(PUCHAR)MapCallerPtr((LPVOID)pCdrom->sglist[dwIndex].sb_buf,pCdrom->sglist[dwIndex].sb_len);
}
}
dwErr = ScsiUnitAttention(pDevice, pDevice->Lun);
if (ERROR_SUCCESS == dwErr)
{
DWORD dwTransferred;
// TEMPTEMP: work around for UDFS not refreshing disk info
if (!pDevice->DiskInfo.di_bytes_per_sect ||
!pDevice->DiskInfo.di_total_sectors)
{
DISK_INFO di = {0};
dwErr = ScsiReadCapacity(pDevice, &di, pDevice->Lun);
bRc = (ERROR_SUCCESS == dwErr);
if (!bRc)
{
pDevice->Flags.Busy = FALSE;
break;
}
}
dwErr = ScsiCDRead(pDevice, pRead, &dwTransferred);
if (pdwBytesTransferred)
*pdwBytesTransferred=dwTransferred;
bRc = (ERROR_SUCCESS == dwErr);
}
pDevice->Flags.Busy = FALSE;
} else {
DEBUGMSG(ZONE_ERR,(TEXT("IOCTL_CDROM_READ_SG: ERROR_BUSY\n")));
dwErr = ERROR_BUSY;
}
}
break;
case IOCTL_CDROM_TEST_UNIT_READY:
DEBUGMSG(ZONE_CDROM,(TEXT("IOCTL_CDROM_TEST_UNIT_READY\n")));
if ( !pOutBuf || OutBufLen < sizeof(CDROM_TESTUNITREADY))
{
dwErr = ERROR_INVALID_PARAMETER;
} else if (!pDevice->Flags.Busy) {
//
// UDFS uses this IOCTL to poll the device, so we
// also test medium changed and update medium info.
//
ULONG ulPrev, ulMediumChanged;
PCDROM_TESTUNITREADY pTur;
pDevice->Flags.Busy = TRUE;
pTur = (PCDROM_TESTUNITREADY)pOutBuf;
dwErr = ScsiUnitAttention(pDevice, pDevice->Lun);
if (ERROR_SUCCESS == dwErr)
{
ulPrev = pDevice->Flags.MediumPresent;
// did it change?
ulMediumChanged = ulPrev ^ pDevice->Flags.MediumPresent;
if (ulMediumChanged && pDevice->Flags.MediumPresent)
{
DISK_INFO di = {0};
// Try to update the medium info
dwErr = ScsiReadCapacity(pDevice, &di, pDevice->Lun);
}
bRc = TRUE;
}
pTur->bUnitReady = (ERROR_SUCCESS == dwErr);
pDevice->Flags.Busy = FALSE;
} else {
DEBUGMSG(ZONE_ERR,(TEXT("IOCTL_CDROM_TEST_UNIT_READY: ERROR_BUSY\n")));
dwErr = ERROR_BUSY;
}
break;
case IOCTL_CDROM_DISC_INFO:
DEBUGMSG(ZONE_CDROM,(TEXT("IOCTL_CDROM_DISC_INFO\n")));
if ( !pOutBuf || OutBufLen < sizeof(CDROM_DISCINFO))
{
dwErr = ERROR_INVALID_PARAMETER;
} else {
PCDROM_DISCINFO pCdi = (PCDROM_DISCINFO)pOutBuf;
//
// TODO: update when when .\common\oak\drivers\block\atapi\cdio
// adds this feature.
//
bRc = TRUE;
}
break;
case IOCTL_CDROM_LOAD_MEDIA:
DEBUGMSG(ZONE_CDROM,(TEXT("IOCTL_CDROM_LOAD_MEDIA\n")));
dwErr = ScsiStartStopUnit(pDevice, START, TRUE, pDevice->Lun);
bRc = (dwErr == ERROR_SUCCESS);
break;
case IOCTL_CDROM_EJECT_MEDIA:
DEBUGMSG(ZONE_CDROM,(TEXT("IOCTL_CDROM_EJECT_MEDIA\n")));
dwErr = ScsiStartStopUnit(pDevice, STOP, TRUE, pDevice->Lun);
bRc = (dwErr == ERROR_SUCCESS);
break;
case IOCTL_CDROM_GET_SENSE_DATA:
DEBUGMSG(ZONE_CDROM,(TEXT("IOCTL_CDROM_GET_SENSE_DATA\n")));
if ( !pOutBuf || OutBufLen < sizeof(CD_SENSE_DATA) )
{
dwErr = ERROR_INVALID_PARAMETER;
} else {
// Note: this driver performs autosense,
// so the sense data returned here may or may not be as expected.
TRANSPORT_DATA tData;
tData.TransferLength = 0;
tData.RequestLength = OutBufLen;
tData.DataBlock = pOutBuf;
dwErr = ScsiRequestSense(pDevice, &tData, pDevice->Lun);
bRc = (dwErr == ERROR_SUCCESS);
if (pdwBytesTransferred)
*pdwBytesTransferred = tData.TransferLength;
} break;
//
// CD-ROM Digital Audio
//
case IOCTL_CDROM_READ_TOC:
case IOCTL_CDROM_GET_CONTROL:
case IOCTL_CDROM_PLAY_AUDIO: // Custom IOCTL
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:
{
dwErr = ScsiCDAudio(pDevice, Ioctl,
pInBuf, InBufLen,
pOutBuf, OutBufLen,
pdwBytesTransferred);
bRc = (dwErr == ERROR_SUCCESS);
}
break;
default:
DEBUGMSG(ZONE_ERR,(TEXT("Unsupported IOCTL:0x%x\n"), Ioctl));
dwErr = ERROR_NOT_SUPPORTED;
bRc = FALSE;
break;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -