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

📄 block.cpp

📁 Freescale ARM11系列CPU MX31的WINCE 5.0下的BSP
💻 CPP
📖 第 1 页 / 共 4 页
字号:

    PBYTE pbCommand = (PBYTE) ptcCommand->CommandBlock;
    PBYTE pbData = (PBYTE) ptdData->DataBlock;
    DWORD dwResult = EXECUTE_FAIL;

    // don't test if LUN is valid; LUNs are deprecated

    // test if data block is large enough
    if (ptdData->RequestLength < sizeof(READ_CAPACITY_DATA)) {
        DEBUGMSG(ZONE_ERROR, (_T(
            "%s host requesting less than required; ptdData->RequestLength < %u\r\n"
            ), pszFname, sizeof(READ_CAPACITY_DATA)));
        goto EXIT;
    }

    ZeroMemory(pbData, ptdData->RequestLength);
    ptdData->TransferLength = ptdData->RequestLength;

    // pack logical block address
    PREAD_CAPACITY_DATA pReadCapacityData;
    pReadCapacityData = (PREAD_CAPACITY_DATA) pbData;
    // -1 to return last addressable
    pReadCapacityData->LastLogicalBlockAddress = ByteSwapUlong(g_diDiskInfo.di_total_sectors - 1);

    // pack block length in bytes
    pReadCapacityData->BlockLength = ByteSwapUlong(BytesPerSector());

    dwResult = EXECUTE_PASS;

EXIT:;
    return dwResult;
}

// ----------------------------------------------------------------------------
// Function: ProcessScsiStartStop
//     Process a SCSI-2 START STOP command
//
// Parameters:
//     ptcCommand - command block wrapper
// ----------------------------------------------------------------------------

static
DWORD
ProcessScsiStartStop(
    PTRANSPORT_COMMAND ptcCommand
    )
{
    SETFNAME(_T("ProcessScsiStartStop"));

    PBYTE pbCommand = (PBYTE) ptcCommand->CommandBlock;
    DWORD dwResult = EXECUTE_FAIL;

    // don't test if LUN is valid; LUNs are deprecated

    if (pbCommand[4] & 0x02) {
        // LoEj = 1
        if (pbCommand[4] & 0x01) {
            // Start = 1
            // load medium
            DEBUGMSG(ZONE_COMMENT, (_T("%s load medium\r\n"), pszFname));
        }
        else {
            // Start = 0
            // unload medium
            DEBUGMSG(ZONE_COMMENT, (_T("%s unload medium\r\n"), pszFname));
        }
    }
    else {
        // LoEj = 0
        if (pbCommand[4] & 0x01) {
            // Start = 1
            // start medium
            DEBUGMSG(ZONE_COMMENT, (_T("%s start medium\r\n"), pszFname));
        }
        else {
            // Start = 0
            // stop medium
            DEBUGMSG(ZONE_COMMENT, (_T("%s stop medium\r\n"), pszFname));
        }
    }

    dwResult = EXECUTE_PASS;
    return dwResult;
}

// ----------------------------------------------------------------------------
// Function: ProcessScsiWrite10
//     Process a SCSI-2 WRITE (10) command
//
// Parameters:
//     ptcCommand - command block wrapper
//     ptdData - data block wrapper
// ----------------------------------------------------------------------------

