📄 isapistrm.cpp
字号:
}
while(cbLeftToWrite)
{
// Remainder will be written to linked buffers
if (!m_pLastBuffer || (m_cbLastBuffer == STRM_BUFFER_SIZE))
{
// Need to allocate a new buffer
m_pLastBuffer = new BYTE[STRM_BUFFER_SIZE];
if (!m_pLastBuffer)
{
m_SOAPIsapiResponse.put_HTTPStatus((BSTR)g_pwszStatusInternalError);
if (pcbWritten)
*pcbWritten = 0;
return E_OUTOFMEMORY;
}
// Add this to the list
m_pBuffersList.Add((void *) m_pLastBuffer);
m_cLinkedBuffers++;
m_cbLastBuffer = 0;
}
cbWritten = STRM_BUFFER_SIZE - m_cbLastBuffer;
if (cbWritten > cbLeftToWrite)
cbWritten = cbLeftToWrite;
memcpy(m_pLastBuffer + m_cbLastBuffer, (BYTE *)pv+(cb - cbLeftToWrite), cbWritten);
m_cbLastBuffer += cbWritten;
cbLeftToWrite -= cbWritten;
}
if (pcbWritten)
*pcbWritten = cb;
return S_OK;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// function: COutputStream::Seek(LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
//
// parameters:
//
// description:
// returns:
//
////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP COutputStream::Seek(LARGE_INTEGER dlibMove,
DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
{
return E_FAIL;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// function: COutputStream::FlushBuffer()
//
// parameters:
//
// description:
// Flushes to the output Http stream
// returns:
//
////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP COutputStream::FlushBuffer()
{
ULONG cbToWrite;
DWORD idx;
CLinkedList * pLinkIndex = NULL;
BYTE * ptempbuf;
if (!m_pECB)
return E_FAIL;
ASSERT(!m_fHeaderSent || (m_cbFirstBuffer == 0));
#ifndef UNDER_CE
ASSERT(g_dwNaglingFlags == 0 || g_dwNaglingFlags == (HSE_IO_SYNC | HSE_IO_NODELAY));
#endif
if(!m_fHeaderSent)
SendHeader();
if (m_cbFirstBuffer)
{
cbToWrite = m_cbFirstBuffer;
#ifndef UNDER_CE
m_pECB->WriteClient( m_pECB->ConnID, (void *)m_bFirstBuffer, &cbToWrite, g_dwNaglingFlags);
#else
m_pECB->WriteClient( m_pECB->ConnID, (void *)m_bFirstBuffer, &cbToWrite, 0);
#endif
ASSERT(cbToWrite == m_cbFirstBuffer);
m_cbFirstBuffer = 0;
}
// Write the in between linked buffers
if (m_cLinkedBuffers)
{
if (m_cLinkedBuffers > 1)
{
ptempbuf = (BYTE *) m_pBuffersList.First(&pLinkIndex);
for (idx = 0 ; idx < (m_cLinkedBuffers - 1) ; idx++)
{
cbToWrite = STRM_BUFFER_SIZE;
#ifndef UNDER_CE
m_pECB->WriteClient( m_pECB->ConnID, (void *)ptempbuf, &cbToWrite, g_dwNaglingFlags);
#else
m_pECB->WriteClient( m_pECB->ConnID, (void *)ptempbuf, &cbToWrite, 0);
#endif
ASSERT(cbToWrite == STRM_BUFFER_SIZE);
ptempbuf = (BYTE *) m_pBuffersList.Next(&pLinkIndex);
}
}
// Write the last buffer
if (m_cbLastBuffer)
{
cbToWrite = m_cbLastBuffer;
#ifndef UNDER_CE
m_pECB->WriteClient( m_pECB->ConnID, (void *)m_pLastBuffer, &cbToWrite, g_dwNaglingFlags);
#else
m_pECB->WriteClient( m_pECB->ConnID, (void *)m_pLastBuffer, &cbToWrite, 0);
#endif
ASSERT(cbToWrite == m_cbLastBuffer);
m_cbLastBuffer = 0;
}
// Clear all the linked buffers
m_pBuffersList.DeleteList();
m_pLastBuffer = NULL;
m_cLinkedBuffers = 0;
}
return (m_errorcode == Error_Success) ? S_OK : E_FAIL ;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// function: COutputStream::SetSize(ULARGE_INTEGER cbNewSize)
//
// parameters:
//
// description:
// returns:
//
////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP COutputStream::SetSize(ULARGE_INTEGER cbNewSize)
{
#if !defined(_W64) && !defined(UNDER_CE)
m_cbFileSize = (ULONGLONG) cbNewSize;
#else
m_cbFileSize = (ULONGLONG) cbNewSize.HighPart << 32;
m_cbFileSize += (ULONGLONG) cbNewSize.LowPart;
#endif
return S_OK;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// function: COutputStream::CopyTo(IStream *pstm, ULARGE_INTEGER cb, ULARGE_INTEGER *pcbRead,
// ULARGE_INTEGER *pcbWritten)
//
// parameters:
//
// description:
// returns:
//
////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP COutputStream::CopyTo(IStream *pstm,
ULARGE_INTEGER cb, ULARGE_INTEGER *pcbRead,
ULARGE_INTEGER *pcbWritten)
{
return E_FAIL;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// function: COutputStream::Commit(DWORD grfCommitFlags)
//
// parameters:
//
// description:
// returns:
//
////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP COutputStream::Commit(DWORD grfCommitFlags)
{
return E_FAIL;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// function: COutputStream::Revert(void)
//
// parameters:
//
// description:
// returns:
//
////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP COutputStream::Revert(void)
{
return E_FAIL;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// function: COutputStream::LockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
//
// parameters:
//
// description:
// returns:
//
////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP COutputStream::LockRegion(
ULARGE_INTEGER libOffset, ULARGE_INTEGER cb,
DWORD dwLockType)
{
return E_FAIL;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// function: COutputStream::UnlockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
//
// parameters:
//
// description:
// returns:
//
////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP COutputStream::UnlockRegion(
ULARGE_INTEGER libOffset, ULARGE_INTEGER cb,
DWORD dwLockType)
{
return E_FAIL;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// function: COutputStream::Stat(STATSTG *pstatstg, DWORD grfStatFlag)
//
// parameters:
//
// description:
// returns:
//
////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP COutputStream::Stat(STATSTG *pstatstg,
DWORD grfStatFlag)
{
return E_FAIL;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// function: COutputStream::Clone(IStream **ppstm)
//
// parameters:
//
// description:
// returns:
//
////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP COutputStream::Clone(IStream **ppstm)
{
return E_FAIL;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// function: COutputStream::Write(IStream *pIStrmIn)
//
// parameters:
//
// description:
// Writes to the output Http stream reading in from the stream given
// Assumes that the content-length is given in filesize
// returns:
//
////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP COutputStream::Write(IStream *pIStrmIn)
{
HRESULT hr = S_OK;
BYTE tempbuf[STRM_BUFFER_SIZE];
ULONG cbRead;
ULONG cbWritten;
// We assume that the file size is already given, and use it in the Headers
ASSERT(m_cbFileSize != 0);
SendHeader();
while (TRUE)
{
CHK(pIStrmIn->Read(tempbuf, STRM_BUFFER_SIZE, &cbRead));
if (cbRead == 0)
break;
cbWritten = cbRead;
#ifndef UNDER_CE
m_pECB->WriteClient( m_pECB->ConnID, (void *)tempbuf, &cbWritten, g_dwNaglingFlags);
#else
m_pECB->WriteClient( m_pECB->ConnID, (void *)tempbuf, &cbWritten, 0);
#endif
if (cbWritten != cbRead)
return E_FAIL;
}
Cleanup:
return hr;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// function: COutputStream::SendHeader()
//
// parameters:
//
// description:
// Sends http headers to the output Http stream
// returns:
//
////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL COutputStream::SendHeader()
{
HSE_SEND_HEADER_EX_INFO HeaderExInfo;
char szHeader[MAX_HEADER_LENGTH];
char szTemp[ONEK];
char* pszStatus = NULL;
const char* pszHeaderEx = NULL;
#ifndef UNDER_CE
DWORD cchHeader = 0;
#endif
char szApplPath[ONEK+1];
DWORD cchApplPath = ONEK;
char szLength[64];
DWORD cchContLength;
BOOL KeepAlive = FALSE;
#ifdef UNDER_CE
HRESULT hr = ERROR_SUCCESS;
// ensure that the strings are null terminated by default
szHeader[0] = 0;
szTemp[0] = 0;
szLength[0] = 0;
#endif
if (m_fHeaderSent)
return FALSE;
if (m_SOAPIsapiResponse.m_pwstrHTTPStatus != NULL)
{
DWORD cwchar;
DWORD dwStringLen;
// Use the user supplied header
dwStringLen = wcslen((WCHAR *)(m_SOAPIsapiResponse.m_pwstrHTTPStatus));
#ifndef UNDER_CE
__try{
#endif
pszStatus = (char *) _alloca(dwStringLen * 3 + 1);
#ifndef UNDER_CE
}
__except(1){
return FALSE;
}
#endif
// The buffer is given in Unicode. Convert it to utf-8 before writing
cwchar = WideCharToMultiByte(CP_UTF8, 0,
(LPCWSTR)(m_SOAPIsapiResponse.m_pwstrHTTPStatus),
dwStringLen,
(LPSTR)pszStatus, dwStringLen * 3 + 1,
NULL, NULL);
#ifdef UNDER_CE
if(!cwchar)
{
cwchar = WideCharToMultiByte(CP_ACP, 0,
(LPCWSTR)(m_SOAPIsapiResponse.m_pwstrHTTPStatus),
dwStringLen,
(LPSTR)pszStatus, dwStringLen * 3 + 1,
NULL, NULL);
}
#endif
if(cwchar < (dwStringLen * 3 + 1)) {
pszStatus[cwchar] = 0;
} else {
pszStatus[dwStringLen * 3] = 0;
}
}
switch (m_errorcode)
{
case Error_Success:
if (!pszStatus)
pszStatus = (char *)g_szStatusOK;
pszHeaderEx = g_szHeaderExContentExpires;
KeepAlive = TRUE;
break;
case Error_BadRequest:
if (!pszStatus)
pszStatus = (char *)g_szStatusBadRequest;
break;
case Error_AccessDenied: // permission denied
if (!pszStatus)
pszStatus = (char *)g_szStatusAccessDenied;
szApplPath[0] = NULL;
m_pECB->GetServerVariable(
m_pECB->ConnID, "URL", szApplPath, &cchApplPath);
wsprintfA(szTemp, g_szHeaderExAccessDenied, szApplPath);
pszHeaderEx = szTemp;
break;
case Error_NotFound: // bad server or db name or not specified
if (!pszStatus)
pszStatus = (char *)g_szStatusNotFound;
break;
case Error_MethodNotAllowed: // post, get & head are the only methods allowed
pszHeaderEx = g_szHeaderExMethodNotAllowed;
if (!pszStatus)
pszStatus = (char *)g_szStatusMethodNotAllowed;
break;
case Error_UnsupportedContentType: // content type's other than text/xml,
if (!pszStatus)
pszStatus = (char *)g_szStatusUnsupportedContentType; // or application/x-www-form-urlencoded
break;
case Error_UnprocessableEntity: // XSL related errors
if (!pszStatus)
pszStatus = (char *)g_szStatusUnprocessableEntity;
break;
case Error_InternalError: // Out of memory etc.
if (!pszStatus)
pszStatus = (char *)g_szStatusInternalError;
break;
case Error_NotImplemeneted:
if (!pszStatus)
pszStatus = (char *)g_szStatusNotImplemented;
break;
case Error_Timeout:
if (!pszStatus)
pszStatus = (char *)g_szStatusTimeout;
break;
case Error_ServiceUnavailable:
if (!pszStatus)
pszStatus = (char *)g_szStatusServiceUnavailable;
break;
default:
ASSERT(FALSE);
if (!pszStatus)
pszStatus = (char *)g_szStatusInternalError;
break;
}
if (m_fHeadersOnly)
{
pszHeaderEx = g_szHeaderExContentExpires;
}
// Return the content-length
if (m_cbFileSize != 0)
{
_ui64toa(m_cbFileSize, szLength, 10 );
}
else
{
cchContLength = m_cbFirstBuffer + m_cbLastBuffer;
if (m_cLinkedBuffers > 1)
cchContLength += STRM_BUFFER_SIZE * (m_cLinkedBuffers - 1);
_itoa(cchContLength, szLength, 10);
}
{
//Assemble the header
char szHeaderTemp[MAX_HEADER_LENGTH];
if (m_SOAPIsapiResponse.m_pwstrHTTPCharset)
{
const char szTypeString[] = "Content-Type: %s; charset=\"%S\"\r\nContent-Length: %s\r\n";
if(strlen(szTypeString) +
strlen(g_szContentTextXML) +
wcslen(m_SOAPIsapiResponse.m_pwstrHTTPCharset) +
strlen(szLength) + 1 >= MAX_HEADER_LENGTH) {
ASSERT(FALSE);
return FALSE;
}
#ifdef UNDER_CE
hr = StringCchPrintfA(
szHeaderTemp,
MAX_HEADER_LENGTH,
szTypeString,
(char *)g_szContentTextXML,
m_SOAPIsapiResponse.m_pwstrHTTPCharset,
szLength);
if(FAILED(hr)) {
ASSERT(FALSE);
return FALSE;
}
#else
cchHeader = wsprintfA(
szHeaderTemp,
szTypeString,
(char *)g_szContentTextXML,
m_SOAPIsapiResponse.m_pwstrHTTPCharset,
szLength);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -