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

📄 csgreq.cpp

📁 6410BSP3
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// ----------------------------------------------------------------------------
// This function sets the current position in the active buffer in the Scatter/
// Gather buffer list.
//
//   dwCurrentBufferPosition
//     [in] The 0-based index of the new position in the active buffer in the
//     Scatter/Gather buffer list.
// ----------------------------------------------------------------------------
VOID CSgReq::SetCurrentBufferPosition(DWORD dwCurrentBufferPosition)
{
    if (NULL == m_pSgReq) {
        ASSERT(NULL != m_pSgReq);
        return;
    }
    m_dwCurrentBufferPosition = dwCurrentBufferPosition;
    return;
}

// ----------------------------------------------------------------------------
// This function associates a Scatter/Gather structure with the wrapper.  This
// function also validates the Scatter/Gather structure and copies it into 
// m_rgMappedSgBufList.  If successful, return TRUE.  If
// unsuccessful, return FALSE.
//
//   pSgReq
//     [in] Pointer to Scatter/Gather structure to wrap.
// ----------------------------------------------------------------------------
BOOL CSgReq::DoAttach(PSG_REQ pSgReq, DWORD dwSectorSize)
{
    if (NULL == pSgReq) {
        ASSERT(NULL != pSgReq);
        return FALSE;
    }
    if (0 == pSgReq->sr_num_sec) {
        ASSERT(0 < pSgReq->sr_num_sec);
        return FALSE;
    }
    if ((0 == pSgReq->sr_num_sg) || (pSgReq->sr_num_sg > MAX_SG_BUF)) {
        ASSERT(0 < pSgReq->sr_num_sg);
        ASSERT(MAX_SG_BUF >= pSgReq->sr_num_sg);
        return FALSE;
    }
    if ((pSgReq->sr_num_sec * dwSectorSize) != GetSgReqLengthBySgBufList(pSgReq)) {
        ASSERT(FALSE);
        return FALSE;
    }

    // Reset mapped Scatter/Gather buffer list.
    DoResetMappedSgBufList(m_rgMappedSgBufList, MAX_SG_BUF);

    // Map pointers in caller's buffer list to mapped Scatter/Gather buffer list.
    if(FALSE == DoMapSgBufList(m_rgMappedSgBufList, MAX_SG_BUF, pSgReq->sr_sglist, pSgReq->sr_num_sg)) {
        return FALSE;
    }

    // Initialize position.
    m_pSgReq = pSgReq;
    m_dwSectorSize = dwSectorSize;
    m_dwCurrentBuffer = 0;
    m_dwCurrentBufferPosition = 0;

    return TRUE;
}

// ----------------------------------------------------------------------------
// This function activates the next buffer in the Scatter/Gather buffer list.
// That is, if buffer 0 is currently active, then after calling this function,
// buffer 1 will be active.  It is not possible to advance past the last buffer
// in the buffer list.  If successful, return TRUE.  If unsuccessful, return
// FALSE.
// ----------------------------------------------------------------------------
BOOL CSgReq::DoAdvanceBuffer()
{
    if (NULL == m_pSgReq) {
        ASSERT(NULL != m_pSgReq);
        return FALSE;
    }
    // Don't allow the caller to advance past the last buffer (i.e., we do not
    // wrap around to the first buffer).
    if ((m_dwCurrentBuffer + 1) > (m_pSgReq->sr_num_sg - 1)) {
        return FALSE;
    }
    m_dwCurrentBuffer += 1;
    m_dwCurrentBufferPosition = 0;
    return TRUE;
}

