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

📄 isapistrm.cpp

📁 Windows CE 6.0 Server 源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    }
    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 + -