📄 csgreq.cpp
字号:
// ----------------------------------------------------------------------------
// 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 + -