📄 isapistrm.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft shared
// source or premium shared source license agreement under which you licensed
// this source code. If you did not accept the terms of the license agreement,
// you are not authorized to use this source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the SOURCE.RTF on your install media or the root of your tools installation.
// THE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
//+----------------------------------------------------------------------------
//
//
// Module Name: isapistrm.cpp
//
// Contents:
//
// ISAPI Extension that services SOAP packages.
//
//-----------------------------------------------------------------------------
#ifdef UNDER_CE
#include "WinCEUtils.h"
#include "strsafe.h"
#endif
#include "isapihdr.h"
#define INIT_SOAP_GLOBALS
#include "soapglo.h"
// HTTP Error codes
const char g_szEmpty[] = "";
const char g_szStatusOK[] = "200 OK";
const char g_szStatusBadRequest[] = "400.100 Bad Request";
const char g_szStatusAccessDenied[] = "401 Access Denied";
const char g_szStatusNotFound[] = "404 Not Found";
const char g_szStatusMethodNotAllowed[] = "405 Method Not Allowed";
const char g_szStatusUnsupportedContentType[] = "415 Unsupported Media Type";
const char g_szStatusUnprocessableEntity[] = "422 Unprocessable Entity";
const char g_szStatusNotImplemented[] = "501 Not Implemented";
const char g_szStatusServiceUnavailable[] = "503 Service Unavailable";
const char g_szStatusTimeout[] = "504 Gateway Timeout";
const char g_szHeaderExMethodNotAllowed[] = "Allow: GET,HEAD,POST\r\n";
const char g_szHeaderExAccessDenied[] = "WWW-Authenticate: Basic realm=\"%.900s\"\r\n";
const char g_szHeaderExContentExpires[] = "Expires: -1;\r\n";
const WCHAR g_pwszStatusInternalError[] = L"500 Internal Server Error";
// HTTP content types
char g_szContentTextXML[] = "text/xml";
const WCHAR g_pwstrISAPIErrorSource[] = L"Error source: ";
////////////////////////////////////////////////////////////////////////////////////////////////////
// function: CIsapiStream::AddRef()
//
// parameters:
//
// description:
// returns:
//
////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP_(ULONG) CIsapiStream::AddRef()
{
return InterlockedIncrement((long*)&m_cRef);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// function: CIsapiStream::Release()
//
// parameters:
//
// description:
// returns:
//
////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP_(ULONG) CIsapiStream::Release()
{
long cRef = InterlockedDecrement((long*)&m_cRef);
if (!cRef)
{
delete this;
return 0;
}
return cRef;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// function: CIsapiStream::QueryInterface(REFIID riid, LPVOID *ppv)
//
// parameters:
//
// description:
// returns:
//
////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CIsapiStream::QueryInterface(REFIID riid, LPVOID *ppv)
{
if (NULL == ppv)
return E_INVALIDARG;
// Initialize the output param
*ppv = NULL;
// This is the non-delegating IUnknown implementation
if (riid == IID_IUnknown || riid == IID_ISequentialStream ||
riid == IID_IStream )
{
*ppv = (LPVOID)this;
}
if (NULL == *ppv)
return E_NOINTERFACE;
((LPUNKNOWN)*ppv)->AddRef();
return S_OK;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// function: CIsapiStream::Read(void *pv, ULONG cb, ULONG *pcbRead)
//
// parameters:
//
// description:
//
// returns:
//
////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CIsapiStream::Read(void *pv,
ULONG cb, ULONG *pcbRead)
{
return E_FAIL;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// function: CIsapiStream::Write(const void *pv, ULONG cb, ULONG *pcbRead)
//
// parameters:
//
// description:
//
// returns:
//
////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CIsapiStream::Write(const void *pv,
ULONG cb, ULONG *pcbRead)
{
return E_FAIL;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// function: CIsapiStream::Seek(LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
//
// parameters:
//
// description:
// returns:
//
////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CIsapiStream::Seek(LARGE_INTEGER dlibMove,
DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
{
return E_FAIL;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// function: CIsapiStream::SetSize(ULARGE_INTEGER libNewSize)
//
// parameters:
//
// description:
// returns:
//
////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CIsapiStream::SetSize(ULARGE_INTEGER libNewSize)
{
return E_FAIL;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// function: CIsapiStream::CopyTo(IStream *pstm, ULARGE_INTEGER cb, ULARGE_INTEGER *pcbRead,
// ULARGE_INTEGER *pcbWritten)
//
// parameters:
//
// description:
// returns:
//
////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CIsapiStream::CopyTo(IStream *pstm,
ULARGE_INTEGER cb, ULARGE_INTEGER *pcbRead,
ULARGE_INTEGER *pcbWritten)
{
return E_FAIL;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// function: CIsapiStream::Commit(DWORD grfCommitFlags)
//
// parameters:
//
// description:
// returns:
//
////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CIsapiStream::Commit(DWORD grfCommitFlags)
{
return E_FAIL;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// function: CIsapiStream::Revert(void)
//
// parameters:
//
// description:
// returns:
//
////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CIsapiStream::Revert(void)
{
return E_FAIL;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// function: CIsapiStream::LockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
//
// parameters:
//
// description:
// returns:
//
////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CIsapiStream::LockRegion(
ULARGE_INTEGER libOffset, ULARGE_INTEGER cb,
DWORD dwLockType)
{
return E_FAIL;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// function: CIsapiStream::UnlockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
//
// parameters:
//
// description:
// returns:
//
////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CIsapiStream::UnlockRegion(
ULARGE_INTEGER libOffset, ULARGE_INTEGER cb,
DWORD dwLockType)
{
return E_FAIL;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// function: CIsapiStream::Stat(STATSTG *pstatstg, DWORD grfStatFlag)
//
// parameters:
//
// description:
// returns:
//
////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CIsapiStream::Stat(STATSTG *pstatstg,
DWORD grfStatFlag)
{
return E_FAIL;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// function: CIsapiStream::Clone(IStream **ppstm)
//
// parameters:
//
// description:
// returns:
//
////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CIsapiStream::Clone(IStream **ppstm)
{
return E_FAIL;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// function: CInputStream::Read(void *pv, ULONG cb, ULONG *pcbRead)
//
// parameters:
//
// description:
// Reads the POST data from iis
// returns:
//
////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CInputStream::Read(void *pv,
ULONG cb, ULONG *pcbRead)
{
if (!m_pECB || (m_pECB->cbTotalBytes <= 0))
return E_FAIL;
if (m_dwTotalRead < m_pECB->cbTotalBytes)
{
//
// Read from the data buffer in the ECB
//
if (m_dwTotalRead < m_pECB->cbAvailable)
{
*pcbRead = min(cb, ULONG(m_pECB->cbAvailable - m_dwTotalRead));
memcpy(pv, (BYTE *)m_pECB->lpbData + m_dwTotalRead, *pcbRead);
}
else
{
// Set the size of our temporary buffer
*pcbRead = min(cb, ULONG(m_pECB->cbTotalBytes - m_dwTotalRead));
// Read the data into the temporary buffer
if (!m_pECB->ReadClient(m_pECB->ConnID, pv, pcbRead))
{
return E_FAIL;
}
}
m_dwTotalRead += *pcbRead;
return m_pECB->cbTotalBytes - m_dwTotalRead ? E_PENDING : S_OK;
}
else
*pcbRead = 0;
return S_FALSE;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// function: deleteOutputBuffer(void *pObj)
//
// parameters:
//
// description: Destructor function for buffers linked list
// returns:
//
////////////////////////////////////////////////////////////////////////////////////////////////////
void deleteOutputBuffer(void *pObj)
{
BYTE * pBuf;
pBuf = (BYTE *)pObj;
delete [] pBuf;
return;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// function: COutputStream::AddRef()
//
// parameters:
//
// description:
// returns:
//
////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP_(ULONG) COutputStream::AddRef()
{
return InterlockedIncrement((long*)&m_cRef);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// function: COutputStream::Release()
//
// parameters:
//
// description:
// returns:
//
////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP_(ULONG) COutputStream::Release()
{
long cRef = InterlockedDecrement((long*)&m_cRef);
if (!cRef)
{
delete this;
return 0;
}
return cRef;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// function: COutputStream::QueryInterface(REFIID riid, LPVOID *ppv)
//
// parameters:
//
// description:
// returns:
//
////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP COutputStream::QueryInterface(REFIID riid, LPVOID *ppv)
{
if (NULL == ppv)
return E_INVALIDARG;
// Initialize the output param
*ppv = NULL;
// This is the non-delegating IUnknown implementation
if (riid == IID_IUnknown || riid == IID_ISequentialStream ||
riid == IID_IStream)
{
*ppv = (LPVOID)this;
}
if (riid == IID_ISOAPIsapiResponse)
*ppv = (LPVOID) &m_SOAPIsapiResponse;
if (NULL == *ppv)
return E_NOINTERFACE;
((LPUNKNOWN)*ppv)->AddRef();
return S_OK;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// function: COutputStream::Read(void *pv, ULONG cb, ULONG *pcbRead)
//
// parameters:
//
// description:
//
// returns:
//
////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP COutputStream::Read(void *pv,
ULONG cb, ULONG *pcbRead)
{
return E_FAIL;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// function: COutputStream::Write(const void *pv, ULONG cb, ULONG *pcbWritten)
//
// parameters:
//
// description:
// Writes to the output Http stream
// returns:
//
////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP COutputStream::Write(const void *pv,
ULONG cb, ULONG *pcbWritten)
{
ULONG cbWritten;
ULONG cbLeftToWrite;
// Make sure we didn't send headers yet
ASSERT(!m_fHeaderSent);
cbLeftToWrite = cb;
// Fill out the first buffer if not already FULL
if (m_cbFirstBuffer < STRM_BUFFER_SIZE)
{
// We are still in the first buffer
cbWritten = STRM_BUFFER_SIZE - m_cbFirstBuffer;
if (cbWritten > cbLeftToWrite)
cbWritten = cbLeftToWrite;
memcpy(m_bFirstBuffer + m_cbFirstBuffer, pv, cbWritten);
m_cbFirstBuffer += cbWritten;
cbLeftToWrite -= cbWritten;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -