273 lines
7.2 KiB
C++
273 lines
7.2 KiB
C++
/**********************************************************************/
|
||
/** Microsoft Windows NT **/
|
||
/** Copyright(c) Microsoft Corp., 1994 **/
|
||
/**********************************************************************/
|
||
|
||
/*
|
||
mimemap.cxx
|
||
|
||
This module contains the code for MIME to file type mappings
|
||
|
||
The mime mappings are used for selecting the correct type based on file
|
||
extensions and for indicating what types the server accepts.
|
||
|
||
FILE HISTORY:
|
||
Johnl 23-Aug-1994 Created
|
||
|
||
*/
|
||
|
||
#include "w3p.hxx"
|
||
|
||
//
|
||
// Private constants.
|
||
//
|
||
|
||
//
|
||
// Private globals.
|
||
//
|
||
|
||
//
|
||
// Private prototypes.
|
||
//
|
||
|
||
BOOL
|
||
SelectCustomMimeMapping(
|
||
IN const CHAR *pszPath,
|
||
IN STR *pstrContentType,
|
||
IN CHAR *pszMimeMapping
|
||
)
|
||
/*++
|
||
|
||
Routine Description
|
||
|
||
Called when we have a configured metadata mime mapping on a directory,
|
||
and want to look it up.
|
||
|
||
Arguments
|
||
|
||
pszPath - Path including extension to be looked up.
|
||
pstrContentType - Where to return the content type.
|
||
pszMimeMapping - Pointer to mime mapping string.
|
||
|
||
Returns
|
||
|
||
TRUE if operation successful.
|
||
|
||
--*/
|
||
{
|
||
CHAR *pszCurrentMimeType;
|
||
CHAR *pszExt;
|
||
DWORD dwExtLength;
|
||
BOOL bCheckingDefault;
|
||
CHAR *pszLastSlash;
|
||
|
||
if (pszPath == NULL)
|
||
{
|
||
pszExt = "*";
|
||
dwExtLength = sizeof("*") - 1;
|
||
bCheckingDefault = TRUE;
|
||
}
|
||
else
|
||
{
|
||
|
||
|
||
// Need to find the extension. The extension is whatever follows the
|
||
// dot after the last slash in the path.
|
||
|
||
// Find the last slash. If there isn't one, use the start of the path.
|
||
|
||
pszLastSlash = strrchr((CHAR *)pszPath, '\\');
|
||
|
||
if (pszLastSlash == NULL)
|
||
{
|
||
pszLastSlash = (CHAR *)pszPath;
|
||
}
|
||
|
||
pszExt = strrchr(pszLastSlash, '.');
|
||
|
||
if (pszExt == NULL || *(pszExt+1) == '\0')
|
||
{
|
||
// Didn't find one, so look for the default mapping.
|
||
pszExt = "*";
|
||
dwExtLength = sizeof("*") - 1;
|
||
bCheckingDefault = TRUE;
|
||
}
|
||
else
|
||
{
|
||
dwExtLength = strlen(pszExt);
|
||
bCheckingDefault = FALSE;
|
||
}
|
||
|
||
}
|
||
|
||
|
||
// Look at the mime type mapping string and see if we have a match. The
|
||
// string was preformatted when we read the metadata, and is stored as
|
||
// a set of multi-sz mime-type, .ext strings. If we're not looking for the
|
||
// default, and we don't find one on the first pass, we'll try to find the
|
||
// default mapping.
|
||
|
||
for (;;)
|
||
{
|
||
pszCurrentMimeType = pszMimeMapping;
|
||
|
||
do {
|
||
CHAR *pszCurrentSeparator;
|
||
DWORD dwCurrentExtLength;
|
||
CHAR *pszCurrentMimeString;
|
||
DWORD dwCurrentMimeStringLength;
|
||
|
||
|
||
// First, isolate the mime type from the extension.
|
||
|
||
pszCurrentSeparator = strchr(pszCurrentMimeType, ',');
|
||
|
||
// Compute the length of the extension
|
||
|
||
dwCurrentExtLength = DIFF(pszCurrentSeparator - pszCurrentMimeType);
|
||
|
||
// Find the mime map string, and it's length
|
||
|
||
pszCurrentMimeString = pszCurrentSeparator + 1;
|
||
|
||
dwCurrentMimeStringLength = strlen(pszCurrentMimeString);
|
||
|
||
// We have the extension and the length, compare against the
|
||
// input extension.
|
||
|
||
if (dwExtLength == dwCurrentExtLength &&
|
||
!_strnicmp(pszExt, pszCurrentMimeType, dwExtLength))
|
||
{
|
||
// Allright, we have a winner.
|
||
|
||
return pstrContentType->Copy(pszCurrentMimeString,
|
||
dwCurrentMimeStringLength);
|
||
}
|
||
|
||
|
||
// Otherwise, look at the next one.
|
||
pszCurrentMimeType = pszCurrentMimeString + dwCurrentMimeStringLength + 1;
|
||
|
||
|
||
} while ( *pszCurrentMimeType != '\0' );
|
||
|
||
if (!bCheckingDefault)
|
||
{
|
||
|
||
// Look backwards for another '.' so we can support extensions
|
||
// like ".xyz.xyz" or ".a.b.c".
|
||
|
||
if ( pszExt > pszLastSlash )
|
||
{
|
||
pszExt--;
|
||
|
||
while ( ( pszExt > pszLastSlash ) && ( *pszExt != '.' ) )
|
||
{
|
||
pszExt--;
|
||
}
|
||
|
||
if ( *pszExt == '.' )
|
||
{
|
||
dwExtLength = strlen( pszExt );
|
||
continue;
|
||
}
|
||
}
|
||
|
||
// Didn't find one, so look for the default mapping.
|
||
pszExt = "*";
|
||
dwExtLength = sizeof("*") - 1;
|
||
bCheckingDefault = TRUE;
|
||
}
|
||
else
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
|
||
return FALSE;
|
||
}
|
||
|
||
/*******************************************************************
|
||
|
||
NAME: SelectMimeMapping
|
||
|
||
SYNOPSIS: Given a file name, this routine finds the appropriate
|
||
MIME type for the name
|
||
|
||
ENTRY: pstrContentType - Receives MIME type or icon file to use
|
||
pszPath - Path of file being requested (extension
|
||
is used for the mime mapping). Should be
|
||
fully qualified and canonicalized. If NULL, then the
|
||
default mapping is used
|
||
mmtype - Type of data to retrieve. Can retrieve either
|
||
the mime type associated with the file extension or
|
||
the icon associated with the extension
|
||
|
||
RETURNS: TRUE on success, FALSE on error (call GetLastError)
|
||
|
||
HISTORY:
|
||
Johnl 04-Sep-1994 Created
|
||
|
||
********************************************************************/
|
||
|
||
BOOL SelectMimeMapping( STR * pstrContentType,
|
||
const CHAR * pszPath,
|
||
PW3_METADATA pMetaData,
|
||
enum MIMEMAP_TYPE mmtype )
|
||
{
|
||
BOOL fRet = TRUE;
|
||
CHAR *pszMimeMap;
|
||
|
||
switch ( mmtype )
|
||
{
|
||
case MIMEMAP_MIME_TYPE:
|
||
|
||
pszMimeMap = (CHAR *)pMetaData->QueryMimeMap()->QueryPtr();
|
||
if (*pszMimeMap != '\0')
|
||
{
|
||
fRet = SelectCustomMimeMapping( pszPath,
|
||
pstrContentType,
|
||
pszMimeMap );
|
||
|
||
if ( fRet )
|
||
{
|
||
break;
|
||
}
|
||
|
||
}
|
||
|
||
fRet = SelectMimeMappingForFileExt( g_pInetSvc,
|
||
pszPath,
|
||
pstrContentType );
|
||
break;
|
||
|
||
case MIMEMAP_MIME_ICON:
|
||
fRet = SelectMimeMappingForFileExt( g_pInetSvc,
|
||
pszPath,
|
||
NULL,
|
||
pstrContentType );
|
||
break;
|
||
|
||
default:
|
||
DBG_ASSERT( FALSE );
|
||
SetLastError( ERROR_INVALID_PARAMETER );
|
||
return FALSE;
|
||
}
|
||
|
||
IF_DEBUG( PARSING )
|
||
{
|
||
if ( mmtype == MIMEMAP_MIME_TYPE )
|
||
DBGPRINTF((DBG_CONTEXT,
|
||
"[SelectMimeMapping] Returning %s for extension %s\n",
|
||
pstrContentType->QueryStr(),
|
||
pszPath ? pszPath : TEXT("*") ));
|
||
}
|
||
|
||
return fRet;
|
||
}
|
||
|
||
//
|
||
// Private functions.
|
||
//
|
||
|