939 lines
23 KiB
C++
939 lines
23 KiB
C++
|
/**********************************************************************/
|
|||
|
/** Microsoft Windows NT **/
|
|||
|
/** Copyright(c) Microsoft Corp., 1995 **/
|
|||
|
/**********************************************************************/
|
|||
|
|
|||
|
/*
|
|||
|
extmap.cxx
|
|||
|
|
|||
|
This module contains the extension mapping to CGI or BGI scripts.
|
|||
|
|
|||
|
|
|||
|
FILE HISTORY:
|
|||
|
Johnl 22-Sep-1995 Created
|
|||
|
|
|||
|
*/
|
|||
|
|
|||
|
#include "w3p.hxx"
|
|||
|
#include <rpc.h>
|
|||
|
#include <rpcndr.h>
|
|||
|
#include <mbstring.h>
|
|||
|
|
|||
|
//
|
|||
|
// Name of the value under the parameters key containing the list of
|
|||
|
// script extension to BGI/CGI binaries.
|
|||
|
//
|
|||
|
|
|||
|
#define HTTP_EXT_MAPS "Script Map"
|
|||
|
|
|||
|
char Get[] = "GET";
|
|||
|
|
|||
|
#define GET_SIZE (sizeof("GET"))
|
|||
|
|
|||
|
//
|
|||
|
// This is the maximum size for a script map extension
|
|||
|
//
|
|||
|
#define MAX_EXT_LEN 128
|
|||
|
|
|||
|
//
|
|||
|
// This list is the extension maps found in the registry - they always get
|
|||
|
// appended to the end of all extension mappings that are added to a particular
|
|||
|
// URI.
|
|||
|
//
|
|||
|
|
|||
|
static BOOL fInitialized = FALSE;
|
|||
|
|
|||
|
class EXT_MAP_ITEM
|
|||
|
{
|
|||
|
public:
|
|||
|
|
|||
|
EXT_MAP_ITEM( const char * pszExtension,
|
|||
|
const char * pszImage,
|
|||
|
const DWORD dwFlags,
|
|||
|
const CHAR * pszExclusions,
|
|||
|
const DWORD dwExclusionLength)
|
|||
|
: _strExt ( pszExtension ),
|
|||
|
_strImage ( pszImage ),
|
|||
|
_GatewayType( GATEWAY_UNKNOWN ),
|
|||
|
_cchExt ( 0 ),
|
|||
|
_dwFlags ( dwFlags ),
|
|||
|
_fGetValid (0),
|
|||
|
_dwInclusionCount ( 0 ),
|
|||
|
_ppszInclusionTable ( NULL ),
|
|||
|
_pszInclusions ( NULL )
|
|||
|
{
|
|||
|
DWORD cch;
|
|||
|
_fValid = _strExt.IsValid() && _strImage.IsValid() && ExpandImage();
|
|||
|
|
|||
|
if ( _fValid )
|
|||
|
{
|
|||
|
const CHAR * pchtmp = pszImage;
|
|||
|
|
|||
|
_cchExt = _strExt.QueryCCH();
|
|||
|
|
|||
|
//
|
|||
|
// Determine if this is a CGI or BGI gateway
|
|||
|
//
|
|||
|
|
|||
|
while ( pchtmp = strchr( pchtmp + 1, '.' ))
|
|||
|
{
|
|||
|
if ( !_strnicmp( pchtmp, ".exe", 4 ))
|
|||
|
{
|
|||
|
_GatewayType = GATEWAY_CGI;
|
|||
|
}
|
|||
|
else if ( !_strnicmp( pchtmp, ".dll", 4 ))
|
|||
|
{
|
|||
|
_GatewayType = GATEWAY_BGI;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (!strcmp(pszExtension, "*"))
|
|||
|
{
|
|||
|
_fWildcard = TRUE;
|
|||
|
_dwFlags |= MD_SCRIPTMAPFLAG_WILDCARD;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
_fWildcard = FALSE;
|
|||
|
_dwFlags &= ~MD_SCRIPTMAPFLAG_WILDCARD;
|
|||
|
}
|
|||
|
|
|||
|
if (pszExclusions != NULL)
|
|||
|
{
|
|||
|
const CHAR *pszTemp;
|
|||
|
char *pszDest;
|
|||
|
|
|||
|
_pszInclusions = new char[dwExclusionLength];
|
|||
|
|
|||
|
if (_pszInclusions == NULL)
|
|||
|
{
|
|||
|
_fValid = FALSE;
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
_dwInclusionCount = 1;
|
|||
|
pszTemp = pszExclusions;
|
|||
|
pszDest = _pszInclusions;
|
|||
|
|
|||
|
while (*pszTemp != '\0')
|
|||
|
{
|
|||
|
CHAR ch;
|
|||
|
|
|||
|
ch = *pszTemp;
|
|||
|
pszTemp++;
|
|||
|
|
|||
|
if (ch != ',')
|
|||
|
{
|
|||
|
*pszDest = ch;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
*pszDest = '\0';
|
|||
|
|
|||
|
_dwInclusionCount++;
|
|||
|
}
|
|||
|
|
|||
|
pszDest++;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
*pszDest = '\0';
|
|||
|
|
|||
|
_ppszInclusionTable = new char *[_dwInclusionCount];
|
|||
|
|
|||
|
if (_ppszInclusionTable == NULL)
|
|||
|
{
|
|||
|
_fValid = FALSE;
|
|||
|
return;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
DWORD i;
|
|||
|
DWORD dwPos;
|
|||
|
|
|||
|
pszTemp = _pszInclusions;
|
|||
|
|
|||
|
i = 0;
|
|||
|
|
|||
|
do {
|
|||
|
|
|||
|
_ppszInclusionTable[i] = (CHAR *)pszTemp;
|
|||
|
|
|||
|
if ( _fGetValid )
|
|||
|
{
|
|||
|
dwPos = 0;
|
|||
|
}
|
|||
|
|
|||
|
while (*pszTemp != '\0')
|
|||
|
{
|
|||
|
if (dwPos < GET_SIZE)
|
|||
|
{
|
|||
|
if (*pszTemp == Get[dwPos])
|
|||
|
{
|
|||
|
dwPos++;
|
|||
|
|
|||
|
if (dwPos == (GET_SIZE - 1))
|
|||
|
{
|
|||
|
if (*(pszTemp+1) == '\0')
|
|||
|
{
|
|||
|
_fGetValid = TRUE;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
dwPos = GET_SIZE;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
dwPos = GET_SIZE;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
pszTemp++;
|
|||
|
}
|
|||
|
|
|||
|
DBG_ASSERT(*pszTemp == '\0');
|
|||
|
|
|||
|
pszTemp++;
|
|||
|
|
|||
|
i++;
|
|||
|
|
|||
|
} while (i < _dwInclusionCount );
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
_dwInclusionCount = 0;
|
|||
|
_ppszInclusionTable = NULL;
|
|||
|
_pszInclusions = NULL;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
~EXT_MAP_ITEM( )
|
|||
|
{
|
|||
|
delete _ppszInclusionTable;
|
|||
|
delete _pszInclusions;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
GATEWAY_TYPE QueryGatewayType( VOID ) const
|
|||
|
{ return _GatewayType; }
|
|||
|
|
|||
|
const CHAR * QueryScript( VOID ) const
|
|||
|
{ return _strImage.QueryStr(); }
|
|||
|
|
|||
|
const CHAR * QueryExtension( VOID ) const
|
|||
|
{ return _strExt.QueryStr(); }
|
|||
|
|
|||
|
const BOOL AllowedOnReadDir()
|
|||
|
{ return _dwFlags & MD_SCRIPTMAPFLAG_SCRIPT; }
|
|||
|
|
|||
|
const DWORD QueryFlags()
|
|||
|
{ return _dwFlags; }
|
|||
|
|
|||
|
DWORD QueryCCHExt( VOID ) const
|
|||
|
{ return _cchExt; }
|
|||
|
|
|||
|
BOOL IsValid( VOID ) const
|
|||
|
{ return _fValid; }
|
|||
|
|
|||
|
BOOL IsWildCard( VOID ) const
|
|||
|
{ return _fWildcard; }
|
|||
|
|
|||
|
BOOL IsGetValid( VOID ) const
|
|||
|
{ return _fGetValid; }
|
|||
|
|
|||
|
BOOL ExpandImage( VOID );
|
|||
|
|
|||
|
BOOL CheckInclusions(
|
|||
|
const CHAR *pszVerb
|
|||
|
);
|
|||
|
|
|||
|
LIST_ENTRY _ListEntry;
|
|||
|
|
|||
|
private:
|
|||
|
|
|||
|
STR _strExt;
|
|||
|
STR _strImage;
|
|||
|
DWORD _cchExt;
|
|||
|
GATEWAY_TYPE _GatewayType;
|
|||
|
DWORD _fValid:1;
|
|||
|
DWORD _fWildcard:1;
|
|||
|
DWORD _fGetValid:1;
|
|||
|
DWORD _dwFlags;
|
|||
|
DWORD _dwInclusionCount;
|
|||
|
CHAR **_ppszInclusionTable;
|
|||
|
CHAR *_pszInclusions;
|
|||
|
};
|
|||
|
|
|||
|
|
|||
|
BOOL
|
|||
|
EXT_MAP_ITEM::ExpandImage( VOID )
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Expand any embedded environment variables in the image.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
TRUE if successful, FALSE if not.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
DWORD cbRet = 0;
|
|||
|
TCHAR achBuffer[ MAX_PATH + 1 ];
|
|||
|
DWORD cbBufLen = sizeof( achBuffer );
|
|||
|
|
|||
|
cbRet = ExpandEnvironmentStringsA( _strImage.QueryStr(),
|
|||
|
achBuffer,
|
|||
|
cbBufLen );
|
|||
|
if ( !cbRet || ( cbRet > cbBufLen ) )
|
|||
|
{
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
return _strImage.Copy( achBuffer );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Private globals.
|
|||
|
//
|
|||
|
|
|||
|
BOOL
|
|||
|
W3_METADATA::BuildExtMap(
|
|||
|
CHAR *pszExtMapList
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Builds the extension mapping into the metadata. The input string is
|
|||
|
a multi-sz of comma seperated ext, image name strings.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
TRUE if successfull, FALSE if not.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
EXT_MAP_ITEM * pExtMap;
|
|||
|
EXT_MAP_ITEM * pWCExtMapItem;
|
|||
|
LIST_ENTRY * pEntry;
|
|||
|
|
|||
|
m_fAnyExtAllowedOnReadDir = FALSE;
|
|||
|
|
|||
|
m_dwMaxExtLen = 0;
|
|||
|
|
|||
|
do
|
|||
|
{
|
|||
|
|
|||
|
CHAR *pszExt;
|
|||
|
CHAR *pszImage;
|
|||
|
CHAR *pszFlags;
|
|||
|
CHAR *pszExclusions;
|
|||
|
CHAR *pszTemp;
|
|||
|
CHAR *pszTemp2;
|
|||
|
CHAR *pszTemp3;
|
|||
|
DWORD dwExclusionSize;
|
|||
|
DWORD dwExtSize;
|
|||
|
|
|||
|
pszExt = pszExtMapList;
|
|||
|
|
|||
|
// Find the end of the extension, and temporarily NULL terminate it.
|
|||
|
|
|||
|
pszImage = strchr(pszExt, ',');
|
|||
|
|
|||
|
if (pszImage == NULL) {
|
|||
|
// Bad script map entry
|
|||
|
SetLastError(ERROR_INVALID_DATA);
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
pszTemp = pszImage++;
|
|||
|
*pszTemp = '\0';
|
|||
|
|
|||
|
pszFlags = strchr(pszImage, ',');
|
|||
|
|
|||
|
if (pszFlags == NULL) {
|
|||
|
// Bad script map entry
|
|||
|
SetLastError(ERROR_INVALID_DATA);
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
pszTemp2 = pszFlags++;
|
|||
|
*pszTemp2 = '\0';
|
|||
|
|
|||
|
//
|
|||
|
// HOTFIX: make sure the extension is not too long to be copied to
|
|||
|
// our static buffer.
|
|||
|
//
|
|||
|
dwExtSize = strlen(pszExt);
|
|||
|
if (dwExtSize > MAX_EXT_LEN) {
|
|||
|
// Bad script map entry
|
|||
|
SetLastError(ERROR_INVALID_DATA);
|
|||
|
return FALSE;
|
|||
|
} else if (dwExtSize > m_dwMaxExtLen) {
|
|||
|
m_dwMaxExtLen = dwExtSize;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// See if there's any excluded methods. If there are, break them out.
|
|||
|
//
|
|||
|
|
|||
|
pszExclusions = strchr(pszFlags, ',');
|
|||
|
|
|||
|
if (pszExclusions != NULL)
|
|||
|
{
|
|||
|
pszTemp3 = pszExclusions++;
|
|||
|
*pszTemp3 = '\0';
|
|||
|
dwExclusionSize = strlen(pszExclusions) + 1;
|
|||
|
pszExtMapList = pszExclusions + dwExclusionSize;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
pszExtMapList = pszFlags + strlen(pszFlags) + 1;
|
|||
|
dwExclusionSize = 0;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// HOTFIX: Now convert extension to lower case so we can avoid
|
|||
|
// multi-byte string compares that cause lock contention.
|
|||
|
//
|
|||
|
|
|||
|
IISstrlwr( (PUCHAR) pszExt );
|
|||
|
|
|||
|
//
|
|||
|
// Note we OR in the notransmit flag on *all* script mappings!
|
|||
|
//
|
|||
|
|
|||
|
pExtMap = new EXT_MAP_ITEM( pszExt,
|
|||
|
pszImage,
|
|||
|
((DWORD) atoi( pszFlags )),
|
|||
|
pszExclusions,
|
|||
|
dwExclusionSize);
|
|||
|
|
|||
|
*pszTemp = ',';
|
|||
|
*pszTemp2 = ',';
|
|||
|
|
|||
|
if (pszExclusions != NULL)
|
|||
|
{
|
|||
|
*pszTemp3 = '\0';
|
|||
|
}
|
|||
|
|
|||
|
if ( !pExtMap ||
|
|||
|
!pExtMap->IsValid() )
|
|||
|
{
|
|||
|
delete pExtMap;
|
|||
|
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
if (!pExtMap->IsWildCard())
|
|||
|
{
|
|||
|
InsertTailList( &m_ExtMapHead, &pExtMap->_ListEntry );
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
|
|||
|
pWCExtMapItem = (EXT_MAP_ITEM *)QueryWildcardMapping();
|
|||
|
|
|||
|
if (pWCExtMapItem != NULL)
|
|||
|
{
|
|||
|
delete pWCExtMapItem;
|
|||
|
}
|
|||
|
|
|||
|
SetWildcardMapping( pExtMap );
|
|||
|
}
|
|||
|
|
|||
|
if ( pExtMap->QueryFlags() )
|
|||
|
{
|
|||
|
m_fAnyExtAllowedOnReadDir = TRUE;
|
|||
|
}
|
|||
|
|
|||
|
} while ( *pszExtMapList != '\0');
|
|||
|
|
|||
|
return TRUE;
|
|||
|
|
|||
|
} // W3_METADATA::BuildExtMap
|
|||
|
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
W3_METADATA::TerminateExtMap(
|
|||
|
VOID
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Cleans up the extension map list
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
LIST_ENTRY * pEntry;
|
|||
|
EXT_MAP_ITEM * pExtMap;
|
|||
|
|
|||
|
while ( !IsListEmpty( &m_ExtMapHead ))
|
|||
|
{
|
|||
|
pExtMap = CONTAINING_RECORD( m_ExtMapHead.Flink,
|
|||
|
EXT_MAP_ITEM,
|
|||
|
_ListEntry );
|
|||
|
|
|||
|
RemoveEntryList( &pExtMap->_ListEntry );
|
|||
|
|
|||
|
delete pExtMap;
|
|||
|
}
|
|||
|
|
|||
|
pExtMap = (EXT_MAP_ITEM *)QueryWildcardMapping();
|
|||
|
|
|||
|
if (pExtMap != NULL)
|
|||
|
{
|
|||
|
delete pExtMap;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
} // W3_METADATA::TerminateExtMap
|
|||
|
|
|||
|
BOOL
|
|||
|
EXT_MAP_ITEM::CheckInclusions(
|
|||
|
const CHAR *pszVerb
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Check the extension map list to see if the input verb is included.
|
|||
|
If it is, we return TRUE, otherwise we return FALSE.
|
|||
|
--*/
|
|||
|
{
|
|||
|
DWORD i;
|
|||
|
|
|||
|
//
|
|||
|
// Special case for EMPTY script map. Allow all verbs
|
|||
|
//
|
|||
|
|
|||
|
if (0 == _dwInclusionCount)
|
|||
|
{
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
for (i = 0; i < _dwInclusionCount; i++)
|
|||
|
{
|
|||
|
if (!_stricmp(pszVerb, _ppszInclusionTable[i]))
|
|||
|
{
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return FALSE;
|
|||
|
|
|||
|
} // EXT_MAP_ITEM::CheckInclusions
|
|||
|
|
|||
|
BOOL
|
|||
|
W3_METADATA::LookupExtMap(
|
|||
|
IN const CHAR * pchExt,
|
|||
|
IN BOOL fNoWildcards,
|
|||
|
OUT STR * pstrGatewayImage,
|
|||
|
OUT GATEWAY_TYPE * pGatewayType,
|
|||
|
OUT DWORD * pcchExt,
|
|||
|
OUT BOOL * pfImageInURL,
|
|||
|
OUT BOOL * pfVerbExcluded,
|
|||
|
OUT DWORD * pdwFlags,
|
|||
|
IN const CHAR *pszVerb,
|
|||
|
IN enum HTTP_VERB Verb,
|
|||
|
IN OUT PVOID * ppvExtMapInfo
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Finds the admin specified mapping between a script extension and the
|
|||
|
associated CGI or BGI binary to run (or load).
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
pchExt - Pointer to possible extension to be mapped (i.e., '.pl')
|
|||
|
pstrGatewayImage - Receives the mapped binary image name
|
|||
|
pGatewayType - Specifies whether this is a BGI, CGI or MAP extension type
|
|||
|
pcchExt - Returns length of extension (including dot)
|
|||
|
pfImageInURL - Indicates an image was found encoded in the URL and not
|
|||
|
from a script extension mapping
|
|||
|
pdwFlags - Returns extension flags
|
|||
|
ppvExtMapInfo - Cached extension map info. If *ppvExtMapInfo is NULL on
|
|||
|
input, then set to the matched PEXT_MAP_ITEM. If not NULL
|
|||
|
on input, then it is used instead of doing lookup.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
EXT_MAP_ITEM * pExtMapItem;
|
|||
|
DWORD cchTillEOS;
|
|||
|
BOOL fRet;
|
|||
|
LIST_ENTRY * pEntry;
|
|||
|
BOOL bFoundMatch = FALSE;
|
|||
|
BOOL fUseExtMapInfo = *ppvExtMapInfo != NULL;
|
|||
|
|
|||
|
*pGatewayType = GATEWAY_UNKNOWN;
|
|||
|
*pfVerbExcluded = FALSE;
|
|||
|
|
|||
|
//
|
|||
|
// Check for wildcard mapping first
|
|||
|
//
|
|||
|
|
|||
|
if (!fNoWildcards)
|
|||
|
{
|
|||
|
pExtMapItem = (EXT_MAP_ITEM *)QueryWildcardMapping();
|
|||
|
|
|||
|
if (pExtMapItem != NULL)
|
|||
|
{
|
|||
|
if (Verb == HTV_GET && pExtMapItem->IsGetValid())
|
|||
|
{
|
|||
|
bFoundMatch = TRUE;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
// If verb is not included, don't return the * script map.
|
|||
|
// Instead, continue to look for a script map match.
|
|||
|
|
|||
|
bFoundMatch = pExtMapItem->CheckInclusions( pszVerb );
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Look for the exact extension mapping if there's no wildcard
|
|||
|
//
|
|||
|
|
|||
|
if (!bFoundMatch && pchExt != NULL)
|
|||
|
{
|
|||
|
if ( fUseExtMapInfo )
|
|||
|
{
|
|||
|
//
|
|||
|
// If caller passed in a non-NULL pExtMapInfo, then use it
|
|||
|
// instead of doing a manual lookup
|
|||
|
//
|
|||
|
|
|||
|
if ( *ppvExtMapInfo != EXTMAP_UNKNOWN_PTR )
|
|||
|
{
|
|||
|
pExtMapItem = (EXT_MAP_ITEM*) *ppvExtMapInfo;
|
|||
|
bFoundMatch = TRUE;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
//
|
|||
|
// This buffer, rgchExtBuffer, holds a copy of a portion of a URL
|
|||
|
// which we are testing to see if it's a known extension. We copy
|
|||
|
// into this buffer so we can convert the extension to lower case
|
|||
|
// without disrupting the original.
|
|||
|
//
|
|||
|
CHAR rgchExtBuffer[MAX_EXT_LEN + 4];
|
|||
|
DWORD dwLength;
|
|||
|
|
|||
|
DBG_ASSERT( *pchExt == '.' );
|
|||
|
|
|||
|
//
|
|||
|
// HOTFIX: Now convert extension to lower case so we can avoid
|
|||
|
// multi-byte string compares that cause lock contention.
|
|||
|
//
|
|||
|
// Since we don't want to risk modifying the orignal URL, we
|
|||
|
// copy it into another buffer first.
|
|||
|
//
|
|||
|
|
|||
|
cchTillEOS = strlen( pchExt );
|
|||
|
|
|||
|
dwLength = min(cchTillEOS, m_dwMaxExtLen + 1);
|
|||
|
memcpy(rgchExtBuffer, pchExt, dwLength);
|
|||
|
rgchExtBuffer[ dwLength ] = 0;
|
|||
|
|
|||
|
IISstrlwr( (PUCHAR) rgchExtBuffer );
|
|||
|
|
|||
|
//
|
|||
|
// Look through the list of mappings
|
|||
|
//
|
|||
|
|
|||
|
for ( pEntry = m_ExtMapHead.Flink;
|
|||
|
!bFoundMatch && pEntry != &m_ExtMapHead;
|
|||
|
pEntry = pEntry->Flink )
|
|||
|
{
|
|||
|
pExtMapItem = CONTAINING_RECORD( pEntry, EXT_MAP_ITEM, _ListEntry );
|
|||
|
|
|||
|
if ( cchTillEOS >= pExtMapItem->QueryCCHExt() &&
|
|||
|
(pchExt[pExtMapItem->QueryCCHExt()] == '/' ||
|
|||
|
pchExt[pExtMapItem->QueryCCHExt()] == '\0' ) &&
|
|||
|
!memcmp( rgchExtBuffer,
|
|||
|
pExtMapItem->QueryExtension(),
|
|||
|
pExtMapItem->QueryCCHExt())
|
|||
|
)
|
|||
|
{
|
|||
|
bFoundMatch = TRUE;
|
|||
|
*ppvExtMapInfo = pExtMapItem;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (bFoundMatch)
|
|||
|
{
|
|||
|
*pGatewayType = pExtMapItem->QueryGatewayType();
|
|||
|
*pcchExt = pExtMapItem->QueryCCHExt();
|
|||
|
*pfImageInURL = FALSE;
|
|||
|
*pdwFlags = pExtMapItem->QueryFlags();
|
|||
|
|
|||
|
//
|
|||
|
// Check that verb is included. If it isn't, we're still going to return
|
|||
|
// this item. Just indicate that the verb was excluded.
|
|||
|
//
|
|||
|
|
|||
|
if (Verb != HTV_GET || !pExtMapItem->IsGetValid())
|
|||
|
{
|
|||
|
*pfVerbExcluded = !pExtMapItem->CheckInclusions(pszVerb);
|
|||
|
}
|
|||
|
|
|||
|
fRet = pstrGatewayImage->Copy( pExtMapItem->QueryScript() );
|
|||
|
|
|||
|
if ( !_stricmp( pExtMapItem->QueryScript(), "nogateway" ) )
|
|||
|
{
|
|||
|
*pGatewayType = GATEWAY_NONE;
|
|||
|
}
|
|||
|
|
|||
|
return fRet;
|
|||
|
}
|
|||
|
|
|||
|
if ( !pchExt || fUseExtMapInfo )
|
|||
|
{
|
|||
|
if ( !fUseExtMapInfo )
|
|||
|
{
|
|||
|
*ppvExtMapInfo = EXTMAP_UNKNOWN_PTR;
|
|||
|
}
|
|||
|
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Either the image will be specified in the URL or not found, so
|
|||
|
// just indicate it's in the URL. Not found has precedence.
|
|||
|
//
|
|||
|
|
|||
|
*pfImageInURL = TRUE;
|
|||
|
*pdwFlags = 0;
|
|||
|
|
|||
|
//
|
|||
|
// Look for CGI or BGI scripts in the URL itself
|
|||
|
//
|
|||
|
|
|||
|
if ( cchTillEOS >= 4 &&
|
|||
|
(*(pchExt+4) == TEXT('/') ||
|
|||
|
*(pchExt+4) == TEXT('\0')) )
|
|||
|
{
|
|||
|
*pcchExt = 4;
|
|||
|
|
|||
|
//
|
|||
|
// Don't confuse a menu map request with a gateway request
|
|||
|
//
|
|||
|
|
|||
|
if ( !::_tcsnicmp( TEXT(".MAP"), pchExt, 4 ))
|
|||
|
{
|
|||
|
*pGatewayType = GATEWAY_MAP;
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
if ( !::_tcsnicmp( TEXT(".EXE"), pchExt, 4 ) ||
|
|||
|
!::_tcsnicmp( TEXT(".CGI"), pchExt, 4 ) ||
|
|||
|
!::_tcsnicmp( TEXT(".COM"), pchExt, 4 ))
|
|||
|
{
|
|||
|
*pGatewayType = GATEWAY_CGI;
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
else if (!::_tcsnicmp( TEXT(".DLL"), pchExt, 4 ) ||
|
|||
|
!::_tcsnicmp( TEXT(".ISA"), pchExt, 4 ) )
|
|||
|
{
|
|||
|
*pGatewayType = GATEWAY_BGI;
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
*ppvExtMapInfo = EXTMAP_UNKNOWN_PTR;
|
|||
|
|
|||
|
return TRUE;
|
|||
|
} // W3_METADATA::LookupExtMap
|
|||
|
|
|||
|
|
|||
|
APIERR
|
|||
|
ReadRegistryExtMap(
|
|||
|
VOID
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Builds the extension mapping from the registry
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
NO_ERROR if successful, win32 error code on failure
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
HKEY hkeyParam;
|
|||
|
DWORD dwDisposition;
|
|||
|
LIST_ENTRY pEntry;
|
|||
|
APIERR err;
|
|||
|
DWORD i = 0;
|
|||
|
DWORD dwRegType;
|
|||
|
MB mb( (IMDCOM*) g_pInetSvc->QueryMDObject() );
|
|||
|
MULTISZ msz;
|
|||
|
BOOL fNeedToWrite = FALSE;
|
|||
|
|
|||
|
if ( !fInitialized )
|
|||
|
{
|
|||
|
fInitialized = TRUE;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Get the list
|
|||
|
//
|
|||
|
|
|||
|
err = RegCreateKeyEx( HKEY_LOCAL_MACHINE,
|
|||
|
W3_PARAMETERS_KEY "\\" HTTP_EXT_MAPS,
|
|||
|
0,
|
|||
|
0,
|
|||
|
0,
|
|||
|
KEY_READ,
|
|||
|
NULL,
|
|||
|
&hkeyParam,
|
|||
|
&dwDisposition );
|
|||
|
|
|||
|
if( err != NO_ERROR )
|
|||
|
{
|
|||
|
TCP_PRINT(( DBG_CONTEXT,
|
|||
|
"cannot open registry key, error %lu\n",
|
|||
|
err ));
|
|||
|
|
|||
|
return NO_ERROR;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
if ( !mb.Open( "/LM/W3SVC/",
|
|||
|
METADATA_PERMISSION_READ|METADATA_PERMISSION_WRITE ) ||
|
|||
|
!mb.GetMultisz( "",
|
|||
|
MD_SCRIPT_MAPS,
|
|||
|
IIS_MD_UT_FILE,
|
|||
|
&msz ))
|
|||
|
{
|
|||
|
TCP_PRINT(( DBG_CONTEXT,
|
|||
|
"cannot get the script maps from the metabase, error %d\n",
|
|||
|
GetLastError() ));
|
|||
|
|
|||
|
return NO_ERROR;
|
|||
|
}
|
|||
|
|
|||
|
while ( TRUE )
|
|||
|
{
|
|||
|
CHAR achExt[MAX_PATH+1];
|
|||
|
CHAR achImage[MAX_PATH+1];
|
|||
|
DWORD cchExt = sizeof( achExt );
|
|||
|
DWORD cchImage = sizeof( achImage );
|
|||
|
|
|||
|
err = RegEnumValue( hkeyParam,
|
|||
|
i++,
|
|||
|
achExt,
|
|||
|
&cchExt,
|
|||
|
NULL,
|
|||
|
&dwRegType,
|
|||
|
(LPBYTE) achImage,
|
|||
|
&cchImage );
|
|||
|
|
|||
|
if ( err == ERROR_NO_MORE_ITEMS )
|
|||
|
{
|
|||
|
err = NO_ERROR;
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
if ( dwRegType == REG_SZ )
|
|||
|
{
|
|||
|
const CHAR * psz;
|
|||
|
BOOL fFound = FALSE;
|
|||
|
|
|||
|
//
|
|||
|
// Look for this script map in the metabase, if not found, add it
|
|||
|
//
|
|||
|
|
|||
|
for ( psz = msz.First(); psz != NULL; psz = msz.Next( psz ) )
|
|||
|
{
|
|||
|
if ( !IISstrnicmp( (PUCHAR)achExt, (PUCHAR)psz, cchExt ))
|
|||
|
{
|
|||
|
fFound = TRUE;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if ( !fFound )
|
|||
|
{
|
|||
|
STR str;
|
|||
|
CHAR achFlags[32];
|
|||
|
|
|||
|
//
|
|||
|
// Note these scripts are added w/o the Script bit and with
|
|||
|
// the "never download" bit. In addition, we leave the
|
|||
|
// method exclusion list blank.
|
|||
|
//
|
|||
|
|
|||
|
_itoa( 0, achFlags, 10 );
|
|||
|
|
|||
|
if ( !str.Append( achExt ) ||
|
|||
|
!str.Append( "," ) ||
|
|||
|
!str.Append( achImage ) ||
|
|||
|
!str.Append( "," ) ||
|
|||
|
!str.Append( achFlags ) ||
|
|||
|
!msz.Append( str.QueryStr() ))
|
|||
|
{
|
|||
|
return err = GetLastError();
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
TCP_PRINT(( DBG_CONTEXT,
|
|||
|
"Added \"%s\" from registry as script map\n",
|
|||
|
str.QueryStr() ));
|
|||
|
|
|||
|
fNeedToWrite = TRUE;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if ( fNeedToWrite )
|
|||
|
{
|
|||
|
if ( !mb.SetMultiSZ( "",
|
|||
|
MD_SCRIPT_MAPS,
|
|||
|
IIS_MD_UT_FILE,
|
|||
|
msz.QueryStr() ))
|
|||
|
{
|
|||
|
TCP_PRINT(( DBG_CONTEXT,
|
|||
|
"Failed to write MD_SCRIPT_MAPS back to metabase, error %d\n",
|
|||
|
GetLastError() ));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
RegCloseKey( hkeyParam );
|
|||
|
|
|||
|
return err;
|
|||
|
}
|
|||
|
|
|||
|
VOID
|
|||
|
FreeRegistryExtMap(
|
|||
|
VOID
|
|||
|
)
|
|||
|
{
|
|||
|
if ( !fInitialized )
|
|||
|
{
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
fInitialized = FALSE;
|
|||
|
}
|
|||
|
|