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

📄 disk.c

📁 s3c2440在wince4.2下的SDK,实时操作系统用
💻 C
📖 第 1 页 / 共 4 页
字号:
    DWORD  dwErr  = ERROR_SUCCESS;
    PUCHAR pBuf = NULL;
    DWORD  dwBufLen = 0;

    DEBUGMSG(ZONE_DSK_IOCTL,(TEXT("USBDISK6>DSK_IOControl(IOCTL:0x%x, InBuf:0x%x, InBufLen:%d, OutBuf:0x%x, OutBufLen:0x%x)\n"),
                                    Ioctl, pInBuf, InBufLen, pOutBuf, OutBufLen ));

    if ( ACCEPT_IO(pDevice) ) 
    {
        EnterCriticalSection(&pDevice->Lock);

        switch (Ioctl) 
        {       		
            case IOCTL_DISK_GETINFO: // new ioctls
                pBuf = pOutBuf;
                dwBufLen = OutBufLen;
                break;
            
            case DISK_IOCTL_GETINFO: // old ioctls
                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 {
                    RETAILMSG( 1, (L"Not loading a UpperDriver since partition manager exists"));
                }    
                break;
            case IOCTL_DISK_DEVICE_INFO:
                if ((InBufLen== 0) || (pInBuf== NULL))
                {
                    dwErr = ERROR_INVALID_PARAMETER;
                    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 {
                    //
                    // if we already have valid disk info then use it
                    //
                    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 {
                        //
                        // query the device for it
                        //
                        DWORD dwBytesTransferred;
                        dwBytesTransferred = GetDiskInfo( pDevice, (PDISK_INFO)pBuf, pDevice->Lun);
                
                        if ( dwSize == dwBytesTransferred) {
                            // See the comments in MountUpperDriver.
                            pDevice->Flags.FSDMounted = TRUE;
                            pDevice->Flags.MediumChanged=FALSE;
                            bRc = TRUE;
                        }
                        else
                            if (pDevice->Flags.MediumPresent==FALSE) {
                                dwErr = ERROR_INVALID_PARAMETER;
                                DEBUGMSG(ZONE_ERR,(TEXT("IOCTL_GET_INFO: Desk is Not Present\r\n")));
                            }
                        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 {
                        
                        dwErr = ScsiUnitAttention(pDevice, pDevice->Lun);
                        if (ERROR_SUCCESS == dwErr) 
                        {
                            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);
                            }
                        }
                        else 
                            if (pDevice->Flags.MediumPresent==FALSE) {
                                dwErr = ERROR_INVALID_PARAMETER;
                                DEBUGMSG(ZONE_ERR,(TEXT("IOCTL_READ_WRITE: Desk is Not Present\r\n")));
                            }
                    }
                }
            }
            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)
                                    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:

⌨️ 快捷键说明

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