Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

1111 lines
30 KiB

/*++
Copyright (c) 1995 Microsoft Corporation
Module Name :
mimemap.cxx
Abstract:
This module defines the member functions for MIME_MAP class
and MIME_MAP_ENTRY class
Author:
Murali R. Krishnan ( MuraliK ) 10-Jan-1995
Project:
TCP Services Common DLL
Functions Exported:
MIME_MAP_ENTRY::MIME_MAP_ENTRY()
MIME_MAP::MIME_MAP()
MIME_MAP::~MIME_MAP()
MIME_MAP::CleanupThis()
MIME_MAP::InitFromRegistry()
MIME_MAP::LookupMimeEntryForFileExt()
MIME_MAP::LookupMimeEntryForMimeType()
Revision History:
Vlad Sadovsky ( VladS) 16-Dec-1995 Rewrote registry initialization
to be compatible with IE 2.0
--*/
/************************************************************
* Include Headers
************************************************************/
# include <tchar.h>
# include <tcpdllp.hxx>
# include "mimemap.hxx"
//
// Hard coded defaults for MimeEntries.
//
static const TCHAR sg_rgchDefaultFileExt[] = TEXT( "*");
static const TCHAR sg_rgchDefaultMimeType[] = TEXT("application/octet-stream");
static TCHAR sg_rgchDefaultMimeEntry[] =
TEXT( "application/octet-stream,*,default.ico,0");
/************************************************************
* Functions
************************************************************/
static LPTSTR
MMNextField( IN OUT LPTSTR * ppchFields);
static LPTSTR
ReadMimeMapFromRegistry( IN LPCTSTR pszRegKey);
/************************************************************
* MIME_MAP_ENTRY member functions
************************************************************/
MIME_MAP_ENTRY::MIME_MAP_ENTRY(
IN LPCTSTR pchMimeType,
IN LPCTSTR pchFileExt,
IN LPCTSTR pchIconFile,
IN LPCTSTR pchGopherType)
: m_strFileExt ( pchFileExt),
m_strMimeType ( pchMimeType),
m_strIconFile ( pchIconFile),
m_strGopherType ( pchGopherType)
/*++
This function constructs a new MIME_MAP_ENTRY object.
After initializing various fields, it also sets the m_fValid flag.
The user needs to check MIME_MAP_ENTRY::IsValid() for the newly
constructed object.
--*/
{
InitializeListHead( & m_ListEntry);
m_fValid = ( m_strFileExt.IsValid() &&
m_strMimeType.IsValid() &&
m_strIconFile.IsValid() &&
m_strGopherType.IsValid());
} // MIME_MAP_ENTRY::MIME_MAP_ENTRY()
# if DBG
VOID
MIME_MAP_ENTRY::Print( VOID) const
{
DBGPRINTF( ( DBG_CONTEXT,
"MIME_MAP_ENTRY( %08x)\tFileExt=%s\tMimeType=%s\t"
"IconFile=%s\tGopherType=%s\n",
this,
m_strFileExt.QueryStr(),
m_strMimeType.QueryStr(),
m_strIconFile.QueryStr(),
m_strGopherType.QueryStr())
);
return;
} // MIME_MAP_ENTRY::Print()
# endif // DBG
/************************************************************
* MIME_MAP member functions
************************************************************/
MIME_MAP::MIME_MAP( VOID)
/*++
This function constructs a new MIME_MAP container object for
containing the MIME_MAP_ENTRY objects.
The MIME_MAP object is dummy constructed.
It is set valid when we initialize the elements and
create the MmeDefault entry.
--*/
: m_tsLock (),
m_strRegEntry (),
m_fValid ( FALSE),
m_pMmeDefault ( NULL)
{
InitializeListHead( &m_MimeEntriesListHead);
DBG_CODE( m_cLocked = ( 0));
} // MIME_MAP::MIME_MAP()
VOID
MIME_MAP::CleanupThis( VOID)
/*++
This function cleans up the MIME_MAP object, freeing all
dynamically allocated space and reinitiallizing the list head.
Returns:
None
--*/
{
// DBG_ASSERT( !IsLocked());
if ( m_fValid) {
PLIST_ENTRY pEntry;
//LockThisForWrite();
//
// Walk down the list and free all the MIME_MAP entries in the list
//
for( pEntry = m_MimeEntriesListHead.Flink;
pEntry != &m_MimeEntriesListHead;
) {
PMIME_MAP_ENTRY pMmeCurrent;
pMmeCurrent = CONTAINING_RECORD( pEntry,
MIME_MAP_ENTRY,
m_ListEntry);
pEntry = pEntry->Flink;
delete pMmeCurrent;
} // for
InitializeListHead( &m_MimeEntriesListHead);
m_pMmeDefault = NULL;
m_fValid = FALSE;
//UnlockThis();
}
return;
} // MIME_MAP::CleanupThis()
static LPTSTR
MMNextField( IN OUT LPTSTR * ppchFields)
/*++
This function separates and terminates the next field and returns a
pointer to the same.
Also it updates the incoming pointer to point to start of next field.
The fields are assumed to be separated by commas.
--*/
{
LPTSTR pchComma;
LPTSTR pchField = NULL;
DBG_ASSERT( ppchFields != NULL);
//
// Look for a comma in the input.
// If none present, assume that rest of string
// consists of the next field.
//
pchField = *ppchFields;
if ( ( pchComma = _tcschr( *ppchFields, TEXT(','))) != NULL) {
//
// Terminate current field. Store current field name in pchComma and
// update *ppchFields to contain the next field.
//
*pchComma = TEXT( '\0'); // terminate this field with a NULL.
*ppchFields = pchComma + 1; // goto next field.
} else {
//
// Assume everything till end of string is the current field.
//
*ppchFields = *ppchFields + _tcslen( *ppchFields) + 1;
}
pchField = ( *pchField == TEXT( '\0')) ? NULL : pchField;
return ( pchField);
} // MMNextField()
static PMIME_MAP_ENTRY
ReadAndParseMimeMapEntry( IN OUT LPTSTR * ppszValues)
/*++
This function parses the string containing next mime map entry and
related fields and if successful creates a new MIME_MAP_ENTRY
object and returns it.
Otherwise it returns NULL.
In either case, the incoming pointer is updated to point to next entry
in the string ( past terminating NULL), assuming incoming pointer is a
multi-string ( double null terminated).
Arguments:
ppszValues pointer to string containing the MimeEntry values.
Returns:
On successful MIME_ENTRY being parsed, a new MIME_MAP_ENTRY object.
On error returns NULL.
--*/
{
PMIME_MAP_ENTRY pMmeNew = NULL;
DBG_ASSERT( ppszValues != NULL);
LPTSTR pszMimeEntry = *ppszValues;
IF_DEBUG( MIME_MAP) {
DBGPRINTF( ( DBG_CONTEXT, "ReadAndParseMimeMapEntry( %s)\n",
*ppszValues));
}
if ( pszMimeEntry != NULL && *pszMimeEntry != TEXT( '\0')) {
LPTSTR pchMimeType;
LPTSTR pchFileExt;
LPTSTR pchIconFile;
LPTSTR pchGopherType;
pchMimeType = MMNextField( ppszValues);
pchFileExt = MMNextField( ppszValues);
pchIconFile = MMNextField( ppszValues);
pchGopherType = MMNextField( ppszValues);
if ( pchMimeType == NULL ||
pchFileExt == NULL
) {
// pchIconFile and pchGopherType can be NULL
DBGPRINTF( ( DBG_CONTEXT,
" ReadAndParseMimeEntry()."
" Invalid Mime String ( %s)."
"MimeType( %08x): %s, FileExt( %08x): %s,"
"IcnoFile( %08x): %s, GopherType( %08x): %s\n",
pszMimeEntry,
pchMimeType, pchMimeType,
pchFileExt, pchFileExt,
pchIconFile, pchIconFile,
pchGopherType, pchGopherType));
DBG_ASSERT( pMmeNew == NULL);
} else {
pMmeNew = new MIME_MAP_ENTRY( pchMimeType, pchFileExt,
pchIconFile, pchGopherType);
if ( pMmeNew != NULL && !pMmeNew->IsValid()) {
//
// unable to create a new MIME_MAP_ENTRY object. Delete it.
//
delete pMmeNew;
pMmeNew = NULL;
}
}
}
return ( pMmeNew);
} // ReadAndParseMimeMapEntry()
DWORD
MIME_MAP::InitFromRegistry( IN LPCTSTR pszRegKey)
/*++
This function reads the mimemap stored either as a MULTI_SZ or as a sequence
of REG_SZ and returns a double null terminated sequence of mime types on
success. If there is any failure, the failures are ignored and it returns
a NULL.
Arguments:
pszRegKey pointer to NULL terminated string containing registry entry.
Returns:
NULL on failure to open/read registry entries
non-NULL string allocated using TCP_ALLOC containing double null
terminated sequence of strings with MimeMapEntries.
If non-NULL the pointer should be freed using TCP_FREE by caller.
--*/
{
DWORD dwError = NO_ERROR;
DWORD dwErrorChicago = NO_ERROR;
if ( IsValid()) {
//
// There is some mime mapping already present. Cleanup first
//
CleanupThis();
}
// DBG_ASSERT( !IsLocked());
DBG_ASSERT( !IsValid());
// First read INETSERVICES MIME database ( co common types will have priority)
dwError = InitFromRegistryNtStyle( pszRegKey);
// Now read Chicago shell registration database
dwErrorChicago = InitFromRegistryChicagoStyle( );
// If at least one succeeded - return success
if (dwErrorChicago == NO_ERROR ||
dwError == NO_ERROR )
return NO_ERROR;
return dwError;
}
static BOOL
GetFileExtension( IN const TCHAR * pchPathName, OUT LPCTSTR * ppstrExt)
{
BOOL fReturn = FALSE;
LPCTSTR pchExt = sg_rgchDefaultFileExt;
DBG_ASSERT( ppstrExt != NULL);
if ( pchPathName ) {
LPCTSTR pchLastDot;
pchLastDot = _tcsrchr( pchPathName, TEXT( '.'));
if ( pchLastDot != NULL) {
LPCTSTR pchLastWhack;
pchLastWhack = _tcsrchr( pchPathName, TEXT( '\\'));
if ( pchLastWhack == NULL) {
pchLastWhack = pchPathName; // only file name specified.
}
if ( pchLastDot > pchLastWhack) {
// if the dot comes only in the last component, then get ext
pchExt = pchLastDot + 1; // +1 to skip last dot.
}
}
}
*ppstrExt = pchExt;
return TRUE;
} // GetFileExtension()
DWORD
MIME_MAP::LookupMimeEntryForMimeType(
IN const STR & strMimeType,
OUT PCMIME_MAP_ENTRY * prgMme,
IN OUT LPDWORD pnMmeEntries)
/*++
This function maps MimeType to an array of MimeMapEntry objects that match
the given MimeType.
Before calling this function,
ensure that you had already locked this object.
After completing use of the array, unlock the MIME_MAP.
The reason is:
To avoid changes in the data while using the read only members of
MIME_MAP.
Arguments:
strMimeType string containing the MimeType used in search
prgpMme pointer to an array of pointers to Mme.
The array is initialized to contain the
read only pointers to the MIME_MAP_ENTRY objects.
If prgpMme is NULL, then
number of matches is counted and returned.
pnMmeEntries pointer to count of entries in the array
( when called).
On successful return contains total numb of entries
present in the array or count of entries required.
Returns:
NO_ERROR on success.
ERROR_INSUFFICIENT_BUFFER if the prgMme does not have enough space for
copying all the read-only pointers to matched entries.
other Win32 errors if any.
--*/
{
DWORD dwError;
DWORD nMaxMme = 0;
DWORD iMmeFound = 0; // index into array for MmeFound
//
// Assumes that MIME_MAP object is locked.
//
// DBG_ASSERT( IsLocked());
if ( pnMmeEntries != NULL) {
nMaxMme = *pnMmeEntries; // max that we can store.
*pnMmeEntries = 0; // number found. set to default value
}
if ( strMimeType.IsEmpty() || nMaxMme == 0) {
SetLastError( ERROR_INVALID_PARAMETER);
return ( ERROR_INVALID_PARAMETER);
}
for( PLIST_ENTRY pEntry = m_MimeEntriesListHead.Flink;
pEntry != &m_MimeEntriesListHead;
pEntry = pEntry->Flink
){
PMIME_MAP_ENTRY pMme = CONTAINING_RECORD(
pEntry,
MIME_MAP_ENTRY,
m_ListEntry);
DBG_ASSERT( pMme!= NULL);
if ( !_tcsicmp( pMme->QueryMimeType(),
strMimeType.QueryStr())) {
//
// We found the matching Mme. Add it to array of found.
//
if ( prgMme != NULL && iMmeFound < nMaxMme) {
// store the pointer to found match
prgMme[iMmeFound] = pMme;
}
iMmeFound++;
} // found a match
// continue search for next item.
} // for
dwError = ( iMmeFound > nMaxMme) ? ERROR_INSUFFICIENT_BUFFER : NO_ERROR;
*pnMmeEntries = iMmeFound;
return ( dwError);
} // MIME_MAP::LookupMimeEntryForMimeType()
PCMIME_MAP_ENTRY
MIME_MAP::LookupMimeEntryForFileExt(
IN const TCHAR * pchPathName)
/*++
This function mapes FileExtension to MimeEntry.
The function returns a single mime entry for given file's extension.
If no match is found, the default mime entry is returned.
The returned entry is a readonly pointer and should not be altered.
Arguments:
pchPathName pointer to string containing the path for file.
( either full path or just the file name)
If NULL, then the default MimeMapEntry is returned.
Returns:
If a matching mime entry is found,
a const pointer to MimeMapEntry object is returned.
Otherwise the default mime map entry object is returned.
Note:
Lock MimeMap object before calling and free it after using the
PMIME_MAP_ENTRY object.
--*/
{
PMIME_MAP_ENTRY pMmeMatch = m_pMmeDefault;
LPCTSTR pchExt;
//
// Assumes that MIME_MAP object is locked.
//
// DBG_ASSERT( IsLocked());
if ( pchPathName != NULL && *pchPathName ) {
if ( GetFileExtension( pchPathName, &pchExt)) {
//
// Successfully got extension. Search in the list of MimeEntries.
//
//
// John & Murali discussed possibility of reordering list based on
// matches found. NYI
//
for( PLIST_ENTRY pEntry = m_MimeEntriesListHead.Flink;
pEntry != &m_MimeEntriesListHead;
pEntry = pEntry->Flink
){
PMIME_MAP_ENTRY pMme = CONTAINING_RECORD(
pEntry,
MIME_MAP_ENTRY,
m_ListEntry);
DBG_ASSERT( pMme!= NULL);
if ( !_tcsicmp( pMme->QueryFileExt(),
pchExt )) {
//
// We found the matching Mme. Stop search.
//
pMmeMatch = pMme;
break;
}
} // for
} // GetFileExtension()
}
return ( pMmeMatch);
} // MIME_MAP::LookupMimeEntryForFileExt()
BOOL
MIME_MAP::AddMimeMapEntry( IN PMIME_MAP_ENTRY pMmeNew)
/*++
This function adds the new MIME_MAP_ENTRY to the list of entries
maintained in MIME_MAP
Arguments:
pMmeNew poitner to newly created MimeMapEntry object.
Returns:
Win32 error codes. NO_ERROR on success.
--*/
{
BOOL fReturn = FALSE;
if ( pMmeNew == NULL || !pMmeNew->IsValid()) {
SetLastError( ERROR_INVALID_PARAMETER);
DBG_ASSERT( !fReturn);
} else {
InsertTailList( &m_MimeEntriesListHead, &pMmeNew->m_ListEntry);
if ( !_tcscmp( pMmeNew->QueryFileExt(), sg_rgchDefaultFileExt)) {
m_pMmeDefault = pMmeNew; // Use this as default
}
fReturn = TRUE;
}
return ( fReturn);
} // MIME_MAP::AddMimeMapEntry()
# if DBG
VOID
MIME_MAP::Print( VOID)
{
//LockThisForRead();
DBGPRINTF( ( DBG_CONTEXT,
"MIME_MAP ( %08x). RegEntry = %s\tIsValid() = %d\n",
this, m_strRegEntry.QueryStr(), IsValid())
);
for( PLIST_ENTRY pEntry = m_MimeEntriesListHead.Flink;
pEntry != &m_MimeEntriesListHead;
pEntry = pEntry->Flink
) {
PMIME_MAP_ENTRY pMme = CONTAINING_RECORD(
pEntry,
MIME_MAP_ENTRY,
m_ListEntry);
DBG_ASSERT( pMme != NULL);
pMme->Print();
} // for
if ( m_pMmeDefault != NULL) {
DBGPRINTF( ( DBG_CONTEXT, "Default MimeMapEntry is: \n"));
m_pMmeDefault->Print();
} else {
DBGPRINTF( ( DBG_CONTEXT, "Default MimeMapEntry is NULL\n"));
}
//UnlockThis();
return;
} // MIME_MAP::Print()
# endif // DBG
static LPTSTR
ReadMimeMapFromRegistry( IN LPCTSTR pszRegKey)
/*++
This function reads the mimemap stored either as a MULTI_SZ or as a sequence
of REG_SZ and returns a double null terminated sequence of mime types on
success. If there is any failure, the failures are ignored and it returns
a NULL.
Arguments:
pszRegKey pointer to NULL terminated string containing registry entry.
Returns:
NULL on failure to open/read registry entries
non-NULL string allocated using TCP_ALLOC containing double null
terminated sequence of strings with MimeMapEntries.
If non-NULL the pointer should be freed using TCP_FREE by caller.
--*/
{
HKEY hkeyMimeMap = NULL;
DWORD dwError;
LPTSTR pszMimeMap = NULL;
dwError = RegOpenKeyEx( HKEY_LOCAL_MACHINE, // hkey
pszRegKey, // reg entry string
0, // dwReserved
KEY_ALL_ACCESS, // access
&hkeyMimeMap); // pHkeyReturned.
if ( dwError != NO_ERROR) {
DBGPRINTF( ( DBG_CONTEXT,
"MIME_MAP::InitFromRegistry(). Cannot open RegKey %s."
"Ignoring Error = %d\n",
pszRegKey,
dwError));
ASSERT( pszMimeMap == NULL);
} else {
//
// Read the registry for new mappings
//
ASSERT( hkeyMimeMap != NULL);
DWORD cbMimeString = 0;
pszMimeMap = KludgeMultiSz( hkeyMimeMap, &cbMimeString);
IF_DEBUG( MIME_MAP) {
DBGPRINTF( ( DBG_CONTEXT,
"MimeMapEntry from registry is %d bytes( %s)\n",
cbMimeString, pszMimeMap));
}
if ( pszMimeMap != NULL && *pszMimeMap == '\0') {
//
// No entry is found in the registry. Dummy data read.
//
DBGPRINTF(( DBG_CONTEXT,
"MIME_MAP::InitFromRegistry( %s)."
" No Mime Entry Found. Using Default.",
pszRegKey,
sg_rgchDefaultMimeEntry));
TCP_FREE( pszMimeMap);
pszMimeMap = NULL;
}
dwError = RegCloseKey( hkeyMimeMap);
IF_DEBUG( MIME_MAP) {
DBGPRINTF( ( DBG_CONTEXT,
"RegCloseKey( %08x) returned Error = %d."
" Ignored.\n",
hkeyMimeMap,
dwError));
}
} // valid regkey opened.
return ( pszMimeMap);
} // ReadMimeMapFromRegistry()
DWORD
MIME_MAP::InitFromRegistryNtStyle( IN LPCSTR pszRegKey)
/*++
This function reads the MIME_MAP entries from registry and parses
the entry, creates MIME_MAP_ENTRY object and adds the object to list
of MimeMapEntries.
Arguments:
pszRegKey pointer to registry key to read the MimeEntries.
If NULL, any previous value present is used.
If there is no previous registry key available,
then just the default mime mappings are established.
Returns:
Win32 error code. NO_ERROR on success.
Format of Storage in registry:
The entries are stored in NT under a registry
with a list of values in following format.
mimetype,file-extension,icon,gopher-type=
It can be stored using MULTI_SZ, but above form is convenient for both
Windows 95 ( withoug MULTI_SZ) and WindowsNT.
--*/
{
DWORD dwError = NO_ERROR;
//
// Override the old registry entry for MimeEntries, if new one exists.
//
if ( pszRegKey!= NULL && !m_strRegEntry.Copy( pszRegKey)) {
//UnlockThis();
return ( ERROR_NOT_ENOUGH_MEMORY);
}
LPTSTR pszValueAlloc = NULL; // to be free using TCP_FREE()
LPTSTR pszValue;
if ( !m_strRegEntry.IsEmpty()) {
//
// There is some registry key for Mime Entries. Try open and read.
//
pszValueAlloc = ReadMimeMapFromRegistry( m_strRegEntry.QueryStr());
} // valid reg entry specified.
//
// At this point, pszAllocValue should have
// non-NULL value consisting of double null terminated MimeMapEntries
// read from registry
// ( space allocateed using TCP_ALLOC; should be freed by TCP_FREE)
// or
// NULL indicating a failure in opening or reading the MimeMapEntries.
// Use Default MimeEntry if this is NULL.
//
pszValue = ( pszValueAlloc != NULL) ?
pszValueAlloc :
sg_rgchDefaultMimeEntry;
// Ignore all errors.
dwError = NO_ERROR;
//
// Parse each MimeEntry in the string containing list of mime objects.
//
for( ; m_pMmeDefault == NULL; // repeat until default is set
pszValue = sg_rgchDefaultMimeEntry // force default mapping in iter 2.
) {
while ( *pszValue != TEXT( '\0')) {
PMIME_MAP_ENTRY pMmeNew;
pMmeNew = ReadAndParseMimeMapEntry( &pszValue);
//
// If New MimeMap entry found, Create a new object and update list
//
if ( pMmeNew != NULL &&
!AddMimeMapEntry( pMmeNew)) {
dwError = GetLastError();
DBGPRINTF( ( DBG_CONTEXT,
"MIME_MAP::InitFromRegistry()."
" Failed to add new MIME Entry. Error = %d\n",
dwError)
);
delete pMmeNew;
break;
}
} // while
} // for
//UnlockThis();
if ( pszValueAlloc != NULL) {
TCP_FREE( pszValueAlloc); // free the memory allocated by Kludge
}
return ( dwError);
} // MIME_MAP::InitFromRegistryNtStyle
DWORD
MIME_MAP::InitFromRegistryChicagoStyle( VOID )
/*++
This function reads the list of MIME content-types available for regsitered file
extensions. Global list of MIME objects is updated with not added yet extensions.
This method should be invoked after server-specific map had been read, so it does not
overwrite extensions common for two.
Arguments:
None.
Returns:
FALSE on failure to open/read registry entries
TRUE on success ( does not mean any objects were added)
--*/
{
HKEY hkeyMimeMap = NULL;
HKEY hkeyMimeType = NULL;
HKEY hkeyExtension = NULL;
DWORD dwError = ERROR_SUCCESS;
DWORD dwErrorChild = ERROR_SUCCESS;
DWORD dwIndexSubKey;
DWORD dwMimeSizeAllowed ;
DWORD dwType;
DWORD cbValue;
LPTSTR pszMimeMap = NULL;
TCHAR szSubKeyName[MAX_PATH];
TCHAR szExtension[MAX_PATH];
PTSTR pszMimeType;
LockThisForRead();
//
// Read content types from all registered extensions
//
dwError = RegOpenKeyEx(HKEY_CLASSES_ROOT, // hkey
"", // reg entry string
0, // dwReserved
KEY_ALL_ACCESS, // access
&hkeyMimeMap); // pHkeyReturned.
if ( dwError != NO_ERROR) {
DBGPRINTF( ( DBG_CONTEXT,
"MIME_MAP::InitFromRegistry(). Cannot open RegKey %s."
"Error = %d\n",
"HKCR_",
dwError) );
goto AddDefault;
}
dwIndexSubKey = 0;
*szSubKeyName = '\0';
pszMimeType = szSubKeyName ;
dwError = RegEnumKey(hkeyMimeMap,
dwIndexSubKey,
szExtension,
sizeof(szExtension));
while (dwError == ERROR_SUCCESS ) {
//
// Some entries in HKEY_CLASSES_ROOT are extensions ( start with dot)
// and others are file types. We don't need file types here .
//
if (!::IsDBCSLeadByte(*szExtension) &&
TEXT('.') == *szExtension) {
//
// Got next eligible extension
//
dwErrorChild = RegOpenKeyEx( HKEY_CLASSES_ROOT, // hkey
szExtension, // reg entry string
0, // dwReserved
KEY_ALL_ACCESS, // access
&hkeyExtension); // pHkeyReturned.
if ( dwErrorChild != NO_ERROR) {
DBGPRINTF( ( DBG_CONTEXT,
"MIME_MAP::InitFromRegistry(). Cannot open RegKey HKEY_CLASSES_ROOT\\%s."
"Ignoring Error = %d\n",
szExtension,
dwErrorChild));
break;
}
//
// Now get content type for this extension if present
//
*szSubKeyName = '\0';
cbValue = sizeof(szSubKeyName);
dwErrorChild = RegQueryValueEx(hkeyExtension,
"Content Type",
NULL,
&dwType,
(LPBYTE)&szSubKeyName[0],
&cbValue);
if ( dwErrorChild == NO_ERROR) {
//
// Now we have MIME type and file extension
// Create a new object and update list
//
if (!CreateAndAddMimeMapEntry(szSubKeyName,szExtension)) {
dwError = GetLastError();
DBGPRINTF( ( DBG_CONTEXT,
"MIME_MAP::InitFromRegistry()."
" Failed to add new MIME Entry. Error = %d\n",
dwError)) ;
}
}
RegCloseKey(hkeyExtension);
}
//
// Attempt to read next extension
//
dwIndexSubKey++;
dwError = RegEnumKey(hkeyMimeMap,
dwIndexSubKey,
szExtension,
sizeof(szExtension));
} // end_while
dwError = RegCloseKey( hkeyMimeMap);
AddDefault:
//
// Now after we are done with registry mapping - add default MIME type in case
// if NT database does not exist
//
if (!CreateAndAddMimeMapEntry(sg_rgchDefaultMimeType,
sg_rgchDefaultFileExt)) {
dwError = GetLastError();
DBGPRINTF( ( DBG_CONTEXT,
"MIME_MAP::InitFromRegistry()."
"Failed to add new MIME Entry. Error = %d\n",
dwError) );
}
UnlockThis();
return ( NO_ERROR);
} // InitFromRegistryChicagoStyle
BOOL
MIME_MAP::CreateAndAddMimeMapEntry(
IN LPCTSTR pszMimeType,
IN LPCTSTR pszExtension
)
{
DWORD dwError;
//
// First check if thie extension is not yet present
//
if (LookupMimeEntryForFileExt(pszExtension)) {
DBGPRINTF( ( DBG_CONTEXT,
"MIME_MAP::CreateAndAddMimeEntry."
" New MIME Entry already exists for extension %s .\n",
pszExtension)
);
return TRUE;
}
//
// File extensions, stored by OLE/shell registration UI have leading
// dot, we need to remove it , as other code won't like it.
//
if (!::IsDBCSLeadByte(*pszExtension) &&
TEXT('.') == *pszExtension) {
pszExtension = ::CharNext(pszExtension);
}
PMIME_MAP_ENTRY pMmeNew;
pMmeNew = new MIME_MAP_ENTRY(pszMimeType, //
pszExtension, //
NULL, // Nobody needs icons files
NULL // Gopher type ignored for now
);
if (!pMmeNew || !pMmeNew->IsValid()) {
//
// unable to create a new MIME_MAP_ENTRY object.
//
if (pMmeNew) {
delete pMmeNew;
}
return FALSE;
}
if ( !AddMimeMapEntry( pMmeNew)) {
dwError = GetLastError();
DBGPRINTF( ( DBG_CONTEXT,
"MIME_MAP::InitFromRegistry()."
" Failed to add new MIME Entry. Error = %d\n",
dwError)
);
delete pMmeNew;
return FALSE;
}
return TRUE;
} // MIME_MAP::CreateAndAddMimeMapEntry
/************************ End of File ***********************/