static
DWORD
ProcessScsiWrite10(
    PTRANSPORT_COMMAND ptcCommand,
    PTRANSPORT_DATA ptdData
    )
{
    SETFNAME(_T("ProcessScsiWrite10"));

    PBYTE pbCommand = (PBYTE) ptcCommand->CommandBlock;
    PBYTE pbData = (PBYTE) ptdData->DataBlock;
    DWORD dwLogicalBlockAddress;
    DWORD dwTransferLength;
    DWORD dwResult = EXECUTE_FAIL;

    SG_REQ sgSgReq;
    SG_BUF sgSgBuf;
    DWORD dwBytesReturned;
    BOOL fResult = FALSE;

    DWORD dwIndex;

    PUFI_CB pUfiCb = (PUFI_CB) pbCommand;
    DEBUGCHK(pUfiCb->bReserved1 == 0);

    // don't test if LUN is valid; LUNs are deprecated

    if (g_hStore==NULL||g_hStore==INVALID_HANDLE_VALUE)
        g_hStore=OpenStore(g_szDeviceName2);

    // test if logical block address is valid
    dwLogicalBlockAddress = ByteSwapUlong(pUfiCb->dwLogicalBlockAddress);
    // test if transfer length is valid
    dwTransferLength = ByteSwapUshort(pUfiCb->wTransferLength);

    DEBUGMSG(ZONE_COMMENT, (_T(
        "%s starting LBA/sector = %u, transfer length = %u (sectors)\r\n"
        ), pszFname, dwLogicalBlockAddress, dwTransferLength));

    ptdData->TransferLength = dwTransferLength * BytesPerSector();

    // is the host attempting to overwrite the virtual disk's MBR?
    if ((dwLogicalBlockAddress == 0) && (g_lpbMBR != NULL)) {
        DEBUGMSG(ZONE_COMMENT, (_T(
            "%s write request targeting virtual disk's MBR; virtual disk's MBR is write-protected\r\n"
            ), pszFname));
        dwResult = EXECUTE_FAIL;
        goto EXIT;
    }

    // if partitions being exposed selectively, then an unexposed partition
    // appears as unallocated space to the host; we want to prevent access to
    // unexposed partitions; ensure write request does not target a sector in
    // an unexposed partition

    // are partitions being exposed selectively?
    if (g_lpbMBR != NULL) {

        // cycle through bit mast of partitions selected for exposure; (0
        // denotes an unexposed partition)
        for (dwIndex = 0; dwIndex < MAX_PARTTABLE_ENTRIES; dwIndex += 1) {

            if ((g_bmPartitions & (1 << dwIndex)) == 0) {

                // this partition is unexposed

                // fetch corresponding partition table entry
                PPARTENTRY pPartEntry = (PPARTENTRY) ((g_lpbPhysMBR + PARTTABLE_OFFSET) + (dwIndex * sizeof(PARTENTRY)));

                // determine whether the current write request lies in the
                // range of the unexposed partition
                if ((dwLogicalBlockAddress >= pPartEntry->Part_StartSector) &&
                    (dwLogicalBlockAddress <= (pPartEntry->Part_StartSector + pPartEntry->Part_TotalSectors))
                ) {
                    DEBUGMSG(ZONE_COMMENT, (_T(
                        "%s write request targets unexposed partition\r\n"
                        ), pszFname));
                    dwResult = EXECUTE_FAIL;
                    goto EXIT;
                }
            }
        }
    }

    // prepare scatter/gather buffer
    sgSgBuf.sb_buf = (PBYTE) pbData;
    sgSgBuf.sb_len = ptdData->TransferLength;

    // prepare scatter/gather request
    sgSgReq.sr_start = dwLogicalBlockAddress;
    sgSgReq.sr_num_sec = dwTransferLength;
    sgSgReq.sr_status = 0;
    sgSgReq.sr_callback = NULL;
    sgSgReq.sr_num_sg = 1;
    sgSgReq.sr_sglist[0] = sgSgBuf;
    
    DWORD dwIoControlCode = (g_fLegacyBlockDriver) ? DISK_IOCTL_WRITE : IOCTL_DISK_WRITE;
    fResult = DeviceIoControl(
        g_hStore,
        dwIoControlCode,
        &sgSgReq,
        sizeof(sgSgReq),
        NULL,
        0,
        &dwBytesReturned,
        NULL);
    if (fResult) {
        DEBUGMSG(ZONE_COMMENT, (_T(
            "%s IOCTL_DISK_WRITE passed; %u bytes read\r\n"
            ), pszFname, dwBytesReturned));
    }
    else {
        DWORD dwError = GetLastError();
        RETAILMSG(1, (_T("%s IOCTL_DISK_WRITE failed; error = %u\r\n"
        ), pszFname, dwError));
        goto EXIT;
    }

    dwResult = EXECUTE_PASS;
    
EXIT:;
    return dwResult;
}

// ----------------------------------------------------------------------------
// Function: ProcessScsiPreventAllowMediumRemoval
//     Process a SCSI-2 PREVENT ALLOW MEDIUM REMOVAL command
//
// Parameters:
//     ptcCommand - command block wrapper
// ----------------------------------------------------------------------------

static
DWORD
ProcessScsiPreventAllowMediumRemoval(
    PTRANSPORT_COMMAND ptcCommand
    )
{
    SETFNAME(_T("ProcessScsiPreventAllowMediumRemoval"));

    const BYTE bPreventBit = 0x01;
    PBYTE pbCommand = (PBYTE) ptcCommand->CommandBlock;
    DWORD dwResult = EXECUTE_FAIL;

    // don't test if LUN is valid; LUNs are deprecated

    // test if prevent bit high
    if (pbCommand[4] & bPreventBit) {
        DEBUGMSG(ZONE_COMMENT, (_T("%s prevent enabled\r\n"), pszFname));
    }
    else {
        DEBUGMSG(ZONE_COMMENT, (_T("%s prevent disabled\r\n"), pszFname));
    }

    dwResult = EXECUTE_PASS;
    return dwResult;
}

// ----------------------------------------------------------------------------
// Function: ProcessScsiVerify
//     Process a SCSI-2 VERIFY command
//
// Parameters:
//     ptcCommand - command block wrapper
// ----------------------------------------------------------------------------

