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

📄 disk.c

📁 Windows CE 5.0下的U盘驱动源代码。
💻 C
📖 第 1 页 / 共 4 页
字号:
                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 + -