// ----------------------------------------------------------------------------
// This function advances the current buffer position by the specified number of
// bytes and updates the active buffer and current position within the active
// buffer accordingly.  It is not possible to seek past the last buffer in the
// Scatter/Gather buffer list.  Return the number of bytes the current buffer
// position advanced forward.  This value may differ from dwBytes if the caller
// attempted to seek past the last buffer in the Scatter/Gather buffer list.
//
//      dwBytes
//        [in] The number of bytes to advance.
// ----------------------------------------------------------------------------
DWORD CSgReq::DoSeek(DWORD dwBytes)
{
    DWORD dwRet = dwBytes;
    DWORD dwBytesLeftInCurrentBuffer = 0;

    if (NULL == m_pSgReq) {
        ASSERT(NULL != m_pSgReq);
        return FALSE;
    }

seek_in_current_buffer:;

    // Is the seek finished?
    if (0 == dwBytes) {
        goto exit;
    }

    // Calculate the number of bytes left in the current buffer.  We'll advance
    // one buffer at a time.
    dwBytesLeftInCurrentBuffer = GetCurrentBufferLength() - m_dwCurrentBufferPosition;

    // Given our current position and the number of bytes left to seek, will we
    // seek past the current buffer?
    if (dwBytes > dwBytesLeftInCurrentBuffer) {
        // We'll seek past the current buffer.  Advance to the next buffer.  If
        // this fails, then we'll have reached the end of the buffer list.
        dwBytes -= dwBytesLeftInCurrentBuffer;
        if (FALSE == DoAdvanceBuffer()) {
            goto exit;
        }
        // Repeat with next buffer.
        goto seek_in_current_buffer;
    }
    else {
        // We won't seek past the current buffer.  Adjust our current position
        // within the current buffer.
        m_dwCurrentBufferPosition += dwBytes;
        dwBytes = 0;
    }

exit:;

    // Return the difference between the requested number of bytes to seek and
    // the number of bytes yet to seek.  If the caller tried seeking past the
    // end of the buffer list, then the actual number of bytes we seeked past
    // will be less than the requested number of bytes to seek past.
    return (dwRet - dwBytes);
}

// ----------------------------------------------------------------------------
// This function reads the specified number of bytes from the current
// position in the active buffer in the Scatter/Gather buffer list to the
// supplied buffer.  If the read spans Scatter/Gather buffers, this function
// updates the active buffer and current position within the active buffer
// accordingly.  If successful, return TRUE.  If unsuccessful, return FALSE.
//
//   pbBuf
//     [out] The destination buffer.
//   dwBytes
//     [in] The number of bytes to read (from the current position in the
//     active buffer in the Scatter/Gather buffer list).
//   pdwBytesRead
//     [out] Pointer to DWORD in which to store the actual number of bytes
//     read.
// ----------------------------------------------------------------------------
BOOL CSgReq::DoReadMultiple(PBYTE pbBuf, DWORD dwBytes, PDWORD pdwBytesRead)
{
    DWORD dwBytesLeftInCurrentBuffer = 0;

    if (NULL == pbBuf) {
        ASSERT(NULL != pbBuf);
        return FALSE;
    }
    if (NULL == pdwBytesRead) {
        ASSERT(NULL != pdwBytesRead);
        return FALSE;
    }
    if (NULL == m_pSgReq) {
        ASSERT(NULL != m_pSgReq);
        return FALSE;
    }

    *pdwBytesRead = dwBytes;

read_from_current_buffer:;

    // Is the read finished?
    if (0 == dwBytes) {
        goto exit;
    }

    // Calculate the number of bytes left in the current buffer.  We'll advance
    // one buffer at a time.
    dwBytesLeftInCurrentBuffer = GetCurrentBufferLength() - m_dwCurrentBufferPosition;

    // Given our current position and the number of bytes left to read, will we
    // read past the current buffer?
    if (dwBytes > dwBytesLeftInCurrentBuffer) {
        // We'll read past the current buffer.  Read the contents of the current
        // buffer.
        memcpy((LPVOID)pbBuf, (LPVOID)GetCurrentBufferPositionAsPointer(), dwBytesLeftInCurrentBuffer);
        pbBuf += dwBytesLeftInCurrentBuffer;
        dwBytes -= dwBytesLeftInCurrentBuffer;
        // Advance to the next buffer.  If this fails, then we'll have reached
        // the end of the buffer list.
        if (FALSE == DoAdvanceBuffer()) {
            goto exit;
        }
        // Repeat with the next buffer.
        goto read_from_current_buffer;
    }
    else {
        // We won't read past the current buffer.  Read the required contents of
        // the current buffer.
        memcpy((LPVOID)pbBuf, (LPVOID)GetCurrentBufferPositionAsPointer(), dwBytes);
        m_dwCurrentBufferPosition += dwBytes;
        dwBytes = 0;
    }

exit:;

    // Return the difference between the requested number of bytes to read and
    // the number of bytes remaining to be read.  If the caller tried reading
    // past the end of the buffer list, then the actual number of bytes we read
    // will be less than the requested number of bytes to read.
    *pdwBytesRead -= dwBytes;
    return TRUE;
}