static
DWORD
ProcessScsiVerify(
    PTRANSPORT_COMMAND ptcCommand
    )
{
    SETFNAME(_T("ProcessScsiVerify"));

    PBYTE pbCommand = (PBYTE) ptcCommand->CommandBlock;
    DWORD dwResult = EXECUTE_FAIL;

    // don't test if LUN is valid; LUNs are deprecated

    DEBUGMSG(ZONE_COMMENT, (_T(
        "%s DPO = %u; BytChk = %u; RelAdr = %u\r\n"),
        pszFname,
        pbCommand[1] & (1 << 4), // DPO bit
        pbCommand[1] & (1 << 1), // BytChk bit
        pbCommand[1] & (1 << 0)  // RelAdr
        ));

    // fake the verification
    dwResult = EXECUTE_PASS;

    return dwResult;
}

// ----------------------------------------------------------------------------
// Function: STORE_Init
//     Initialize SCSI-2 direct-access device emulator
//
// Parameters:
//     pszContext - driver's configuration key
// ----------------------------------------------------------------------------

DWORD
STORE_Init(
    LPCTSTR pszActiveKey
    )
{
    SETFNAME(_T("STORE_Init"));

    HKEY hKey = NULL;
    DWORD cbData;
    DWORD dwError;
    DWORD dwType;
    BOOL fResult;
    DWORD dwBytesReturned;
    FUNCTION_ENTER_MSG();

    // mark self as uninitialized
    g_fInitialized = FALSE;

    // open the client driver key
    hKey = OpenDeviceKey(pszActiveKey);
    if (hKey == NULL) {
        dwError = GetLastError();
        DEBUGMSG(ZONE_ERROR, (_T(
            "%s Failed to open device key for \"%s\"; Error = %u\r\n"
            ), pszFname, pszActiveKey, dwError));
        goto EXIT;
    }

    // read name of store to expose
    cbData = sizeof(g_szDeviceName);
    dwError = RegQueryValueEx(hKey, PRX_DEVICE_NAME_VAL, NULL, &dwType, (PBYTE) g_szDeviceName, &cbData);
    if ((dwError != ERROR_SUCCESS) || (dwType != REG_SZ)) {
        DEBUGMSG(ZONE_ERROR, (_T(
            "%s Failed to read %s; error = %u\r\n"
            ), pszFname, PRX_DEVICE_NAME_VAL, dwError));
        goto EXIT;
    }
    g_szDeviceName[dim(g_szDeviceName) - 1] = 0; // force null-termination
    _tcscpy(g_szDeviceName,L"DSK1:");
    if (g_szDeviceName2[0]==0)
        _tcscpy(g_szDeviceName2,L"DSK1:");
    DEBUGMSG(ZONE_INIT, (_T(
        "%s %s = %s\r\n"
        ), pszFname, PRX_DEVICE_NAME_VAL, g_szDeviceName));

    // g_szDeviceName should be a valid stream name, e.g., "DSK1:"
    if (_tcslen(g_szDeviceName) > PRX_STREAM_NAME_LEN) {
        DEBUGMSG(ZONE_ERROR, (_T(
            "%s %s is not a valid stream name\r\n"
            ), pszFname, g_szDeviceName));
        goto EXIT;
    }

    // read removable media flag; default is true if flag not present
    cbData = sizeof(g_dwRemovable);
    dwError = RegQueryValueEx(hKey, PRX_RMB_VAL, NULL, &dwType, (PBYTE) &g_dwRemovable, &cbData);
    if ( (dwError != ERROR_SUCCESS) || (dwType != REG_DWORD) ) {
        DEBUGMSG(ZONE_WARNING, (_T(
            "%s %s not present; default is true\r\n"
            ), pszFname, PRX_RMB_VAL, dwError));
    }
    DEBUGMSG(ZONE_INIT, (_T(
        "%s %s = %u\r\n"
        ), pszFname, PRX_RMB_VAL, g_dwRemovable));

    // open store
    g_hStore = OpenStore(g_szDeviceName);
    if ((g_hStore == NULL) || (g_hStore == INVALID_HANDLE_VALUE)) {
        dwError = GetLastError();
        DEBUGMSG(ZONE_ERROR, (_T(
            "%s failed to open store %s; error = %u\r\n"
            ), pszFname, g_szDeviceName, dwError));
        goto EXIT;
    }
    DEBUGMSG(ZONE_COMMENT, (_T("%s opened store %s\r\n"), pszFname, g_szDeviceName));

    // read disk information
    fResult = DeviceIoControl(
        g_hStore,
        IOCTL_DISK_GETINFO,
        NULL,
        0,
        &g_diDiskInfo,
        sizeof(g_diDiskInfo),
        &dwBytesReturned,
        NULL);

⌨️ 快捷键说明

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