Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

538 lines
14 KiB

#ifndef _ECB_H_
#define _ECB_H_
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// ECB.H
//
// Header for IEcb interface class.
//
// Copyright 1986-1997 Microsoft Corporation, All Rights Reserved
//
#include <autoptr.h> // For CMTRefCounted parent
#include <cvroot.h>
#include <davmb.h> // For IMDData
#include <url.h> // For HttpUriEscape
// ========================================================================
//
// ENUM TRANSFER_CODINGS
//
// Valid transfer codings. See HTTP/1.1 draft section 3.5.
//
// TC_UNKNOWN - Unknown value.
// TC_IDENTITY - Identity encoding (i.e. no encoding).
// TC_CHUNKED - Chunked encoding.
//
enum TRANSFER_CODINGS
{
TC_UNKNOWN,
TC_IDENTITY,
TC_CHUNKED
};
typedef struct _HSE_EXEC_URL_INFO_WIDE {
LPCWSTR pwszUrl; // URL to execute
DWORD dwExecUrlFlags; // Flags
} HSE_EXEC_URL_INFO_WIDE, * LPHSE_EXEC_URL_INFO_WIDE;
// ========================================================================
//
// CLASS IIISAsyncIOCompleteObserver
//
// Passed to IEcb async I/O methods
//
class IIISAsyncIOCompleteObserver
{
// NOT IMPLEMENTED
//
IIISAsyncIOCompleteObserver& operator=( const IIISAsyncIOCompleteObserver& );
public:
// CREATORS
//
virtual ~IIISAsyncIOCompleteObserver() = 0;
// MANIPULATORS
//
virtual VOID IISIOComplete( DWORD dwcbIO, DWORD dwLastError ) = 0;
};
// ========================================================================
//
// CLASS IEcb
//
// Provides a clean interface to the EXTENSION_CONTROL_BLOCK passed
// to us by IIS.
//
class CInstData;
class IEcbBase : public CMTRefCounted
{
private:
// NOT IMPLEMENTED
//
IEcbBase( const IEcbBase& );
IEcbBase& operator=( const IEcbBase& );
// Private URL mapping helpers
//
SCODE ScReqMapUrlToPathEx60After(
/* [in] */ LPCWSTR pwszUrl,
/* [out] */ HSE_UNICODE_URL_MAPEX_INFO * pmi ) const
{
SCODE sc = S_OK;
UINT cbPath = sizeof(pmi->lpszPath);
Assert( m_pecb );
Assert( pwszUrl );
Assert( pmi );
if (!m_pecb->ServerSupportFunction( m_pecb->ConnID,
HSE_REQ_MAP_UNICODE_URL_TO_PATH_EX,
const_cast<LPWSTR>(pwszUrl),
reinterpret_cast<DWORD*>(&cbPath),
reinterpret_cast<DWORD*>(pmi) ))
{
// There is a fix for Windows Bugs 156176 that we need to do the
// following check for. It applies to IIS 6.0 (+) path only. In IIS 5.0
// the maping functions were silently succeeding, and truncating the
// buffer that contained the mapped path if it exceeded MAX_PATH.
// That behaviour suited us, but is not very nice, so IIS 6.0 chose
// to still fill in the buffer as before, but fail with special error
// (ERROR_INSUFFICIENT_BUFFER). That error still means success to us,
// so fail only if we see something different
//
if (ERROR_INSUFFICIENT_BUFFER != GetLastError())
{
// Function does not allow to return failures, so the only option
// is to throw. We cannot proceed if we did not get the data anyway.
// If this function succeeds once, subsequent calls to it are non
// failing.
//
sc = HRESULT_FROM_WIN32(GetLastError());
Assert(FAILED(sc));
DebugTrace("IEcbBase::ScReqMapUrlToPathEx60After() - ServerSupportFunction(HSE_REQ_MAP_UNICODE_URL_TO_PATH_EX) failed 0x%08lX\n", sc);
goto ret;
}
}
DebugTrace ("IEcbBase::ScReqMapUrlToPathEx60After() - ServerSupportFunction"
"(HSE_REQ_MAP_UNICODE_URL_TO_PATH_EX) succeded!\n"
"mapinfo:\n"
"- url \"%ls\" maps to \"%ls\"\n"
"- dwFlags = 0x%08x\n"
"- cchMatchingPath = %d\n"
"- cchMatchingURL = %d\n",
pwszUrl,
pmi->lpszPath,
pmi->dwFlags,
pmi->cchMatchingPath,
pmi->cchMatchingURL);
// The value for cbPath, at this point, should include the L'\0'
// termination, and for that reason cbPath will always be more
// than the length of the matching path.
//
Assert (0 == cbPath % sizeof(WCHAR));
Assert (pmi->cchMatchingPath < cbPath/sizeof(WCHAR));
ret:
return sc;
}
SCODE ScReqMapUrlToPathEx60Before(
/* [in] */ LPCWSTR pwszUrl,
/* [out] */ HSE_UNICODE_URL_MAPEX_INFO * pmi ) const
{
SCODE sc = S_OK;
HSE_URL_MAPEX_INFO mi;
CStackBuffer<CHAR, MAX_PATH> pszUrl;
UINT cchUrl;
UINT cbUrl;
UINT cbPath;
UINT cchPath;
Assert( m_pecb );
Assert( pwszUrl );
Assert( pmi );
// Find out the length of the URL
//
cchUrl = static_cast<UINT>(wcslen(pwszUrl));
cbUrl = cchUrl * 3;
// Resize the buffer to the sufficient size, leave place for '\0' termination
//
if (!pszUrl.resize(cbUrl + 1))
{
sc = E_OUTOFMEMORY;
DebugTrace("IEcbBase::ScReqMapUrlToPathEx60Before() - Error while allocating memory 0x%08lX\n", sc);
goto ret;
}
// Convert to skinny including '\0' termination
//
cbUrl = WideCharToMultiByte(CP_ACP,
0,
pwszUrl,
cchUrl + 1,
pszUrl.get(),
cbUrl + 1,
0,
0);
if (0 == cbUrl)
{
sc = HRESULT_FROM_WIN32(GetLastError());
DebugTrace("IEcbBase::ScSSFReqMapUrlToPathEx() - WideCharToMultiByte() failed 0x%08lX\n", sc);
goto ret;
}
cbPath = MAX_PATH;
// Get the skinny mappings from IIS
//
if (!m_pecb->ServerSupportFunction( m_pecb->ConnID,
HSE_REQ_MAP_URL_TO_PATH_EX,
pszUrl.get(),
reinterpret_cast<DWORD*>(&cbPath),
reinterpret_cast<DWORD*>(&mi)))
{
sc = HRESULT_FROM_WIN32(GetLastError());
DebugTrace("IEcbBase::ScSSFReqMapUrlToPathEx() - ServerSupportFunction() failed 0x%08lX\n", sc);
goto ret;
}
DebugTrace ("IEcbBase::ScSSFReqMapUrlToPathEx() - ServerSupportFunction"
"(HSE_REQ_MAP_URL_TO_PATH_EX) succeded!\n"
"mapinfo:\n"
"- url \"%hs\" maps to \"%hs\"\n"
"- dwFlags = 0x%08x\n"
"- cchMatchingPath = %d\n"
"- cchMatchingURL = %d\n",
pszUrl.get(),
mi.lpszPath,
mi.dwFlags,
mi.cchMatchingPath,
mi.cchMatchingURL);
// The value for cbPath, at this point, should include the null
// termination, and for that reason cbPath will always be more
// than the length of the matching path.
//
Assert (mi.cchMatchingPath < cbPath);
Assert (mi.cchMatchingURL < cbUrl);
// First translate the matching path so we would know its
// length and would be able to pass it back
//
if (mi.cchMatchingPath)
{
// Converting will never yield the buffer bigger than one we already have
//
pmi->cchMatchingPath = MultiByteToWideChar(CP_ACP,
MB_ERR_INVALID_CHARS,
mi.lpszPath,
mi.cchMatchingPath,
pmi->lpszPath,
MAX_PATH);
if (0 == pmi->cchMatchingPath)
{
sc = HRESULT_FROM_WIN32(GetLastError());
DebugTrace("IEcbBase::ScSSFReqMapUrlToPathEx() - MultiByteToWideChar() failed 0x%08lX\n", sc);
goto ret;
}
}
else
{
pmi->cchMatchingPath = 0;
}
// Convert the remainder of the path including the '\0' termination
//
cchPath = MultiByteToWideChar(CP_ACP,
MB_ERR_INVALID_CHARS,
mi.lpszPath + mi.cchMatchingPath,
min(cbPath, MAX_PATH) - mi.cchMatchingPath,
pmi->lpszPath + pmi->cchMatchingPath,
MAX_PATH - pmi->cchMatchingPath);
if (0 == cchPath)
{
sc = HRESULT_FROM_WIN32(GetLastError());
DebugTrace("IEcbBase::ScReqMapUrlToPathEx() - MultiByteToWideChar() failed 0x%08lX\n", sc);
goto ret;
}
// Find the matching URL length for wide version
//
if (mi.cchMatchingURL)
{
pmi->cchMatchingURL = MultiByteToWideChar(CP_ACP,
MB_ERR_INVALID_CHARS,
pszUrl.get(),
mi.cchMatchingURL,
0,
0);
if (0 == pmi->cchMatchingURL)
{
sc = HRESULT_FROM_WIN32(GetLastError());
DebugTrace("IEcbBase::ScReqMapUrlToPathEx() - MultiByteToWideChar() failed 0x%08lX\n", sc);
goto ret;
}
}
else
{
pmi->cchMatchingURL = 0;
}
ret:
return sc;
}
protected:
// Declare the version constant
//
enum
{
IIS_VERSION_6_0 = 0x60000
};
// A POINTER to the original EXTENSION_CONTROL_BLOCK.
// Using a reference would make it impossible for us
// to tell if IIS ever requires that we use the
// EXTENSION_CONTROL_BLOCK passed into async I/O
// completion routines for subsequent I/O.
//
EXTENSION_CONTROL_BLOCK * m_pecb;
IEcbBase( EXTENSION_CONTROL_BLOCK& ecb) :
m_pecb(&ecb)
{
m_cRef = 1; //$HACK Until we have 1-based refcounting
}
public:
virtual BOOL FSsl() const = 0;
virtual BOOL FFrontEndSecured() const = 0;
virtual BOOL FBrief() const = 0;
virtual ULONG LcidAccepted() const = 0;
virtual VOID SetLcidAccepted(LCID lcid) = 0;
virtual LPCSTR LpszRequestUrl() const = 0;
virtual LPCWSTR LpwszRequestUrl() const = 0;
virtual UINT CchUrlPrefix( LPCSTR * ppszPrefix ) const = 0;
virtual UINT CchUrlPrefixW( LPCWSTR * ppwszPrefix ) const = 0;
virtual UINT CchGetServerName( LPCSTR * ppszServer ) const = 0;
virtual UINT CchGetServerNameW( LPCWSTR * ppwszServer ) const = 0;
virtual UINT CchGetVirtualRoot( LPCSTR * ppszVroot ) const = 0;
virtual UINT CchGetVirtualRootW( LPCWSTR * ppwszVroot ) const = 0;
virtual UINT CchGetMatchingPathW( LPCWSTR * ppwszMatching ) const = 0;
virtual LPCWSTR LpwszPathTranslated() const = 0;
virtual CInstData& InstData() const = 0;
virtual BOOL FGetServerVariable( LPCSTR lpszName,
LPSTR lpszValue,
DWORD * pcbValue ) const = 0;
virtual BOOL FGetServerVariable( LPCSTR lpszName,
LPWSTR lpwszValue,
DWORD * pcchValue ) const = 0;
BOOL
WriteClient( LPVOID lpvBuf,
LPDWORD lpdwcbBuf,
DWORD dwFlags ) const
{
Assert( m_pecb );
return m_pecb->WriteClient( m_pecb->ConnID,
lpvBuf,
lpdwcbBuf,
dwFlags );
}
BOOL
ReadClient( LPVOID lpvBuf,
LPDWORD lpdwcbBuf ) const
{
Assert( m_pecb );
return m_pecb->ReadClient( m_pecb->ConnID,
lpvBuf,
lpdwcbBuf );
}
BOOL
ServerSupportFunction( DWORD dwHSERequest,
LPVOID lpvBuffer,
LPDWORD lpdwSize,
LPDWORD lpdwDataType ) const
{
Assert( m_pecb );
return m_pecb->ServerSupportFunction( m_pecb->ConnID,
dwHSERequest,
lpvBuffer,
lpdwSize,
lpdwDataType );
}
SCODE
ScReqMapUrlToPathEx( LPCWSTR pwszUrl,
HSE_UNICODE_URL_MAPEX_INFO * pmi ) const
{
Assert (m_pecb);
if ( m_pecb->dwVersion >= IIS_VERSION_6_0 )
return ScReqMapUrlToPathEx60After( pwszUrl, pmi );
return ScReqMapUrlToPathEx60Before( pwszUrl, pmi );
}
};
class IEcb : public IEcbBase
{
// NOT IMPLEMENTED
//
IEcb( const IEcb& );
IEcb& operator=( const IEcb& );
protected:
// CREATORS
// Only create this object through it's descendents!
//
IEcb( EXTENSION_CONTROL_BLOCK& ecb ) :
IEcbBase(ecb)
{}
~IEcb();
public:
// ACCESSORS
//
LPCSTR
LpszMethod() const
{
Assert( m_pecb );
return m_pecb->lpszMethod;
}
LPCSTR
LpszQueryString() const
{
Assert( m_pecb );
return m_pecb->lpszQueryString;
}
DWORD
CbTotalBytes() const
{
Assert( m_pecb );
return m_pecb->cbTotalBytes;
}
DWORD
CbAvailable() const
{
Assert( m_pecb );
return m_pecb->cbAvailable;
}
const BYTE *
LpbData() const
{
Assert( m_pecb );
return m_pecb->lpbData;
}
virtual LPCWSTR LpwszMethod() const = 0;
virtual UINT CbGetRawURL( LPCSTR * ppszRawURL ) const = 0;
virtual LPCSTR LpszUrlPrefix() const = 0;
virtual LPCWSTR LpwszUrlPrefix() const = 0;
virtual UINT CchUrlPortW( LPCWSTR * ppwszPort ) const = 0;
virtual HANDLE HitUser() const = 0;
virtual BOOL FKeepAlive() const = 0;
virtual BOOL FCanChunkResponse() const = 0;
virtual BOOL FAuthenticated() const = 0;
virtual BOOL FProcessingCEUrl() const = 0;
virtual BOOL FIIS60OrAfter() const = 0;
virtual LPCSTR LpszVersion() const = 0;
virtual BOOL FSyncTransmitHeaders( const HSE_SEND_HEADER_EX_INFO& shei ) = 0;
virtual SCODE ScAsyncRead( BYTE * pbBuf,
UINT * pcbBuf,
IIISAsyncIOCompleteObserver& obs ) = 0;
virtual SCODE ScAsyncWrite( BYTE * pbBuf,
DWORD dwcbBuf,
IIISAsyncIOCompleteObserver& obs ) = 0;
virtual SCODE ScAsyncTransmitFile( const HSE_TF_INFO& tfi,
IIISAsyncIOCompleteObserver& obs ) = 0;
virtual SCODE ScAsyncCustomError60After( const HSE_CUSTOM_ERROR_INFO& cei,
LPSTR pszStatus ) = 0;
virtual SCODE ScExecuteChild( LPCWSTR pwszURI, LPCSTR pszQueryString, BOOL fCustomErrorUrl ) = 0;
virtual SCODE ScSendRedirect( LPCSTR lpszURI ) = 0;
virtual IMDData& MetaData() const = 0;
virtual LPCWSTR PwszMDPathVroot() const = 0;
#ifdef DBG
virtual void LogString( LPCSTR szLocation ) const = 0;
#else
void LogString( LPCSTR ) const {};
#endif
// MANIPULATORS
//
virtual VOID SendAsyncErrorResponse( DWORD dwStatusCode,
LPCSTR pszBody,
DWORD cchzBody,
LPCSTR pszStatusDescription,
DWORD cchzStatusDescription ) = 0;
virtual DWORD HSEHandleException() = 0;
// To be used ONLY by request/response.
//
virtual void SetStatusCode( UINT iStatusCode ) = 0;
virtual void SetConnectionHeader( LPCWSTR pwszValue ) = 0;
virtual void SetAcceptLanguageHeader( LPCSTR pszValue ) = 0;
virtual void CloseConnection() = 0;
};
IEcb * NewEcb( EXTENSION_CONTROL_BLOCK& ecb,
BOOL fUseRawUrlMappings,
DWORD * pdwHSEStatusRet );
#ifdef DBG
void InitECBLogging();
void DeinitECBLogging();
#endif
//
// Routines to manipulate metadata (metabase) paths
//
ULONG CbMDPathW( const IEcb& ecb, LPCWSTR pwszURI );
VOID MDPathFromURIW( const IEcb& ecb, LPCWSTR pwszURI, LPWSTR pwszMDPath );
#endif // !defined(_ECB_H_)