windows-nt/Source/XPSP1/NT/inetsrv/query/qutil/h/gibralt.hxx
2020-09-26 16:20:57 +08:00

407 lines
13 KiB
C++

//+---------------------------------------------------------------------------
//
// Copyright (C) 1996 - 1998, Microsoft Corporation.
//
// File: gibralt.hxx
//
// Contents: Abstraction of the interface to gibraltar
//
// History: 96/Jan/3 DwightKr Created
//
//----------------------------------------------------------------------------
#pragma once
#include <iisext.h>
#include <wininet.h>
#include <weblcid.hxx>
#include <ci64.hxx>
#define HTTP_HEADER "200 OK"
#define HTTP_DATA "Content-Type: text/html\r\n\r\n"
#define CANONIC_DATA "Content-Type: application/octet-stream\r\n\r\n"
#define GIFIMAGE_DATA "Content-Type: image/gif\r\n\r\n"
#define JPEGIMAGE_DATA "Content-Type: image/jpeg\r\n\r\n"
//+---------------------------------------------------------------------------
//
// Class: CWebServer
//
// Purpose: An abstraction of the interface to gibraltar
//
// History: 96/Jan/23 DwightKr Created
// 96-Mar-01 DwightKr Added copy constructor
//
//----------------------------------------------------------------------------
class CWebServer
{
public:
CWebServer( EXTENSION_CONTROL_BLOCK *pEcb ) : _pEcb( pEcb ),
_fWroteHeader( FALSE ),
_codePage( GetACP() ),
_lcid( InvalidLCID ),
_ccLocale( 0 ) {}
void SetCodePage( UINT codePage ) { _codePage = codePage; }
BOOL GetCGIVariable( CHAR const * pszVariableName,
CHAR * pbBuffer,
ULONG * pcbBuffer )
{
Win4Assert ( IsValid() );
return _pEcb->GetServerVariable( _pEcb->ConnID,
(char *) pszVariableName,
pbBuffer,
pcbBuffer );
}
BOOL GetCGIVariable( CHAR const * pszVariableName,
XArray<WCHAR> & wcsValue,
ULONG & cwcBuffer );
BOOL GetCGIVariableW( WCHAR const * wcsVariableName,
XArray<WCHAR> & wcsValue,
ULONG & cwcBuffer );
BOOL GetCGI_REQUEST_METHOD( XArray<WCHAR> & wcsValue,
ULONG & cwcBuffer )
{
Win4Assert( 0 != _pEcb->lpszMethod );
if ( 0 == * (_pEcb->lpszMethod) )
return FALSE;
cwcBuffer = MultiByteToXArrayWideChar( (BYTE const *) _pEcb->lpszMethod,
strlen( _pEcb->lpszMethod ),
_codePage,
wcsValue );
return TRUE;
}
BOOL GetCGI_QUERY_STRING( XArray<WCHAR> & wcsValue,
ULONG & cwcBuffer )
{
Win4Assert( 0 != _pEcb->lpszQueryString );
if ( 0 == * (_pEcb->lpszQueryString) )
return FALSE;
cwcBuffer = MultiByteToXArrayWideChar( (BYTE const *) _pEcb->lpszQueryString,
strlen( _pEcb->lpszQueryString ),
_codePage,
wcsValue );
return TRUE;
}
BOOL GetCGI_PATH_INFO( XArray<WCHAR> & wcsValue,
ULONG & cwcBuffer )
{
Win4Assert( 0 != _pEcb->lpszPathInfo );
if ( 0 == * (_pEcb->lpszPathInfo) )
return FALSE;
cwcBuffer = MultiByteToXArrayWideChar( (BYTE const *) _pEcb->lpszPathInfo,
strlen( _pEcb->lpszPathInfo ),
_codePage,
wcsValue );
return TRUE;
}
BOOL GetCGI_PATH_TRANSLATED( XArray<WCHAR> & wcsValue,
ULONG & cwcBuffer )
{
Win4Assert( 0 != _pEcb->lpszPathTranslated );
if ( 0 == * (_pEcb->lpszPathTranslated) )
return FALSE;
cwcBuffer = MultiByteToXArrayWideChar( (BYTE const *) _pEcb->lpszPathTranslated,
strlen( _pEcb->lpszPathTranslated ),
_codePage,
wcsValue );
return TRUE;
}
BOOL GetCGI_PATH_TRANSLATED( WCHAR *pwcPath,
ULONG &cwcBuffer )
{
Win4Assert( 0 != _pEcb->lpszPathTranslated );
Win4Assert( 0 != * ( _pEcb->lpszPathTranslated ) );
cwcBuffer = MultiByteToWideChar(
CP_ACP,
0,
(const char *) _pEcb->lpszPathTranslated,
strlen(_pEcb->lpszPathTranslated) + 1,
pwcPath,
cwcBuffer );
return 0 != cwcBuffer;
}
BOOL GetCGI_CONTENT_TYPE( XArray<WCHAR> & wcsValue,
ULONG & cwcBuffer )
{
Win4Assert( 0 != _pEcb->lpszContentType );
if ( 0 == * (_pEcb->lpszContentType) )
return FALSE;
cwcBuffer = MultiByteToXArrayWideChar( (BYTE const *) _pEcb->lpszContentType,
strlen( _pEcb->lpszContentType ),
_codePage,
wcsValue );
return TRUE;
}
DWORD GetPhysicalPath( WCHAR const * wcsVirtualPath,
WCHAR * wcsPhysicalPath,
ULONG cwcPhysicalPath,
DWORD dwAccessMask = 0 ); // HSE_URL_FLAGS_*
void SetHttpStatus( DWORD dwStatus )
{
Win4Assert ( IsValid() );
Win4Assert( _pEcb->dwHttpStatusCode >= HTTP_STATUS_FIRST );
Win4Assert( _pEcb->dwHttpStatusCode <= HTTP_STATUS_LAST );
Win4Assert( dwStatus >= HTTP_STATUS_FIRST );
Win4Assert( dwStatus <= HTTP_STATUS_LAST );
_pEcb->dwHttpStatusCode = dwStatus;
}
DWORD GetHttpStatus() const
{
Win4Assert ( IsValid() );
Win4Assert( _pEcb->dwHttpStatusCode >= HTTP_STATUS_FIRST );
Win4Assert( _pEcb->dwHttpStatusCode <= HTTP_STATUS_LAST );
return _pEcb->dwHttpStatusCode;
}
const CHAR * GetQueryString() const
{
Win4Assert ( IsValid() );
return (const CHAR *) _pEcb->lpszQueryString;
}
const CHAR * GetMethod() const
{
Win4Assert ( IsValid() );
return (const CHAR *) _pEcb->lpszMethod;
}
const CHAR * GetClientData( DWORD & cbData ) const
{
Win4Assert ( IsValid() );
cbData = _pEcb->cbAvailable;
return (const CHAR *) _pEcb->lpbData;
}
BOOL IsValid() const { return _pEcb != 0; }
BOOL WriteHeader( const char * pszData = HTTP_DATA,
const char * pszHeader = HTTP_HEADER )
{
Win4Assert( !_fWroteHeader );
Win4Assert ( IsValid() );
_fWroteHeader = TRUE;
DWORD dwDataSize = pszData != 0 ? strlen(pszData)+1 : 0;
return _pEcb->ServerSupportFunction( _pEcb->ConnID,
HSE_REQ_SEND_RESPONSE_HEADER,
(LPVOID) pszHeader,
&dwDataSize,
(LPDWORD)pszData);
}
BOOL WriteClient( const WCHAR * wcsMessage )
{
Win4Assert ( IsValid() );
if (! _fWroteHeader && ! WriteHeader() )
return FALSE;
DWORD cwcMessage = wcslen( (WCHAR *) wcsMessage ) + 1;
XArray<BYTE> pszMessage ( cwcMessage + cwcMessage/8 );
DWORD cbMessage = WideCharToXArrayMultiByte( wcsMessage,
cwcMessage,
_codePage,
pszMessage );
return _pEcb->WriteClient( _pEcb->ConnID,
pszMessage.Get(),
&cbMessage,
0 );
}
BOOL WriteClient( CVirtualString & vsMessage )
{
Win4Assert ( IsValid() );
if (! _fWroteHeader && ! WriteHeader() )
return FALSE;
DWORD cwcMessage = vsMessage.StrLen() + 1;
XArray<BYTE> pszMessage( cwcMessage + cwcMessage/8 );
DWORD cbMessage = WideCharToXArrayMultiByte( vsMessage.Get(),
cwcMessage,
_codePage,
pszMessage );
return _pEcb->WriteClient( _pEcb->ConnID,
pszMessage.Get(),
&cbMessage,
0 );
}
BOOL WriteClient( const BYTE * pcsMessage, DWORD ccMessage )
{
Win4Assert ( IsValid() );
if (! _fWroteHeader && !WriteHeader() )
return FALSE;
return _pEcb->WriteClient( _pEcb->ConnID,
(void *) pcsMessage,
&ccMessage,
0 );
}
void RawWriteClient( BYTE * pbData, ULONG cbData )
{
Win4Assert ( IsValid() );
_pEcb->WriteClient( _pEcb->ConnID,
pbData,
&cbData,
0 );
}
BOOL ReleaseSession( DWORD dwStatus )
{
Win4Assert ( IsValid() );
Win4Assert( HTTP_STATUS_ACCEPTED != _pEcb->dwHttpStatusCode );
BOOL fSuccess = _pEcb->ServerSupportFunction( _pEcb->ConnID,
HSE_REQ_DONE_WITH_SESSION,
&dwStatus,
0, 0 );
_pEcb = 0;
return fSuccess;
}
// void WriteLogData( WCHAR const * wcsLogData );
UINT CodePage() { return _codePage; }
inline void SetLCID( LCID lcid,
WCHAR const * pwszLocale,
unsigned ccLocale );
BOOL IsLCIDValid() { return (InvalidLCID != _lcid); }
LCID GetLCID() { return _lcid; }
unsigned LocaleSize() { return _ccLocale; }
WCHAR const * GetLocale() { return _wszLocale; }
ULONG GetServerInstance()
{
//
// Retrieve the metabase instance number of the ISAPI request
//
char acBuf[ 40 ];
ULONG cbBuf = sizeof acBuf;
if ( !GetCGIVariable( "INSTANCE_ID", acBuf, &cbBuf ) )
THROW( CException( HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER ) ) );
ULONG ulInstance = atoi( acBuf );
Win4Assert( 0 != ulInstance );
return ulInstance;
}
BOOL IsPortSecure()
{
//
// Returns TRUE if the port is SSL secured, FALSE otherwise.
// There is no way to switch the setting on the fly; the only
// way to enable SSL is to mark the vdir as SSL secured in the
// metabase.
//
char acBuf[ 40 ];
ULONG cbBuf = sizeof acBuf;
if ( ! _pEcb->GetServerVariable( _pEcb->ConnID,
"HTTPS", //PORT_SECURE",
acBuf,
&cbBuf ) )
THROW( CException( HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER ) ) );
return ( !_stricmp( acBuf, "on" ) );
}
private:
EXTENSION_CONTROL_BLOCK *_pEcb;
BOOL _fWroteHeader;
UINT _codePage;
LCID _lcid;
WCHAR _wszLocale[16]; // Don't optimize long locales
unsigned _ccLocale;
};
DWORD ProcessWebRequest( CWebServer & webServer );
//+---------------------------------------------------------------------------
//
// Member: CWebServer::SetLCID, public
//
// Synopsis: Caches locale info for fast access
//
// Arguments: [lcid] -- Locale ID
// [pwszLocale] -- String version of LCID (e.g. "EN-US")
// [ccLocale] -- Size in characters of [pwszLocale], including null.
//
// History: 11-Jun-97 KyleP Created
//
//----------------------------------------------------------------------------
inline void CWebServer::SetLCID( LCID lcid,
WCHAR const * pwszLocale,
unsigned ccLocale )
{
if ( lcid == _lcid )
return;
if ( ccLocale <= sizeof(_wszLocale)/sizeof(WCHAR) )
{
RtlCopyMemory( _wszLocale, pwszLocale, ccLocale * sizeof(WCHAR) );
_ccLocale = ccLocale;
_lcid = lcid;
}
else
{
//
// Just take first component
//
WCHAR * pwc = wcschr( pwszLocale, L',' );
if ( (pwc - pwszLocale) < sizeof(_wszLocale)/sizeof(WCHAR) )
{
_ccLocale = CiPtrToUint( pwc - pwszLocale );
_lcid = lcid;
RtlCopyMemory( _wszLocale, pwszLocale, _ccLocale * sizeof(WCHAR) );
_wszLocale[_ccLocale] = 0;
_ccLocale++;
}
else
{
THROW( CException(E_FAIL) );
}
}
}