// ----------------------------------------------------------------------------
// This function writes the specified number of bytes from the supplied
// buffer to the current position in the active buffer in the Scatter/Gather
// buffer list.  If the write spans Scatter/Gather buffers, this function
// updates the active buffer and current position within the active buffer
// accordingly.  If successful, return TRUE.  If unsuccessful, return FALSE.
//
//   pbBuf
//     [out] The source buffer.
//   dwBytes
//     [in] The number of bytes to write (to the current position in the
//     active buffer in the Scatter/Gather buffer list).
//   pdwBytesRead
//     [out] Pointer to DWORD in which to store the actual number of bytes
//     written.
// ----------------------------------------------------------------------------
BOOL CSgReq::DoWriteMultiple(PBYTE pbBuf, DWORD dwBytes, PDWORD pdwBytesWritten)
{
    DWORD dwBytesLeftInCurrentBuffer = 0;

    if (NULL == pbBuf) {
        ASSERT(NULL != pbBuf);
        return FALSE;
    }
    if (NULL == pdwBytesWritten) {
        ASSERT(NULL != pdwBytesWritten);
        return FALSE;
    }
    if (NULL == m_pSgReq) {
        ASSERT(NULL != m_pSgReq);
        return FALSE;
    }

    *pdwBytesWritten = dwBytes;

write_to_current_buffer:;

    // Is the write finished?
    if (0 == dwBytes) {
        goto exit;
    }

    // Calculate the number of bytes left in the current buffer.  We'll advance
    // one buffer at a time.
    dwBytesLeftInCurrentBuffer = GetCurrentBufferLength() - m_dwCurrentBufferPosition;

    // Given our current position and the number of bytes left to write, will we
    // write past the current buffer?
    if (dwBytes > dwBytesLeftInCurrentBuffer) {
        // We'll write past the current buffer.  Write the contents of the
        // current buffer.
        memcpy((LPVOID)GetCurrentBufferPositionAsPointer(), (LPVOID)pbBuf, dwBytesLeftInCurrentBuffer);
        pbBuf += dwBytesLeftInCurrentBuffer;
        dwBytes -= dwBytesLeftInCurrentBuffer;
        // Advance to the next buffer.  If this fails, then we'll have reached
        // the end of the buffer list.
        if (FALSE == DoAdvanceBuffer()) {
            goto exit;
        }
        // Repeat with the next buffer.
        goto write_to_current_buffer;
    }
    else {
        // We won't write past the current buffer.  Write the required contents
        // of the current buffer.
        memcpy((LPVOID)GetCurrentBufferPositionAsPointer(), (LPVOID)pbBuf, dwBytes);
        m_dwCurrentBufferPosition += dwBytes;
        dwBytes = 0;
    }

exit:;

    // Return the difference between the requested number of bytes to write and
    // the number of bytes remaining to be written.  If the caller tried writing
    // past the end of the buffer list, then the actual number of bytes we wrote
    // will be less than the requested number of bytes to write.
    *pdwBytesWritten -= dwBytes;
    return TRUE;
}

⌨️ 快捷键说明

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