875 lines
18 KiB
C++
875 lines
18 KiB
C++
|
/*++
|
||
|
|
||
|
Copyright (c) 2000 Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
ssinc.hxx
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
This module contains the server side include processing code. We
|
||
|
aim for support as specified by iis\spec\ssi.doc. The code is based
|
||
|
on existing SSI support done in iis\svcs\w3\gateways\ssinc\ssinc.cxx.
|
||
|
|
||
|
Author:
|
||
|
|
||
|
Ming Lu (MingLu) 5-Apr-2000
|
||
|
|
||
|
--*/
|
||
|
|
||
|
#ifndef SSINC_HXX_INCLUDED
|
||
|
#define SSINC_HXX_INCLUDED
|
||
|
|
||
|
/************************************************************
|
||
|
* Macros
|
||
|
************************************************************/
|
||
|
|
||
|
//
|
||
|
// General Constants
|
||
|
//
|
||
|
|
||
|
#define SSI_MAX_PATH 1024
|
||
|
#define SSI_MAX_ERROR_MESSAGE 512
|
||
|
#define SSI_MAX_TIME_SIZE 256
|
||
|
#define SSI_MAX_NUMBER_STRING 32
|
||
|
#define SSI_INIT_VARIABLE_OUTPUT_SIZE 64
|
||
|
#define SSI_MAX_NESTED_INCLUDES 255
|
||
|
|
||
|
#define SSI_MAX_FORMAT_LEN 1024
|
||
|
|
||
|
#define SSI_HEADER "Content-Type: text/html\r\n\r\n"
|
||
|
#define SSI_ACCESS_DENIED "401 Authentication Required"
|
||
|
#define SSI_OBJECT_NOT_FOUND "404 Object Not Found"
|
||
|
#define SSI_DLL_NAME L"ssinc.dll"
|
||
|
|
||
|
//
|
||
|
// Default values for #CONFIG options
|
||
|
//
|
||
|
|
||
|
#define SSI_DEF_ERRMSG ""
|
||
|
#define SSI_DEF_ERRMSG_LEN sizeof( SSI_DEF_ERRMSG )
|
||
|
#define SSI_MAX_ERRMSG 256
|
||
|
|
||
|
#define SSI_DEF_TIMEFMT "%A %B %d %Y"
|
||
|
#define SSI_DEF_TIMEFMT_LEN sizeof( SSI_DEF_TIMEFMT )
|
||
|
#define SSI_MAX_TIMEFMT 256
|
||
|
|
||
|
#define SSI_DEF_SIZEFMT FALSE
|
||
|
|
||
|
//
|
||
|
// Specific lvalues for #CONFIG SIZEFMT and #CONFIG CMDECHO
|
||
|
//
|
||
|
|
||
|
#define SSI_DEF_BYTES "bytes"
|
||
|
#define SSI_DEF_BYTES_LEN sizeof( SSI_DEF_BYTES )
|
||
|
#define SSI_DEF_ABBREV "abbrev"
|
||
|
#define SSI_DEF_ABBREV_LEN sizeof( SSI_DEF_ABBREV )
|
||
|
|
||
|
//
|
||
|
// Other cache/signature constants
|
||
|
//
|
||
|
|
||
|
#define SIGNATURE_SEI 0x20494553
|
||
|
#define SIGNATURE_SEL 0x204C4553
|
||
|
|
||
|
#define SIGNATURE_SEI_FREE 0x66494553
|
||
|
#define SIGNATURE_SEL_FREE 0x664C4553
|
||
|
|
||
|
|
||
|
#define W3_PARAMETERS_KEY \
|
||
|
L"System\\CurrentControlSet\\Services\\w3svc\\Parameters"
|
||
|
|
||
|
//
|
||
|
// These are available SSI commands
|
||
|
//
|
||
|
|
||
|
enum SSI_COMMANDS
|
||
|
{
|
||
|
SSI_CMD_INCLUDE = 0,
|
||
|
SSI_CMD_ECHO,
|
||
|
SSI_CMD_FSIZE, // File size of specified file
|
||
|
SSI_CMD_FLASTMOD, // Last modified date of specified file
|
||
|
SSI_CMD_CONFIG, // Configure options
|
||
|
|
||
|
SSI_CMD_EXEC, // Execute CGI or CMD script
|
||
|
|
||
|
SSI_CMD_BYTERANGE, // Custom commands, not defined by NCSA
|
||
|
|
||
|
SSI_CMD_UNKNOWN
|
||
|
};
|
||
|
|
||
|
//
|
||
|
// These tags are essentially subcommands for the various SSI_COMMAND
|
||
|
// values
|
||
|
//
|
||
|
|
||
|
enum SSI_TAGS
|
||
|
{
|
||
|
SSI_TAG_FILE, // Used with include, fsize & flastmod
|
||
|
SSI_TAG_VIRTUAL,
|
||
|
|
||
|
SSI_TAG_VAR, // Used with echo
|
||
|
|
||
|
SSI_TAG_CMD, // Used with Exec
|
||
|
SSI_TAG_CGI,
|
||
|
SSI_TAG_ISA,
|
||
|
|
||
|
SSI_TAG_ERRMSG, // Used with Config
|
||
|
SSI_TAG_TIMEFMT,
|
||
|
SSI_TAG_SIZEFMT,
|
||
|
|
||
|
SSI_TAG_UNKNOWN
|
||
|
};
|
||
|
|
||
|
//
|
||
|
// Variables available to #ECHO VAR = "xxx" but not available in ISAPI
|
||
|
//
|
||
|
|
||
|
enum SSI_VARS
|
||
|
{
|
||
|
SSI_VAR_DOCUMENT_NAME = 0,
|
||
|
SSI_VAR_DOCUMENT_URI,
|
||
|
SSI_VAR_QUERY_STRING_UNESCAPED,
|
||
|
SSI_VAR_DATE_LOCAL,
|
||
|
SSI_VAR_DATE_GMT,
|
||
|
SSI_VAR_LAST_MODIFIED,
|
||
|
|
||
|
SSI_VAR_UNKNOWN
|
||
|
};
|
||
|
|
||
|
//
|
||
|
// SSI Exec types
|
||
|
//
|
||
|
|
||
|
enum SSI_EXEC_TYPE
|
||
|
{
|
||
|
SSI_EXEC_CMD = 1,
|
||
|
SSI_EXEC_CGI = 2,
|
||
|
SSI_EXEC_ISA = 4,
|
||
|
|
||
|
SSI_EXEC_UNKNOWN
|
||
|
};
|
||
|
|
||
|
//
|
||
|
// States of asynchronous SSI_INCLUDE_FILE processing
|
||
|
//
|
||
|
|
||
|
enum SIF_STATE
|
||
|
{
|
||
|
SIF_STATE_UNINITIALIZED,
|
||
|
SIF_STATE_INITIALIZED,
|
||
|
SIF_STATE_READY,
|
||
|
SIF_STATE_EXEC_CHILD_PENDING,
|
||
|
SIF_STATE_INCLUDE_CHILD_PENDING,
|
||
|
SIF_STATE_PROCESSING,
|
||
|
SIF_STATE_COMPLETED,
|
||
|
SIF_STATE_UNKNOWN
|
||
|
};
|
||
|
|
||
|
|
||
|
class SSI_INCLUDE_FILE;
|
||
|
class SSI_ELEMENT_LIST;
|
||
|
class SSI_ELEMENT_ITEM;
|
||
|
|
||
|
/************************************************************
|
||
|
* Structure and Class declarations
|
||
|
************************************************************/
|
||
|
|
||
|
/*++
|
||
|
|
||
|
class SSI_REQUEST
|
||
|
|
||
|
Master structure for SSI request.
|
||
|
Provides a "library" of utilities for use by higher level functions
|
||
|
|
||
|
Hierarchy:
|
||
|
|
||
|
SSI_REQUEST
|
||
|
- SSI_INCLUDE_FILE
|
||
|
- SSI_ELEMENT_LIST
|
||
|
- SSI_ELEMENT_ITEM
|
||
|
|
||
|
|
||
|
--*/
|
||
|
|
||
|
|
||
|
class SSI_REQUEST
|
||
|
{
|
||
|
private:
|
||
|
EXTENSION_CONTROL_BLOCK * _pECB;
|
||
|
STRU _strFilename;
|
||
|
STRU _strURL;
|
||
|
STRA _strUserMessage;
|
||
|
BOOL _fBaseFile;
|
||
|
HANDLE _hUser;
|
||
|
BOOL _fValid;
|
||
|
// Current include file (multiple stm files may be nested)
|
||
|
SSI_INCLUDE_FILE * _pSIF;
|
||
|
|
||
|
// Buffers used for async writes must stay around
|
||
|
LPSTR _pchErrorBuff;
|
||
|
CHAR _achTimeBuffer[ SSI_MAX_TIME_SIZE + 1 ];
|
||
|
DWORD _cbTimeBufferLen;
|
||
|
BUFFER _IOBuffer;
|
||
|
STRA _IOString;
|
||
|
|
||
|
// buffer length variable (to be used for async I/O)
|
||
|
DWORD _cbIOLen;
|
||
|
|
||
|
// Handle to file cache
|
||
|
W3_FILE_INFO_CACHE * _pFileCache;
|
||
|
|
||
|
// Lookaside
|
||
|
static ALLOC_CACHE_HANDLER * sm_pachSSIRequests;
|
||
|
|
||
|
public:
|
||
|
SSI_REQUEST( EXTENSION_CONTROL_BLOCK * pECB );
|
||
|
~SSI_REQUEST();
|
||
|
|
||
|
VOID *
|
||
|
operator new(
|
||
|
size_t size
|
||
|
)
|
||
|
{
|
||
|
DBG_ASSERT( size == sizeof( SSI_REQUEST ) );
|
||
|
DBG_ASSERT( sm_pachSSIRequests != NULL );
|
||
|
return sm_pachSSIRequests->Alloc();
|
||
|
}
|
||
|
|
||
|
VOID
|
||
|
operator delete(
|
||
|
VOID * pSSIRequest
|
||
|
)
|
||
|
{
|
||
|
DBG_ASSERT( pSSIRequest != NULL );
|
||
|
DBG_ASSERT( sm_pachSSIRequests != NULL );
|
||
|
|
||
|
DBG_REQUIRE( sm_pachSSIRequests->Free( pSSIRequest ) );
|
||
|
}
|
||
|
|
||
|
static
|
||
|
HRESULT
|
||
|
Initialize(
|
||
|
VOID
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Global initialization routine for SSI_REQUEST
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
None
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
HRESULT
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
ALLOC_CACHE_CONFIGURATION acConfig;
|
||
|
HRESULT hr = NO_ERROR;
|
||
|
|
||
|
//
|
||
|
// Setup allocation lookaside
|
||
|
//
|
||
|
|
||
|
acConfig.nConcurrency = 1;
|
||
|
acConfig.nThreshold = 100;
|
||
|
acConfig.cbSize = sizeof( SSI_REQUEST );
|
||
|
|
||
|
DBG_ASSERT( sm_pachSSIRequests == NULL );
|
||
|
|
||
|
sm_pachSSIRequests = new ALLOC_CACHE_HANDLER( "SSI_REQUEST",
|
||
|
&acConfig );
|
||
|
|
||
|
if ( sm_pachSSIRequests == NULL )
|
||
|
{
|
||
|
return HRESULT_FROM_WIN32( ERROR_NOT_ENOUGH_MEMORY );
|
||
|
}
|
||
|
|
||
|
return NO_ERROR;
|
||
|
}
|
||
|
|
||
|
static
|
||
|
VOID
|
||
|
Terminate(
|
||
|
VOID
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Terminate SSI_REQUEST globals
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
None
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
None
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
if ( sm_pachSSIRequests != NULL )
|
||
|
{
|
||
|
delete sm_pachSSIRequests;
|
||
|
sm_pachSSIRequests = NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
IsValid(
|
||
|
VOID
|
||
|
) const
|
||
|
{
|
||
|
return _fValid;
|
||
|
}
|
||
|
|
||
|
BOOL
|
||
|
SetCurrentIncludeFile(
|
||
|
SSI_INCLUDE_FILE * pSIF
|
||
|
)
|
||
|
{
|
||
|
_pSIF = pSIF;
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
EXTENSION_CONTROL_BLOCK *
|
||
|
GetECB(
|
||
|
VOID
|
||
|
) const
|
||
|
{
|
||
|
return _pECB;
|
||
|
}
|
||
|
|
||
|
|
||
|
HANDLE
|
||
|
GetUserToken(
|
||
|
VOID
|
||
|
)
|
||
|
{
|
||
|
return _hUser;
|
||
|
}
|
||
|
|
||
|
HRESULT
|
||
|
WriteToClient(
|
||
|
IN PVOID pBuffer,
|
||
|
IN DWORD dwBufLen,
|
||
|
OUT PDWORD pdwActualLen
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Write to data to client through ISAPI.
|
||
|
If sending a nulltermed string, dwBufLen should be strlen( pBuffer )
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
BOOL fRet = FALSE;
|
||
|
*pdwActualLen = dwBufLen;
|
||
|
|
||
|
if ( dwBufLen == 0 )
|
||
|
{
|
||
|
//
|
||
|
// If 0 bytes are sent asynchronously
|
||
|
// there will be no completion callback
|
||
|
//
|
||
|
|
||
|
return NO_ERROR;
|
||
|
}
|
||
|
|
||
|
fRet = _pECB->WriteClient( _pECB->ConnID,
|
||
|
pBuffer,
|
||
|
pdwActualLen,
|
||
|
HSE_IO_ASYNC );
|
||
|
if ( fRet )
|
||
|
{
|
||
|
return HRESULT_FROM_WIN32(ERROR_IO_PENDING);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return HRESULT_FROM_WIN32(GetLastError());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
HRESULT
|
||
|
SendResponseHeader(
|
||
|
IN CHAR * pszMessage,
|
||
|
IN CHAR * pszHeaders
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Send a response header to client through ISAPI
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
BOOL fRet = FALSE;
|
||
|
if( _pECB->ServerSupportFunction( _pECB->ConnID,
|
||
|
HSE_REQ_SEND_RESPONSE_HEADER,
|
||
|
pszMessage,
|
||
|
NULL,
|
||
|
( DWORD * ) pszHeaders ) )
|
||
|
{
|
||
|
return NO_ERROR;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return HRESULT_FROM_WIN32(GetLastError());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
HRESULT
|
||
|
GetVariable(
|
||
|
IN LPSTR pszVariableName,
|
||
|
OUT BUFFER * pbuffOutput
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Get an ISAPI variable
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
DWORD dwBufLen = SSI_INIT_VARIABLE_OUTPUT_SIZE;
|
||
|
BOOL fRet;
|
||
|
BOOL fSecondTry = FALSE;
|
||
|
|
||
|
TryAgain:
|
||
|
if ( !pbuffOutput->Resize( dwBufLen ) )
|
||
|
{
|
||
|
return HRESULT_FROM_WIN32(GetLastError());
|
||
|
}
|
||
|
|
||
|
fRet = _pECB->GetServerVariable( _pECB->ConnID,
|
||
|
pszVariableName,
|
||
|
pbuffOutput->QueryPtr(),
|
||
|
&dwBufLen );
|
||
|
if ( fRet )
|
||
|
{
|
||
|
return NO_ERROR;
|
||
|
}
|
||
|
else if ( !fSecondTry &&
|
||
|
GetLastError() == ERROR_INSUFFICIENT_BUFFER )
|
||
|
{
|
||
|
fSecondTry = TRUE;
|
||
|
goto TryAgain;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return HRESULT_FROM_WIN32(GetLastError());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
HRESULT
|
||
|
SSISendError(
|
||
|
IN DWORD dwMessageID,
|
||
|
IN LPSTR apszParms[]
|
||
|
);
|
||
|
|
||
|
BOOL
|
||
|
SetUserErrorMessage(
|
||
|
IN STRA * pstrUserMessage
|
||
|
)
|
||
|
{
|
||
|
if( FAILED ( _strUserMessage.Copy(*pstrUserMessage) ) )
|
||
|
{
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
//BUGBUG OTHER WAYS TO FIND OUT THE METABASE INFO
|
||
|
BOOL
|
||
|
IsExecDisabled(
|
||
|
VOID
|
||
|
) const
|
||
|
{
|
||
|
//return _pReq->QueryMetaData()->SSIExecDisabled();
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
HRESULT
|
||
|
SendCustomError(
|
||
|
HSE_CUSTOM_ERROR_INFO * pCustomErrorInfo
|
||
|
);
|
||
|
|
||
|
HRESULT
|
||
|
DoFLastMod(
|
||
|
IN STRU *,
|
||
|
IN STRA *,
|
||
|
IN SSI_ELEMENT_LIST *
|
||
|
);
|
||
|
|
||
|
HRESULT
|
||
|
DoFSize(
|
||
|
IN STRU *,
|
||
|
IN BOOL,
|
||
|
IN SSI_ELEMENT_LIST *
|
||
|
);
|
||
|
|
||
|
HRESULT
|
||
|
DoEchoISAPIVariable(
|
||
|
IN STRA *
|
||
|
);
|
||
|
|
||
|
HRESULT
|
||
|
DoEchoDocumentName(
|
||
|
IN STRU *
|
||
|
);
|
||
|
|
||
|
HRESULT
|
||
|
DoEchoDocumentURI(
|
||
|
IN STRU *
|
||
|
);
|
||
|
|
||
|
HRESULT
|
||
|
DoEchoQueryStringUnescaped(
|
||
|
VOID
|
||
|
);
|
||
|
|
||
|
HRESULT
|
||
|
DoEchoDateLocal(
|
||
|
IN STRA *
|
||
|
);
|
||
|
|
||
|
HRESULT
|
||
|
DoEchoDateGMT(
|
||
|
IN STRA *
|
||
|
);
|
||
|
|
||
|
HRESULT
|
||
|
DoEchoLastModified(
|
||
|
IN STRU *,
|
||
|
IN STRA *,
|
||
|
IN SSI_ELEMENT_LIST *
|
||
|
);
|
||
|
|
||
|
HRESULT
|
||
|
SendDate(
|
||
|
IN SYSTEMTIME *,
|
||
|
IN STRA *
|
||
|
);
|
||
|
|
||
|
HRESULT
|
||
|
LookupVirtualRoot(
|
||
|
IN WCHAR * pszVirtual,
|
||
|
OUT STRU * pstrPhysical,
|
||
|
IN DWORD dwAccess
|
||
|
);
|
||
|
|
||
|
HRESULT
|
||
|
DoWork(
|
||
|
DWORD dwError = NO_ERROR
|
||
|
);
|
||
|
|
||
|
HRESULT
|
||
|
PrepareSSI(
|
||
|
VOID
|
||
|
);
|
||
|
|
||
|
static
|
||
|
VOID WINAPI
|
||
|
HseIoCompletion(
|
||
|
IN EXTENSION_CONTROL_BLOCK * pECB,
|
||
|
IN PVOID pContext,
|
||
|
IN DWORD cbIO,
|
||
|
IN DWORD dwError
|
||
|
);
|
||
|
};
|
||
|
|
||
|
/*++
|
||
|
|
||
|
class SSI_INCLUDE_FILE
|
||
|
|
||
|
STM file may include other files. Each include file is represented by SSI_INCLUDE_FILE
|
||
|
|
||
|
--*/
|
||
|
|
||
|
|
||
|
class SSI_INCLUDE_FILE
|
||
|
{
|
||
|
private:
|
||
|
SSI_REQUEST * _pRequest;
|
||
|
// _strFileName - File to send
|
||
|
STRU _strFilename;
|
||
|
// _strURL - URL (from root) of this file
|
||
|
STRU _strURL;
|
||
|
// pParent - Parent SSI include file
|
||
|
SSI_INCLUDE_FILE * _pParent;
|
||
|
|
||
|
SIF_STATE _State;
|
||
|
|
||
|
SSI_ELEMENT_LIST * _pSEL;
|
||
|
LIST_ENTRY * _pCurrentEntry;
|
||
|
|
||
|
BOOL _fSELCached;
|
||
|
BOOL _fFileCached;
|
||
|
W3_FILE_INFO * _pOpenFile;
|
||
|
|
||
|
// Asynchronous child execute info
|
||
|
HSE_EXEC_URL_INFO _ExecUrlInfo;
|
||
|
// Size and time formating info
|
||
|
BOOL _fSizeFmtBytes;
|
||
|
STRA _strTimeFmt;
|
||
|
|
||
|
// Lookaside
|
||
|
static ALLOC_CACHE_HANDLER * sm_pachSSI_IncludeFiles;
|
||
|
|
||
|
|
||
|
public:
|
||
|
SSI_INCLUDE_FILE(
|
||
|
SSI_REQUEST * pRequest,
|
||
|
STRU & strFilename,
|
||
|
STRU & strURL,
|
||
|
SSI_INCLUDE_FILE * pParent
|
||
|
)
|
||
|
: _pRequest( pRequest ),
|
||
|
_pParent( pParent ),
|
||
|
_pSEL( NULL ),
|
||
|
_pCurrentEntry( NULL ),
|
||
|
_fSELCached( FALSE ),
|
||
|
_fFileCached( FALSE ),
|
||
|
_pOpenFile( NULL ),
|
||
|
_fSizeFmtBytes (SSI_DEF_SIZEFMT),
|
||
|
_State( SIF_STATE_UNINITIALIZED )
|
||
|
{
|
||
|
if ( FAILED( _strFilename.Copy( strFilename ) ) )
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
if ( FAILED( _strURL.Copy( strURL ) ) )
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if ( FAILED( _strTimeFmt.Resize( sizeof( SSI_DEF_TIMEFMT ) + 1 ) ) )
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
strcpy( ( CHAR * )_strTimeFmt.QueryStr(), SSI_DEF_TIMEFMT );
|
||
|
|
||
|
|
||
|
SetState( SIF_STATE_INITIALIZED );
|
||
|
}
|
||
|
|
||
|
~SSI_INCLUDE_FILE( VOID );
|
||
|
|
||
|
VOID *
|
||
|
operator new(
|
||
|
size_t size
|
||
|
)
|
||
|
{
|
||
|
DBG_ASSERT( size == sizeof( SSI_INCLUDE_FILE ) );
|
||
|
DBG_ASSERT( sm_pachSSI_IncludeFiles != NULL );
|
||
|
return sm_pachSSI_IncludeFiles->Alloc();
|
||
|
}
|
||
|
|
||
|
VOID
|
||
|
operator delete(
|
||
|
VOID * pSSI_IncludeFile
|
||
|
)
|
||
|
{
|
||
|
DBG_ASSERT( pSSI_IncludeFile != NULL );
|
||
|
DBG_ASSERT( sm_pachSSI_IncludeFiles != NULL );
|
||
|
|
||
|
DBG_REQUIRE( sm_pachSSI_IncludeFiles->Free( pSSI_IncludeFile ) );
|
||
|
}
|
||
|
|
||
|
static
|
||
|
HRESULT
|
||
|
Initialize(
|
||
|
VOID
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Global initialization routine for SSI_REQUEST
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
None
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
HRESULT
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
ALLOC_CACHE_CONFIGURATION acConfig;
|
||
|
HRESULT hr = NO_ERROR;
|
||
|
|
||
|
//
|
||
|
// Setup allocation lookaside
|
||
|
//
|
||
|
|
||
|
acConfig.nConcurrency = 1;
|
||
|
acConfig.nThreshold = 100;
|
||
|
acConfig.cbSize = sizeof( SSI_INCLUDE_FILE );
|
||
|
|
||
|
DBG_ASSERT( sm_pachSSI_IncludeFiles == NULL );
|
||
|
|
||
|
sm_pachSSI_IncludeFiles = new ALLOC_CACHE_HANDLER( "SSI_INCLUDE_FILE",
|
||
|
&acConfig );
|
||
|
|
||
|
if ( sm_pachSSI_IncludeFiles == NULL )
|
||
|
{
|
||
|
return HRESULT_FROM_WIN32( ERROR_NOT_ENOUGH_MEMORY );
|
||
|
}
|
||
|
|
||
|
return NO_ERROR;
|
||
|
}
|
||
|
|
||
|
static
|
||
|
VOID
|
||
|
Terminate(
|
||
|
VOID
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Terminate SSI_REQUEST globals
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
None
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
None
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
if ( sm_pachSSI_IncludeFiles != NULL )
|
||
|
{
|
||
|
delete sm_pachSSI_IncludeFiles;
|
||
|
sm_pachSSI_IncludeFiles = NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
SSI_INCLUDE_FILE *
|
||
|
GetParent( VOID )
|
||
|
{
|
||
|
return _pParent;
|
||
|
}
|
||
|
|
||
|
LIST_ENTRY *
|
||
|
GetCurrentEntry( VOID )
|
||
|
{
|
||
|
return _pCurrentEntry;
|
||
|
}
|
||
|
|
||
|
BOOL IsCompleted( VOID )
|
||
|
{
|
||
|
return ( _State == SIF_STATE_COMPLETED );
|
||
|
}
|
||
|
|
||
|
BOOL IsValid( VOID )
|
||
|
{
|
||
|
return ( _State != SIF_STATE_UNINITIALIZED );
|
||
|
}
|
||
|
|
||
|
BOOL IsBaseFile( VOID )
|
||
|
{
|
||
|
return ( _pParent == NULL );
|
||
|
}
|
||
|
|
||
|
BOOL IsRecursiveInclude( IN STRU & strFilename )
|
||
|
{
|
||
|
if ( !_wcsicmp( strFilename.QueryStr(),
|
||
|
_strFilename.QueryStr() ) )
|
||
|
{
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
if ( !_pParent )
|
||
|
{
|
||
|
return FALSE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return _pParent->IsRecursiveInclude( strFilename );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
VOID
|
||
|
SetState(
|
||
|
SIF_STATE State
|
||
|
)
|
||
|
{
|
||
|
_State = State;
|
||
|
}
|
||
|
|
||
|
HRESULT
|
||
|
Prepare(
|
||
|
VOID
|
||
|
);
|
||
|
|
||
|
HRESULT
|
||
|
BuildSEL(
|
||
|
VOID
|
||
|
);
|
||
|
|
||
|
HRESULT
|
||
|
Process(
|
||
|
VOID
|
||
|
);
|
||
|
|
||
|
HRESULT
|
||
|
DoWork(
|
||
|
DWORD dwError = NO_ERROR
|
||
|
);
|
||
|
|
||
|
HRESULT
|
||
|
GetFullPath(
|
||
|
IN SSI_ELEMENT_ITEM * pSEI,
|
||
|
OUT STRU * pstrPath,
|
||
|
IN DWORD dwPermission,
|
||
|
IN STRU * pstrCurrentURL,
|
||
|
OUT STRU * pstrURL = NULL
|
||
|
);
|
||
|
|
||
|
static
|
||
|
BOOL
|
||
|
ParseSSITag(
|
||
|
IN OUT CHAR * * ppchFilePos,
|
||
|
IN CHAR * pchEOF,
|
||
|
OUT BOOL * pfValidTag,
|
||
|
OUT SSI_COMMANDS * pCommandType,
|
||
|
OUT SSI_TAGS * pTagType,
|
||
|
OUT CHAR * pszTagString
|
||
|
);
|
||
|
|
||
|
static
|
||
|
CHAR *
|
||
|
SSISkipTo(
|
||
|
IN CHAR * pchFilePos,
|
||
|
IN CHAR ch,
|
||
|
IN CHAR * pchEOF
|
||
|
);
|
||
|
|
||
|
static
|
||
|
CHAR *
|
||
|
SSISkipWhite(
|
||
|
IN CHAR * pchFilePos,
|
||
|
IN CHAR * pchEOF
|
||
|
);
|
||
|
|
||
|
static
|
||
|
BOOL
|
||
|
FindInternalVariable(
|
||
|
IN STRA * pstrVariable,
|
||
|
OUT PDWORD pdwID
|
||
|
);
|
||
|
};
|
||
|
#endif
|
||
|
|