1275 lines
40 KiB
C++
1275 lines
40 KiB
C++
#include <cache.hxx>
|
|
|
|
#include "401imprt.hxx"
|
|
#include "401inc.hxx"
|
|
|
|
#ifdef UNICODE
|
|
#error "401imprt.cxx doesn't support UNICODE compilation."
|
|
#endif
|
|
|
|
#define PRE5_CACHE_KEY "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Cache"
|
|
#define IE401_HIST_ROOT "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Cache\\Extensible Cache"
|
|
|
|
//IE401_PER_USER_CACHE_LOCATION is in HKCU
|
|
#define IE401_PER_USER_CACHE_LOCATION \
|
|
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders"
|
|
#define IE401_PER_USER_CACHE_KEY "Cache"
|
|
//IE401_ONE_USER_CACHE_LOCATION is in HKLM
|
|
#define IE401_ONE_USER_CACHE_LOCATION \
|
|
"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Cache\\Content"
|
|
#define IE401_ONE_USER_CACHE_KEY "CachePath"
|
|
|
|
#define MSHIST_DIR_SZ "MSHIST011998020119980225"##FILENAME_SEPARATOR_STR
|
|
#define MSHIST_KEY_SZ "MSHIST011998020119980225"
|
|
#define MSHIST_SZ "MSHIST"
|
|
#define MSHIST_PREFIX_SZ ":1998010119980101:"
|
|
#define VISITED_PREFIX_SZ "Visited:"
|
|
#define INDEX_DAT_SZ "index.dat"
|
|
#define CACHE_LIMIT_SZ "CacheLimit"
|
|
#define CACHE_OPTIONS_SZ "CacheOptions"
|
|
#define CACHE_PATH_SZ "CachePath"
|
|
#define CACHE_PREFIX_SZ "CachePrefix"
|
|
|
|
//----------------------------------------
|
|
//The following tructures and macro, _HISTDATA_V001 and SET_HISTORY_FLAG()
|
|
//allow us to notify members of the Visited: cache that they are to be
|
|
//listed in the History view. The structure was cut'n'pasted from
|
|
//shdocvw\urlhist.cpp and any changes made to the original need
|
|
//to be reflected here as well.
|
|
#define PIDISF_HISTORY 0x10000000
|
|
#define PID_INTSITE_TITLE 16
|
|
//** BUGBUG
|
|
|
|
struct _HISTDATA_V001
|
|
{
|
|
UINT cbSize : 16; // size of this header
|
|
UINT cbVer : 16; // version
|
|
DWORD dwFlags; // PID_INTSITE_FLAGS (PIDISF_ flags)
|
|
DWORD dwWatch; // PID_INTSITE_WATCH (PIDISM_ flags)
|
|
DWORD dwVisits; // PID_INTSITE_VISITCOUNT
|
|
};
|
|
|
|
#define SET_HISTORY_FLAG(lpHeaderInfo) \
|
|
(((_HISTDATA_V001*)lpHeaderInfo)->dwFlags |= PIDISF_HISTORY)
|
|
|
|
//
|
|
// Right after HISTDATA (always at cbSize), we have optional (typically
|
|
// variable length) data which has following data structure. It may have
|
|
// more than one but always has a null-terimiator (cbExtra == 0).
|
|
//
|
|
//HISTEXTRA is also cut'n'pasted from shdocvw.
|
|
struct HISTEXTRA
|
|
{
|
|
UINT cbExtra : 16;
|
|
UINT idExtra : 8; // PID_INTSITE_*
|
|
UINT vtExtra : 8; // VT_*
|
|
BYTE abExtra[1]; // abExtra[cbExtra-4];
|
|
};
|
|
|
|
// HISTEXTRA without the abExtra ==> (sizeof(HISTEXTRA) - sizeof(BYTE))
|
|
#define HISTEXTRA_HEAD_SIZE 4
|
|
//-----------------------------------------
|
|
|
|
|
|
BOOL IsPerUserCache();
|
|
|
|
namespace ie401
|
|
{
|
|
|
|
|
|
//--------------------------------------------------------
|
|
|
|
// The code that enumerates through a IE401 index.dat file is provided
|
|
//by IE401IndexFile. Classes derived from IE401IndexFile override HandleHashElement
|
|
//to handle each HASH_ELEMENT as the index file is enumerated.
|
|
// IE401IndexFile::Import401Url is provided to import URLs without overwriting
|
|
//already existing entries.
|
|
|
|
class IE401IndexFile
|
|
{
|
|
public:
|
|
// EnumHashValues enumerates hash tables, calling HandleHashElement for each.
|
|
virtual BOOL EnumHashValues();
|
|
|
|
protected:
|
|
IE401IndexFile( LPCSTR szFilename);
|
|
IE401IndexFile();
|
|
virtual ~IE401IndexFile();
|
|
|
|
// given by derived class
|
|
virtual BOOL HandleHashElement( ie401::HASH_ITEM* pEntry) = 0;
|
|
|
|
// probably useful to many, default URL import. Not for REDIRs.
|
|
virtual BOOL Import401Url( ie401::URL_FILEMAP_ENTRY* pEntry);
|
|
|
|
BYTE* m_pBuf;
|
|
};
|
|
|
|
|
|
//--------------------------------------------------------
|
|
|
|
// IE401Visited overrides HandleHashElement to import all URLs,
|
|
//translating CEI to its current format.
|
|
// All the dependencies on the change in CEI format are
|
|
//contained in UpgradeHeaderData.
|
|
|
|
class IE401Visited : public IE401IndexFile
|
|
{
|
|
public:
|
|
IE401Visited( LPCSTR szFilename);
|
|
|
|
protected:
|
|
IE401Visited() {}
|
|
|
|
virtual BOOL HandleHashElement( ie401::HASH_ITEM* pEntry);
|
|
|
|
virtual BOOL Import401UrlTranslatingCEI( ie401::URL_FILEMAP_ENTRY* pEntry);
|
|
|
|
virtual BOOL UpgradeHeaderData(
|
|
IN const CHAR* pIn,
|
|
OUT CHAR* pOut,
|
|
IN OUT DWORD* pcbOutSize);
|
|
};
|
|
|
|
|
|
//--------------------------------------------------------
|
|
|
|
// IE401History overrides HandleHashElement to import all URLs
|
|
//and mark them in the Visited: container.
|
|
// All the dependencies on the format for the Visited mark
|
|
//are contained in MarkUrlAsVisited.
|
|
//(colliding items are not imported and associated data
|
|
//files are not copied.)
|
|
|
|
class IE401History : public IE401IndexFile
|
|
{
|
|
public:
|
|
IE401History( LPCSTR szFilename);
|
|
|
|
protected:
|
|
IE401History() {}
|
|
|
|
virtual BOOL HandleHashElement( ie401::HASH_ITEM* pEntry);
|
|
|
|
static BOOL MarkUrlAsVisited( LPSTR szUrlName);
|
|
};
|
|
|
|
|
|
//--------------------------------------------------------
|
|
|
|
|
|
// pre-declaration included so IE401Redirects can be declared as a friend
|
|
class IE401Redirects;
|
|
|
|
|
|
// IE401Content overrides HandleHashElement to import all URLs
|
|
//and also copy associated data files.
|
|
//(colliding items are not imported)
|
|
class IE401Content : public IE401IndexFile
|
|
{
|
|
public:
|
|
IE401Content( LPCSTR szFilename);
|
|
|
|
friend IE401Redirects;
|
|
|
|
protected:
|
|
IE401Content() {}
|
|
|
|
virtual BOOL HandleHashElement( ie401::HASH_ITEM* pEntry);
|
|
|
|
// Extends the default to import files
|
|
BOOL Import401UrlWithFile( ie401::URL_FILEMAP_ENTRY* pEntry);
|
|
|
|
CHAR m_szRootPath[MAX_PATH];
|
|
DWORD m_cbRootPathLength;
|
|
DWORD m_nDirs;
|
|
CHAR m_szDir[DEFAULT_MAX_DIRS][DIR_NAME_SIZE + 1];
|
|
};
|
|
|
|
|
|
//--------------------------------------------------------
|
|
|
|
|
|
// IE401Redirects override HandleHashElement to import redirects.
|
|
// This should be done to an index file after IE401Content has
|
|
//enumerated over it, so the constructor takes a IE401Content object
|
|
//rather than a filename. This IE401Content represents a process
|
|
//that is finished, so its functionality is taken away.
|
|
// Importing redirects is done with a separate enumerator than
|
|
//IE401Content since its less work then retooling IE401IndexFile
|
|
//to enumerate an arbitrary number of times.
|
|
class IE401Redirects : public IE401IndexFile
|
|
{
|
|
public:
|
|
IE401Redirects( IE401Content* pContent);
|
|
|
|
protected:
|
|
IE401Redirects() {}
|
|
|
|
virtual BOOL HandleHashElement( ie401::HASH_ITEM* pEntry);
|
|
|
|
BOOL Import401Redirect( ie401::REDIR_FILEMAP_ENTRY* pEntry);
|
|
};
|
|
|
|
|
|
//******************************************************
|
|
//
|
|
// class OutputStream - utility
|
|
//
|
|
// outputs data to a buffer, tracking buffer used
|
|
//and checking for overflow.
|
|
|
|
|
|
class OutputStream
|
|
{
|
|
public:
|
|
OutputStream( VOID* pBuffer, DWORD cbBufferSize)
|
|
: m_pBuffer( (BYTE*)pBuffer), m_cbBufferSize( cbBufferSize), m_cbPosition(0)
|
|
{
|
|
}
|
|
|
|
BOOL Memcpy( const VOID* pSource, DWORD cbSize)
|
|
{
|
|
if( cbSize + m_cbPosition <= m_cbBufferSize)
|
|
{
|
|
memcpy(&m_pBuffer[m_cbPosition], (BYTE*)pSource, cbSize);
|
|
m_cbPosition += cbSize;
|
|
return TRUE;
|
|
}
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL CopyAnsiToUnicode( const CHAR* pSource, DWORD cSize)
|
|
{
|
|
if( m_cbPosition + cSize * sizeof(WCHAR) / sizeof(CHAR)
|
|
<= m_cbBufferSize)
|
|
{
|
|
DWORD dwSizeCopied;
|
|
|
|
// the semantics of MultiByteToWideChar is different
|
|
//if you give it a zero-length buffer.
|
|
INET_ASSERT( m_cbBufferSize - m_cbPosition != 0);
|
|
|
|
dwSizeCopied =
|
|
MultiByteToWideChar( CP_ACP, 0, pSource, cSize,
|
|
(WCHAR*)&m_pBuffer[m_cbPosition],
|
|
(m_cbBufferSize - m_cbPosition) / sizeof(WCHAR));
|
|
|
|
if( dwSizeCopied != 0)
|
|
{
|
|
m_cbPosition += dwSizeCopied * sizeof(WCHAR);
|
|
return TRUE;
|
|
}
|
|
else
|
|
return FALSE;
|
|
}
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
DWORD GetFinalLength()
|
|
{
|
|
return m_cbPosition;
|
|
}
|
|
|
|
private:
|
|
BYTE* m_pBuffer;
|
|
|
|
DWORD m_cbBufferSize, m_cbPosition;
|
|
};
|
|
|
|
|
|
//*************************************************************************
|
|
//
|
|
// IE401IndexFile
|
|
//
|
|
|
|
// On creation, load the contents of the given file into memory.
|
|
|
|
IE401IndexFile::IE401IndexFile( LPCSTR szFilename)
|
|
{
|
|
m_pBuf = NULL;
|
|
|
|
// load the file into the buffer
|
|
DWORD cbBufSize;
|
|
if( ReadFileToBuffer( szFilename, &m_pBuf, &cbBufSize) == FALSE)
|
|
{
|
|
if( m_pBuf != NULL)
|
|
{
|
|
delete [] m_pBuf;
|
|
m_pBuf = NULL;
|
|
}
|
|
}
|
|
else if( cbBufSize < sizeof(_MEMMAP_HEADER_SMALL)
|
|
|| strcmp((LPSTR) m_pBuf, "Client UrlCache MMF Ver 4.7"))
|
|
{
|
|
// If this file doesn't even have a memmap header, forget it.
|
|
// Now all derived classes can assume they have at least a memmap header
|
|
//if m_pBuf != NULL
|
|
delete [] m_pBuf;
|
|
m_pBuf = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
// Default constructor made protected to prevent direct creation
|
|
IE401IndexFile::IE401IndexFile()
|
|
: m_pBuf(NULL)
|
|
{
|
|
}
|
|
|
|
|
|
IE401IndexFile::~IE401IndexFile()
|
|
{
|
|
if( m_pBuf != NULL)
|
|
delete [] m_pBuf;
|
|
}
|
|
|
|
|
|
//---------------------------------------------------
|
|
//
|
|
|
|
// Enumerate through the entries in an ie401 index
|
|
//file, calling HandleHashElement on each entry.
|
|
|
|
BOOL IE401IndexFile::EnumHashValues()
|
|
{
|
|
BOOL retVal = FALSE;
|
|
|
|
if( m_pBuf == NULL)
|
|
goto doneEnumHashValues;
|
|
|
|
HASH_FILEMAP_ENTRY* pTable;
|
|
HASH_ITEM* pItem;
|
|
// pTable is located by an offset which is located at dwHashTableOffset
|
|
pTable = (HASH_FILEMAP_ENTRY*)(m_pBuf + (((_MEMMAP_HEADER_SMALL*)m_pBuf)->dwHashTableOffset));
|
|
// The first location in the table follows immediately after the HASH_FILEMAP_ENTRY pTable
|
|
pItem = (HASH_ITEM*)(pTable + 1);
|
|
|
|
if (pTable->dwSig != SIG_HASH)
|
|
goto doneEnumHashValues;
|
|
|
|
do // Scan the list of tables.
|
|
{
|
|
// Scan the current table.
|
|
for (; (LPBYTE)pItem < (LPBYTE)pTable + BYTES_PER_TABLE; pItem++)
|
|
{
|
|
// call virtual entry handler
|
|
if( HandleHashElement( pItem) == FALSE)
|
|
goto doneEnumHashValues;
|
|
}
|
|
|
|
// Follow the link to the next table.
|
|
if (!pTable->dwNext)
|
|
{
|
|
pTable = NULL;
|
|
}
|
|
else
|
|
{
|
|
// Validate the table signature and sequence number.
|
|
DWORD nBlock;
|
|
nBlock = pTable->nBlock;
|
|
pTable = (HASH_FILEMAP_ENTRY*) (m_pBuf + pTable->dwNext);
|
|
if (pTable->dwSig != SIG_HASH || pTable->nBlock != nBlock + 1)
|
|
goto doneEnumHashValues;
|
|
|
|
// Set pointer to first location in table.
|
|
pItem = (HASH_ITEM*) (pTable + 1);
|
|
}
|
|
}
|
|
while (pTable);
|
|
|
|
retVal = TRUE;
|
|
|
|
doneEnumHashValues:
|
|
return retVal;
|
|
}
|
|
|
|
|
|
//---------------------------------------------------
|
|
//
|
|
|
|
|
|
// Imports an URL entry without overwriting existing
|
|
//cache entries or copying any associated data files.
|
|
|
|
BOOL IE401IndexFile::Import401Url( ie401::URL_FILEMAP_ENTRY* pEntry)
|
|
{
|
|
BOOL retVal = FALSE;
|
|
|
|
// don't import Url if it is already in the buffer
|
|
if( GetUrlCacheEntryInfo( (LPSTR)((BYTE*)pEntry + pEntry->UrlNameOffset), NULL, 0) == TRUE
|
|
|| GetLastError() != ERROR_FILE_NOT_FOUND)
|
|
{
|
|
goto doneImport401Url;
|
|
}
|
|
|
|
if( pEntry->FileSize != 0)
|
|
{
|
|
INET_ASSERT(0); // Are you importing URL cache entries with external data?
|
|
goto doneImport401Url;
|
|
}
|
|
|
|
if( !CommitUrlCacheEntry(
|
|
(LPCSTR)((BYTE*)pEntry + pEntry->UrlNameOffset),
|
|
NULL,
|
|
*LONGLONG_TO_FILETIME(&pEntry->ExpireTime),
|
|
*LONGLONG_TO_FILETIME(&pEntry->LastModifiedTime),
|
|
pEntry->CacheEntryType,
|
|
pEntry->HeaderInfoOffset != NULL ?
|
|
(BYTE*)((BYTE*)pEntry + pEntry->HeaderInfoOffset) : NULL,
|
|
pEntry->HeaderInfoSize,
|
|
pEntry->FileExtensionOffset != 0 ?
|
|
(LPCSTR)((BYTE*)pEntry + pEntry->FileExtensionOffset) : NULL,
|
|
NULL))
|
|
goto doneImport401Url;
|
|
|
|
CACHE_ENTRY_INFO cei;
|
|
|
|
cei.dwStructSize = sizeof(cei);
|
|
cei.LastAccessTime = *LONGLONG_TO_FILETIME(&pEntry->LastAccessedTime);
|
|
cei.dwHitRate = pEntry->NumAccessed;
|
|
cei.ExpireTime = *LONGLONG_TO_FILETIME(&pEntry->ExpireTime);
|
|
cei.LastModifiedTime = *LONGLONG_TO_FILETIME(&pEntry->LastModifiedTime);
|
|
|
|
if( !SetUrlCacheEntryInfo(
|
|
(LPCSTR)((BYTE*)pEntry + pEntry->UrlNameOffset),
|
|
&cei,
|
|
CACHE_ENTRY_ACCTIME_FC | CACHE_ENTRY_HITRATE_FC
|
|
| CACHE_ENTRY_EXPTIME_FC | CACHE_ENTRY_MODTIME_FC))
|
|
goto doneImport401Url;
|
|
|
|
retVal = TRUE;
|
|
|
|
doneImport401Url:
|
|
return retVal;
|
|
}
|
|
|
|
|
|
//************************************************************************8
|
|
//
|
|
// IE401Visited : public IE401IndexFile
|
|
//
|
|
|
|
IE401Visited::IE401Visited( LPCSTR szFilename) : IE401IndexFile( szFilename)
|
|
{
|
|
}
|
|
|
|
|
|
// imports only URLs using Import401Url- nothing special
|
|
BOOL IE401Visited::HandleHashElement( ie401::HASH_ITEM* pEntry)
|
|
{
|
|
// No reserved bits should be set.
|
|
INET_ASSERT (!(pEntry->dwHash & HASH_BIT_RESERVED));
|
|
|
|
if( !(pEntry->dwHash & HASH_BIT_NOTURL)
|
|
&& ((ie401::FILEMAP_ENTRY*)(m_pBuf + pEntry->dwOffset))->dwSig == SIG_URL)
|
|
{
|
|
Import401UrlTranslatingCEI( (ie401::URL_FILEMAP_ENTRY*)(m_pBuf + pEntry->dwOffset));
|
|
}
|
|
|
|
// after wrapping above in try-catch block, return FALSE on unhandled exception.
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
//----------------------------------------
|
|
//
|
|
// IE401Visited::Import401UrlTranslatingCEI
|
|
//
|
|
// Very much like Import401Url except it makes
|
|
//a call to UpgradeHeaderData before calling CommitCacheEntry.
|
|
|
|
BOOL IE401Visited::Import401UrlTranslatingCEI( ie401::URL_FILEMAP_ENTRY* pEntry)
|
|
{
|
|
BOOL retVal = FALSE;
|
|
|
|
// don't import Url if it is already in the buffer
|
|
if( GetUrlCacheEntryInfo( (LPSTR)((BYTE*)pEntry + pEntry->UrlNameOffset), NULL, 0) == TRUE
|
|
|| GetLastError() != ERROR_FILE_NOT_FOUND)
|
|
{
|
|
goto doneImport401UrlTranslatingCEI;
|
|
}
|
|
|
|
if( pEntry->FileSize != 0)
|
|
{
|
|
INET_ASSERT(0); // Are you importing URL cache entries with external data?
|
|
goto doneImport401UrlTranslatingCEI;
|
|
}
|
|
|
|
DWORD cbHeaderBufSize;
|
|
//BUGBUG: Does shdocvw still obey MAX_CACHE_ENTRY_INFO_SIZE
|
|
//in the version being imported?
|
|
CHAR szHeaderBuf[ MAX_CACHE_ENTRY_INFO_SIZE];
|
|
cbHeaderBufSize = MAX_CACHE_ENTRY_INFO_SIZE;
|
|
|
|
if( pEntry->HeaderInfoOffset != 0)
|
|
{
|
|
if( UpgradeHeaderData( (CHAR*)((BYTE*)pEntry + pEntry->HeaderInfoOffset),
|
|
szHeaderBuf, &cbHeaderBufSize) != TRUE)
|
|
{
|
|
goto doneImport401UrlTranslatingCEI;
|
|
}
|
|
}
|
|
else
|
|
cbHeaderBufSize = 0;
|
|
|
|
if( !CommitUrlCacheEntry(
|
|
(LPCSTR)((BYTE*)pEntry + pEntry->UrlNameOffset),
|
|
NULL,
|
|
*LONGLONG_TO_FILETIME(&pEntry->ExpireTime),
|
|
*LONGLONG_TO_FILETIME(&pEntry->LastModifiedTime),
|
|
pEntry->CacheEntryType,
|
|
cbHeaderBufSize != 0 ?
|
|
(BYTE*)szHeaderBuf : NULL,
|
|
cbHeaderBufSize,
|
|
pEntry->FileExtensionOffset != 0 ?
|
|
((CHAR*)pEntry + pEntry->FileExtensionOffset) : NULL,
|
|
NULL))
|
|
goto doneImport401UrlTranslatingCEI;
|
|
|
|
CACHE_ENTRY_INFO cei;
|
|
|
|
cei.dwStructSize = sizeof(cei);
|
|
cei.LastAccessTime = *LONGLONG_TO_FILETIME(&pEntry->LastAccessedTime);
|
|
cei.dwHitRate = pEntry->NumAccessed;
|
|
cei.ExpireTime = *LONGLONG_TO_FILETIME(&pEntry->ExpireTime);
|
|
cei.LastModifiedTime = *LONGLONG_TO_FILETIME(&pEntry->LastModifiedTime);
|
|
|
|
if( !SetUrlCacheEntryInfo(
|
|
(LPCSTR)((BYTE*)pEntry + pEntry->UrlNameOffset),
|
|
&cei,
|
|
CACHE_ENTRY_ACCTIME_FC | CACHE_ENTRY_HITRATE_FC
|
|
| CACHE_ENTRY_EXPTIME_FC | CACHE_ENTRY_MODTIME_FC))
|
|
goto doneImport401UrlTranslatingCEI;
|
|
|
|
retVal = TRUE;
|
|
|
|
doneImport401UrlTranslatingCEI:
|
|
return retVal;
|
|
|
|
}
|
|
|
|
|
|
BOOL IE401Visited::UpgradeHeaderData(
|
|
IN const CHAR* pIn,
|
|
OUT CHAR* pOut,
|
|
IN OUT DWORD* pcbOutSize)
|
|
{
|
|
BOOL retVal = FALSE;
|
|
|
|
OutputStream op( pOut, *pcbOutSize);
|
|
|
|
// The header info struct contains a HISTDATA followed by
|
|
//a list of HISTEXTRAs.. Their sizes can vary but they should
|
|
//be adjacent. The last HISTEXTRA has a cbExtra of 0 and a sizeof(UINT).
|
|
// When we import a HISTEXTRA (idExtra = PID_INTSITE_TITLE) then
|
|
//we must convert the attached string from ANSI to Unicode
|
|
HISTEXTRA* pExtra = NULL;
|
|
|
|
//first copy the HISTDATA
|
|
if( op.Memcpy( pIn, ((_HISTDATA_V001*)pIn)->cbSize) == FALSE)
|
|
goto doneUpgradeCEIData;
|
|
|
|
for(pExtra = (HISTEXTRA*) (pIn + ((_HISTDATA_V001*)pIn)->cbSize);
|
|
pExtra->cbExtra != 0;
|
|
pExtra = (HISTEXTRA*)((BYTE*)pExtra + pExtra->cbExtra))
|
|
{
|
|
if( pExtra->idExtra != PID_INTSITE_TITLE)
|
|
{
|
|
if( op.Memcpy( pExtra, pExtra->cbExtra) == FALSE)
|
|
goto doneUpgradeCEIData;
|
|
}
|
|
else
|
|
{
|
|
HISTEXTRA* pNew = (HISTEXTRA*)((BYTE*)pOut + op.GetFinalLength());
|
|
|
|
// copy the HISTEXTRA head
|
|
INET_ASSERT( pExtra->cbExtra >= HISTEXTRA_HEAD_SIZE);
|
|
if( op.Memcpy( pExtra, HISTEXTRA_HEAD_SIZE) == FALSE)
|
|
goto doneUpgradeCEIData;
|
|
|
|
if( op.CopyAnsiToUnicode( (CHAR*)&(pExtra->abExtra),
|
|
pExtra->cbExtra - HISTEXTRA_HEAD_SIZE)
|
|
== FALSE)
|
|
goto doneUpgradeCEIData;
|
|
|
|
pNew->vtExtra = VT_LPWSTR;
|
|
|
|
// cbExtra(size) is the change in position of the output stream.
|
|
pNew->cbExtra = ((BYTE*)pOut + op.GetFinalLength()) - (BYTE*)pNew;
|
|
}
|
|
}
|
|
|
|
// the final member in the list is just a DWORD, value == 0.
|
|
// determined from assertions in Urlhist.cpp:
|
|
//ASSERT( phext->cbExtra == 0); // terminator
|
|
//ASSERT( (LPBYTE)phdNew+cbHeader == (LPBYTE)phext+SIZEOF(DWORD) );
|
|
if( op.Memcpy( pExtra, sizeof(DWORD)) == FALSE)
|
|
goto doneUpgradeCEIData;
|
|
|
|
retVal = TRUE;
|
|
|
|
doneUpgradeCEIData:
|
|
|
|
if( retVal == TRUE)
|
|
*pcbOutSize = op.GetFinalLength();
|
|
|
|
return retVal;
|
|
}
|
|
|
|
|
|
//************************************************************************8
|
|
//
|
|
// IE401History : public IE401IndexFile
|
|
//
|
|
|
|
IE401History::IE401History( LPCSTR szFilename) : IE401IndexFile( szFilename)
|
|
{
|
|
}
|
|
|
|
|
|
// imports only URLs using Import401Url then marks them
|
|
//as Visited
|
|
BOOL IE401History::HandleHashElement( ie401::HASH_ITEM* pEntry)
|
|
{
|
|
// No reserved bits should be set.
|
|
INET_ASSERT (!(pEntry->dwHash & HASH_BIT_RESERVED));
|
|
|
|
if( !(pEntry->dwHash & HASH_BIT_NOTURL)
|
|
&& ((ie401::FILEMAP_ENTRY*)(m_pBuf + pEntry->dwOffset))->dwSig == SIG_URL)
|
|
{
|
|
ie401::URL_FILEMAP_ENTRY* pUrlToImport = (ie401::URL_FILEMAP_ENTRY*)(m_pBuf + pEntry->dwOffset);
|
|
|
|
if( Import401Url( pUrlToImport) == TRUE)
|
|
MarkUrlAsVisited( (CHAR*)pUrlToImport + pUrlToImport->UrlNameOffset);
|
|
}
|
|
|
|
// after wrapping above in try-catch block, return FALSE on unhandled exception.
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
// Marks an Url given with a history prefix in the Visited container
|
|
BOOL IE401History::MarkUrlAsVisited( LPSTR szUrlName)
|
|
{
|
|
BOOL retVal = FALSE;
|
|
LPCACHE_ENTRY_INFO pCei = NULL;
|
|
DWORD cbCei = 0;
|
|
|
|
//I'm changing the string from "MSHIST_PREFIX_SZhttp:\\www.urlname"
|
|
//to "VISITED_PREFIX_SZhttp:\\www.urlname" in order to locate/change
|
|
//the cache entry.
|
|
//This requires backing up the old prefix, and setting a new pointer
|
|
//to the correct location to place the new prefix. Once the modified
|
|
//szUrlName is used the old prefix is always restored.
|
|
|
|
// backup the old prefix
|
|
CHAR szBackup[sizeof(MSHIST_PREFIX_SZ)];
|
|
memcpy( szBackup, szUrlName, sizeof(MSHIST_PREFIX_SZ));
|
|
|
|
// Move the pointer to later in the string so that the new, smaller
|
|
//prefix fits, and put the new prefix there.
|
|
LPSTR szModifiedUrl = szUrlName + sizeof(MSHIST_PREFIX_SZ) - sizeof(VISITED_PREFIX_SZ);
|
|
memcpy( szModifiedUrl, VISITED_PREFIX_SZ, sizeof(VISITED_PREFIX_SZ) - 1);
|
|
|
|
// Get the cei
|
|
if( GetUrlCacheEntryInfo( szModifiedUrl, NULL, &cbCei) == TRUE)
|
|
goto doneMarkUrlAsVisited;
|
|
|
|
pCei = (CACHE_ENTRY_INFO*)(new BYTE[cbCei]);
|
|
if( pCei == NULL)
|
|
goto doneMarkUrlAsVisited;
|
|
|
|
if( GetUrlCacheEntryInfo( szModifiedUrl, pCei, &cbCei) != TRUE)
|
|
goto doneMarkUrlAsVisited;
|
|
|
|
if( pCei->dwHeaderInfoSize < sizeof(_HISTDATA_V001))
|
|
goto doneMarkUrlAsVisited;
|
|
|
|
// set the Visited flag
|
|
SET_HISTORY_FLAG(pCei->lpHeaderInfo);
|
|
|
|
CHAR* pStrStr;
|
|
if( pCei->lpHeaderInfo != NULL
|
|
&& (pStrStr = StrStr( pCei->lpHeaderInfo, CACHE_CONTROL_SZ)) != NULL
|
|
&& (pStrStr = StrStr( pStrStr, MUST_REVALIDATE_SZ)) != NULL)
|
|
{
|
|
pCei->CacheEntryType |= MUST_REVALIDATE_CACHE_ENTRY;
|
|
}
|
|
|
|
if( CommitUrlCacheEntry( szModifiedUrl, NULL, pCei->ExpireTime,
|
|
pCei->LastModifiedTime, pCei->CacheEntryType, (BYTE*)pCei->lpHeaderInfo,
|
|
pCei->dwHeaderInfoSize, pCei->lpszFileExtension, NULL) != TRUE)
|
|
goto doneMarkUrlAsVisited;
|
|
|
|
if( SetUrlCacheEntryInfo(
|
|
szModifiedUrl,
|
|
pCei,
|
|
CACHE_ENTRY_ACCTIME_FC | CACHE_ENTRY_HITRATE_FC | CACHE_ENTRY_EXPTIME_FC ) != TRUE)
|
|
goto doneMarkUrlAsVisited;
|
|
|
|
retVal = TRUE;
|
|
|
|
doneMarkUrlAsVisited:
|
|
memcpy( szUrlName, szBackup, sizeof(MSHIST_PREFIX_SZ));
|
|
|
|
if( pCei != NULL)
|
|
delete [] pCei;
|
|
|
|
return retVal;
|
|
}
|
|
|
|
|
|
//************************************************************************8
|
|
//
|
|
// IE401Content : public IE401IndexFile
|
|
//
|
|
|
|
|
|
// on the creation of a IE401Content object, we
|
|
//prepare for the enumeration of its entries by:
|
|
// - identifying the subdirectories of the old cache
|
|
// - register each subdirectory in the new cache
|
|
// - move each subdirectory into the new cache's location
|
|
IE401Content::IE401Content( LPCSTR szFilename)
|
|
: IE401IndexFile( szFilename)
|
|
{
|
|
BOOL fConstructionSuccessful = FALSE;
|
|
|
|
// make sure the index file loaded alright.
|
|
if( m_pBuf == NULL)
|
|
goto exitIE401Construct;
|
|
|
|
// ConfigInfo is retrieved since it contains the path of the new cachefile.
|
|
CACHE_CONFIG_INFO sConfigInfo;
|
|
DWORD dwTemp;
|
|
if( GetUrlCacheConfigInfo( &sConfigInfo,
|
|
&(dwTemp = sizeof(sConfigInfo)),
|
|
CACHE_CONFIG_CONTENT_PATHS_FC)
|
|
== FALSE)
|
|
{
|
|
goto exitIE401Construct;
|
|
}
|
|
|
|
// get the target path for subcontainer move
|
|
m_cbRootPathLength = lstrlen( sConfigInfo.CachePath);
|
|
memcpy( m_szRootPath, sConfigInfo.CachePath, m_cbRootPathLength + 1);
|
|
//target path example: m_szRootPath = "c:\winnt\content.ie5"
|
|
|
|
// get the source path for the subcontainers from the given filename
|
|
DWORD cbSourcePathLength;
|
|
CHAR szSourcePath[MAX_PATH];
|
|
cbSourcePathLength = lstrlen( szFilename);
|
|
memcpy( szSourcePath, szFilename, cbSourcePathLength + 1);
|
|
// clip off the filename so that we have just the path.
|
|
while( cbSourcePathLength > 0 && szSourcePath[cbSourcePathLength] != FILENAME_SEPARATOR)
|
|
{
|
|
cbSourcePathLength--;
|
|
}
|
|
szSourcePath[ ++cbSourcePathLength] = '\0';
|
|
//source path example: szSourcePath = "c:\winnt\content\"
|
|
|
|
// enumerate through the subdirectories,
|
|
// attempt to register that directory in the new cache
|
|
// then move the old directory into the new cache.
|
|
// If the directory cannot be registered or moved, then
|
|
//m_szDir contains "" for that directory index.
|
|
m_nDirs = ((_MEMMAP_HEADER_SMALL*)m_pBuf)->nDirCount;
|
|
DWORD index;
|
|
for( index = 0; index < m_nDirs; index++)
|
|
{
|
|
// get the name of the old subdirectory from the cache.
|
|
memcpy( m_szDir[index],
|
|
((_MEMMAP_HEADER_SMALL*)m_pBuf)->DirArray[index].sDirName,
|
|
DIR_NAME_SIZE);
|
|
m_szDir[index][DIR_NAME_SIZE] = '\0';
|
|
|
|
if( GlobalUrlContainers->CreateContentDirWithSecureName( m_szDir[index]) != TRUE)
|
|
{
|
|
// signal that the directory couldn't be imported and try the next.
|
|
m_szDir[index][0] = '\0';
|
|
continue;
|
|
}
|
|
|
|
// append the subcontainer names to the appropiate destination and source
|
|
//paths.
|
|
memcpy( m_szRootPath + m_cbRootPathLength, m_szDir[index], DIR_NAME_SIZE + 1);
|
|
memcpy( szSourcePath + cbSourcePathLength, m_szDir[index], DIR_NAME_SIZE + 1);
|
|
|
|
#ifndef UNIX
|
|
if( MoveFile( szSourcePath, m_szRootPath) == 0)
|
|
#else
|
|
if (!hConstructSubDirs(m_szRootPath) ||
|
|
CopyDir(szSourcePath, m_szRootPath))
|
|
#endif /* UNIX */
|
|
{
|
|
|
|
// signal that the directory couldn't be imported and try the next.
|
|
m_szDir[index][0] = '\0';
|
|
continue;
|
|
}
|
|
}
|
|
|
|
szSourcePath[ cbSourcePathLength] = '\0';
|
|
m_szRootPath[ m_cbRootPathLength] = '\0';
|
|
|
|
#ifndef UNIX
|
|
// The old index file now is full of dead entries,
|
|
//so we don't keep it around.
|
|
DeleteFile( szFilename);
|
|
#endif /* UNIX */
|
|
|
|
fConstructionSuccessful = TRUE;
|
|
|
|
exitIE401Construct:
|
|
|
|
if( fConstructionSuccessful != TRUE)
|
|
{
|
|
if( m_pBuf != NULL)
|
|
delete [] m_pBuf;
|
|
|
|
m_pBuf = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
// imports only URLs using Import401Url
|
|
BOOL IE401Content::HandleHashElement( ie401::HASH_ITEM* pEntry)
|
|
{
|
|
// No reserved bits should be set.
|
|
INET_ASSERT (!(pEntry->dwHash & HASH_BIT_RESERVED));
|
|
|
|
if( !(pEntry->dwHash & HASH_BIT_NOTURL)
|
|
&& ((ie401::FILEMAP_ENTRY*)(m_pBuf + pEntry->dwOffset))->dwSig == SIG_URL)
|
|
{
|
|
Import401UrlWithFile( (ie401::URL_FILEMAP_ENTRY*)(m_pBuf + pEntry->dwOffset));
|
|
}
|
|
|
|
// after wrapping above in try-catch block, return FALSE on unhandled exception.
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
// Extends the default to import files
|
|
BOOL IE401Content::Import401UrlWithFile( ie401::URL_FILEMAP_ENTRY* pEntry)
|
|
{
|
|
BOOL retVal = FALSE;
|
|
|
|
// don't import Url if it is already in the buffer
|
|
if( GetUrlCacheEntryInfo( (LPSTR)((BYTE*)pEntry + pEntry->UrlNameOffset), NULL, 0) == TRUE
|
|
|| GetLastError() != ERROR_FILE_NOT_FOUND)
|
|
{
|
|
goto doneImport401Url;
|
|
}
|
|
|
|
// don't import an URL if its one of those weird registered files.
|
|
if( (pEntry->DirIndex == IE401_NOT_A_CACHE_SUBDIRECTORY)
|
|
|| (pEntry->CacheEntryType & IE401_EDITED_CACHE_ENTRY))
|
|
{
|
|
goto doneImport401Url;
|
|
}
|
|
|
|
if( pEntry->FileSize != 0)
|
|
{
|
|
// don't import Url if it's subdirectory didn't get created
|
|
if( m_szDir[pEntry->DirIndex][0] == '\0')
|
|
goto doneImport401Url;
|
|
|
|
// store the new file path in m_szRoot
|
|
memcpy( m_szRootPath + m_cbRootPathLength, m_szDir[pEntry->DirIndex], DIR_NAME_SIZE);
|
|
m_szRootPath[ m_cbRootPathLength + DIR_NAME_SIZE] = FILENAME_SEPARATOR;
|
|
m_szRootPath[ m_cbRootPathLength + DIR_NAME_SIZE + 1] = '\0';
|
|
|
|
// This may result in truncation of the filename, when the 401 generated filename to
|
|
// particularly long, causing the total path to exceed MAX_PATH.
|
|
// We won't worry abou this.
|
|
StrCatBuff(m_szRootPath,
|
|
(CHAR*)pEntry + pEntry->InternalFileNameOffset,
|
|
MAX_PATH);
|
|
}
|
|
|
|
if( !CommitUrlCacheEntry(
|
|
(LPCSTR)((BYTE*)pEntry + pEntry->UrlNameOffset),
|
|
(pEntry->FileSize != 0)
|
|
? m_szRootPath : NULL,
|
|
*LONGLONG_TO_FILETIME(&pEntry->ExpireTime),
|
|
*LONGLONG_TO_FILETIME(&pEntry->LastModifiedTime),
|
|
pEntry->CacheEntryType,
|
|
pEntry->HeaderInfoOffset != NULL ?
|
|
(BYTE*)((BYTE*)pEntry + pEntry->HeaderInfoOffset) : NULL,
|
|
pEntry->HeaderInfoSize,
|
|
pEntry->FileExtensionOffset != 0 ?
|
|
(LPCSTR)((BYTE*)pEntry + pEntry->FileExtensionOffset) : NULL,
|
|
NULL))
|
|
goto doneImport401Url;
|
|
|
|
CACHE_ENTRY_INFO cei;
|
|
|
|
cei.dwStructSize = sizeof(cei);
|
|
cei.LastAccessTime = *LONGLONG_TO_FILETIME(&pEntry->LastAccessedTime);
|
|
cei.dwHitRate = pEntry->NumAccessed;
|
|
cei.ExpireTime = *LONGLONG_TO_FILETIME(&pEntry->ExpireTime);
|
|
cei.LastModifiedTime = *LONGLONG_TO_FILETIME(&pEntry->LastModifiedTime);
|
|
|
|
if( !SetUrlCacheEntryInfo(
|
|
(LPCSTR)((BYTE*)pEntry + pEntry->UrlNameOffset),
|
|
&cei,
|
|
CACHE_ENTRY_ACCTIME_FC | CACHE_ENTRY_HITRATE_FC
|
|
| CACHE_ENTRY_EXPTIME_FC | CACHE_ENTRY_MODTIME_FC))
|
|
goto doneImport401Url;
|
|
|
|
retVal = TRUE;
|
|
|
|
doneImport401Url:
|
|
|
|
// Remove appended data
|
|
m_szRootPath[m_cbRootPathLength] = '\0';
|
|
|
|
return retVal;
|
|
}
|
|
|
|
|
|
|
|
//*************************************************************************
|
|
//
|
|
// Import401Redirects()
|
|
//
|
|
|
|
IE401Redirects::IE401Redirects( IE401Content* pContent)
|
|
{
|
|
INET_ASSERT( m_pBuf == NULL);
|
|
|
|
m_pBuf = pContent->m_pBuf;
|
|
pContent->m_pBuf = NULL;
|
|
}
|
|
|
|
|
|
// import items that are redirects
|
|
BOOL IE401Redirects::HandleHashElement( ie401::HASH_ITEM* pEntry)
|
|
{
|
|
// No reserved bits should be set.
|
|
INET_ASSERT (!(pEntry->dwHash & HASH_BIT_RESERVED));
|
|
|
|
if((pEntry->dwOffset != HASH_END) && ((ie401::FILEMAP_ENTRY*)(m_pBuf + pEntry->dwOffset))->dwSig == SIG_REDIR)
|
|
{
|
|
Import401Redirect( (ie401::REDIR_FILEMAP_ENTRY*)(m_pBuf + pEntry->dwOffset));
|
|
}
|
|
|
|
// after wrapping above in try-catch block, return FALSE on unhandled exception.
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
// Imports entries that are redirects
|
|
BOOL IE401Redirects::Import401Redirect( ie401::REDIR_FILEMAP_ENTRY* pEntry)
|
|
{
|
|
LPSTR szTargetUrl = NULL;
|
|
|
|
//** wrap this one in an exception block, because just one of these guys
|
|
//might just try to reference into space.
|
|
|
|
// pEntry is an entry to a redirect entry, which contains an offset to a hash entry.
|
|
// That hash entry contains an offset to the filemap entry of the redirect target.
|
|
FILEMAP_ENTRY* pRedirTarget =
|
|
(FILEMAP_ENTRY*)(m_pBuf + ((HASH_ITEM*)(m_pBuf + pEntry->dwItemOffset))->dwOffset);
|
|
// The filemap entry of the redirect target could be a URL filmap entry or another
|
|
//redirect filemap entry. Either way extract the url of that entry as the target url.
|
|
switch( pRedirTarget->dwSig)
|
|
{
|
|
case SIG_REDIR:
|
|
szTargetUrl = ((REDIR_FILEMAP_ENTRY*)pRedirTarget)->szUrl;
|
|
break;
|
|
case SIG_URL:
|
|
szTargetUrl = (CHAR*)pRedirTarget + ((URL_FILEMAP_ENTRY*)pRedirTarget)->UrlNameOffset;
|
|
break;
|
|
default:
|
|
return FALSE;
|
|
}
|
|
|
|
return GlobalUrlContainers->CreateContentRedirect( szTargetUrl, pEntry->szUrl);
|
|
}
|
|
|
|
|
|
//*************************************************************************
|
|
//
|
|
// Import401History()
|
|
//
|
|
|
|
|
|
// Inside IE401_HIST_ROOT{hHistRoot}, there are some keys that list
|
|
//the history containers we want to import. Before we can import those containers,
|
|
//we import the Visited: container. This file will be found in the subdirectory of
|
|
//the location of the first history subcontainer.
|
|
// When we reach a new container, we create it but don't worry about collisions.
|
|
//Existing Url entries are never overwritten by the import process.
|
|
|
|
BOOL Import401History()
|
|
{
|
|
BOOL retVal = FALSE;
|
|
|
|
HKEY hHistRoot = (HKEY) INVALID_HANDLE_VALUE;
|
|
|
|
// get key to root of history information (which is the root of all extensible containers)
|
|
if( REGOPENKEYEX( IsPerUserCache() ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE,
|
|
IE401_HIST_ROOT, 0, KEY_READ, &hHistRoot)
|
|
!= ERROR_SUCCESS)
|
|
{
|
|
hHistRoot = (HKEY) INVALID_HANDLE_VALUE;
|
|
goto doneImport401History;
|
|
}
|
|
|
|
DWORD index; index = 0;
|
|
CHAR szContainerName[MAX_PATH];
|
|
DWORD cbContainerNameLength;
|
|
DWORD dwCacheLimit;
|
|
DWORD dwCacheOptions;
|
|
CHAR szCachePath[MAX_PATH];
|
|
DWORD cbCachePathSize;
|
|
CHAR szCachePrefix[MAX_PATH];
|
|
|
|
// Enumerate through the extensible containers, if they are History containers import them.
|
|
// When the first history container is found, its path can be used to locate the Visited:
|
|
//container which also must be imported.
|
|
while( RegEnumKeyEx( hHistRoot, index++, szContainerName, &(cbContainerNameLength = MAX_PATH),
|
|
NULL,NULL,NULL,NULL) == ERROR_SUCCESS)
|
|
{
|
|
static BOOL fFirstRun = TRUE;
|
|
|
|
// we can't be sure all the extended containers are history containers.
|
|
//This check verifies we only import history containers.
|
|
if( StrCmpNI( szContainerName, MSHIST_SZ, sizeof(MSHIST_SZ) - 1) != 0
|
|
|| cbContainerNameLength != sizeof(MSHIST_KEY_SZ) - 1)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
HKEY hHistContainer = (HKEY) INVALID_HANDLE_VALUE;
|
|
DWORD dwTemp;
|
|
DWORD dwType;
|
|
|
|
if( REGOPENKEYEX( hHistRoot, szContainerName, 0, KEY_READ, &hHistContainer) != ERROR_SUCCESS)
|
|
goto doneImportHistContainer;
|
|
|
|
if( RegQueryValueEx( hHistContainer, CACHE_LIMIT_SZ, 0, &dwType,
|
|
(BYTE*)&dwCacheLimit, &(dwTemp = sizeof(dwCacheLimit))) != ERROR_SUCCESS
|
|
|| dwType != REG_DWORD)
|
|
{
|
|
goto doneImportHistContainer;
|
|
}
|
|
|
|
if( RegQueryValueEx( hHistContainer, CACHE_OPTIONS_SZ, 0, &dwType,
|
|
(BYTE*)&dwCacheOptions, &(dwTemp = sizeof(dwCacheOptions))) != ERROR_SUCCESS
|
|
|| dwType != REG_DWORD)
|
|
{
|
|
goto doneImportHistContainer;
|
|
}
|
|
|
|
if( RegQueryValueEx( hHistContainer, CACHE_PATH_SZ, 0, &dwType,
|
|
(BYTE*)szCachePath, &(cbCachePathSize = sizeof(szCachePath))) != ERROR_SUCCESS
|
|
|| dwType != REG_SZ)
|
|
{
|
|
goto doneImportHistContainer;
|
|
}
|
|
|
|
if( RegQueryValueEx( hHistContainer, CACHE_PREFIX_SZ, 0, &dwType,
|
|
(BYTE*)&szCachePrefix, &(dwTemp = sizeof(szCachePrefix))) != ERROR_SUCCESS
|
|
|| dwType != REG_SZ)
|
|
{
|
|
goto doneImportHistContainer;
|
|
}
|
|
|
|
// After finding the first container, import the Visited: container.
|
|
if( fFirstRun == TRUE)
|
|
{
|
|
// Clip off the path of the history container, and substitute 'index.dat'
|
|
//to identify the Visited container. Import the visited container, and
|
|
//restore the path to the history container.
|
|
CHAR szBuf[sizeof(MSHIST_DIR_SZ)];
|
|
LPSTR szMSHIST = szCachePath + cbCachePathSize - sizeof(MSHIST_DIR_SZ);
|
|
// ex result: szCachePath:"c:\path\MSHIST011998020119980225\", szMSHIST:"MSHIST011998020119980225\"
|
|
|
|
memcpy( szBuf, szMSHIST, sizeof(MSHIST_DIR_SZ));
|
|
// szBuf:"MSHIST011998020119980225\"
|
|
memcpy( szMSHIST, "index.dat", sizeof("index.dat"));
|
|
// szMSHIST:"index.dat" --> szCachePath:"c:\path\index.dat"
|
|
IE401Visited Visited(szCachePath);
|
|
Visited.EnumHashValues();
|
|
memcpy( szMSHIST, szBuf, sizeof(MSHIST_DIR_SZ));
|
|
// szMSHIST:"MSHIST011998020119980225\" --> szCachePath:"c:\path\MSHIST011998020119980225\"
|
|
|
|
fFirstRun = FALSE;
|
|
}
|
|
|
|
// we don't pass the old path so that the container is put in the new one.
|
|
if( CreateUrlCacheContainer( szContainerName, szCachePrefix, NULL,
|
|
dwCacheLimit, 0, dwCacheOptions, NULL, NULL) != TRUE
|
|
&& GetLastError() != ERROR_ALREADY_EXISTS)
|
|
{
|
|
goto doneImportHistContainer;
|
|
}
|
|
|
|
if( cbCachePathSize + (sizeof(INDEX_DAT_SZ) - 1) > MAX_PATH)
|
|
goto doneImportHistContainer;
|
|
|
|
memcpy( szCachePath + cbCachePathSize - 1, INDEX_DAT_SZ, sizeof(INDEX_DAT_SZ));
|
|
|
|
{
|
|
IE401History History( szCachePath);
|
|
|
|
History.EnumHashValues();
|
|
}
|
|
|
|
doneImportHistContainer:
|
|
|
|
if( hHistContainer != (HKEY) INVALID_HANDLE_VALUE)
|
|
REGCLOSEKEY( hHistContainer);
|
|
}
|
|
|
|
retVal = TRUE;
|
|
|
|
doneImport401History:
|
|
|
|
if( hHistRoot != (HKEY) INVALID_HANDLE_VALUE)
|
|
REGCLOSEKEY( hHistRoot);
|
|
|
|
return retVal;
|
|
}
|
|
|
|
|
|
//*************************************************************************
|
|
//
|
|
// Import401Content()
|
|
//
|
|
|
|
|
|
BOOL Import401Content()
|
|
{
|
|
BOOL retVal = FALSE;
|
|
HKEY hContentKey = (HKEY) INVALID_HANDLE_VALUE;
|
|
CHAR szContentFilename[MAX_PATH];
|
|
LPSTR szKeyName = NULL;
|
|
|
|
if( !GetIE5ContentPath(szContentFilename))
|
|
goto doneImport401Content;
|
|
|
|
// we now have something like 'c:\..\content\content.ie5'
|
|
//and we want something like 'c:\..\content\index.dat'
|
|
LONG index;
|
|
|
|
// find the position of the last '\\'
|
|
index = lstrlen( szContentFilename);
|
|
while( index >= 0 && szContentFilename[index] != FILENAME_SEPARATOR)
|
|
index--;
|
|
|
|
// append an 'index.dat'
|
|
memcpy( szContentFilename + index + 1, INDEX_DAT_SZ, sizeof(INDEX_DAT_SZ));
|
|
|
|
#ifdef UNIX
|
|
{
|
|
// HACK HACK
|
|
//
|
|
// we now have something like
|
|
// '/home/blah/.microsoft/ie5/TempInternetFiles/index.dat'
|
|
// and we want something like
|
|
// /home/blah/.microsoft/TempInternetFiles/index.dat
|
|
char szSearchStr[] = "ie5/";
|
|
char *pszWhere = StrStr(szContentFilename, szSearchStr);
|
|
if (pszWhere)
|
|
{
|
|
memmove(pszWhere, pszWhere+sizeof(szSearchStr)-1,
|
|
lstrlen(pszWhere+sizeof(szSearchStr)-1)+1);
|
|
}
|
|
}
|
|
#endif /* UNIX */
|
|
|
|
{
|
|
IE401Content Content(szContentFilename);
|
|
if( Content.EnumHashValues() == TRUE)
|
|
{
|
|
IE401Redirects Redirects( &Content);
|
|
Redirects.EnumHashValues();
|
|
}
|
|
}
|
|
|
|
doneImport401Content:
|
|
|
|
if( hContentKey != (HKEY) INVALID_HANDLE_VALUE)
|
|
REGCLOSEKEY( hContentKey);
|
|
|
|
return retVal;
|
|
}
|
|
|
|
|
|
//-- end of namespace ie401
|
|
}
|
|
//--
|
|
|
|
|
|
//
|
|
//
|
|
// Returns if caches are per user.
|
|
//
|
|
BOOL IsPerUserCache()
|
|
{
|
|
BOOL fProfilesEnabled = FALSE;
|
|
static BOOL fPerUser = FALSE;
|
|
#ifndef UNIX
|
|
// Is the OS version Windows 95 or Windows NT?
|
|
if (GlobalPlatformType == PLATFORM_TYPE_WIN95)
|
|
{
|
|
// Operating System is Windows 95.
|
|
// Look for special key indicating profiles are enables. If its not found,
|
|
//know that profiles aren't enabled.
|
|
|
|
// Determine if profiles are enabled by OS.
|
|
REGISTRY_OBJ roProfilesEnabled(HKEY_LOCAL_MACHINE, PROFILES_ENABLED_VALUE);
|
|
if (roProfilesEnabled.GetStatus() == ERROR_SUCCESS)
|
|
{
|
|
DWORD dwProfilesEnabled = 0;
|
|
|
|
if( roProfilesEnabled.GetValue(PROFILES_ENABLED, &dwProfilesEnabled) == ERROR_SUCCESS)
|
|
{
|
|
// Found the registry entry.
|
|
fProfilesEnabled = (BOOL) dwProfilesEnabled;
|
|
}
|
|
}
|
|
|
|
}
|
|
else if (GlobalPlatformType == PLATFORM_TYPE_WINNT)
|
|
{
|
|
// Profiles always enabled for NT.
|
|
fProfilesEnabled = TRUE;
|
|
}
|
|
#else
|
|
fProfilesEnabled = TRUE;
|
|
#endif /* UNIX */
|
|
|
|
// Determine if per user cache is allowed.
|
|
REGISTRY_OBJ roProfilesAllowed(HKEY_LOCAL_MACHINE, PRE5_CACHE_KEY);
|
|
if( fProfilesEnabled && roProfilesAllowed.GetStatus() == ERROR_SUCCESS)
|
|
{
|
|
DWORD dwPerUserCache = 0;
|
|
|
|
if( roProfilesAllowed.GetValue(PROFILES_ENABLED,&dwPerUserCache) == ERROR_SUCCESS)
|
|
{
|
|
// Found the registry entry. Set g_fPerUserCache to
|
|
// TRUE only if profiles are enabled.
|
|
fPerUser = ((BOOL) dwPerUserCache);
|
|
}
|
|
else
|
|
{
|
|
// No entry. If profiles are enabled, assume they're allowed.
|
|
fPerUser = fProfilesEnabled;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
fPerUser = fProfilesEnabled;
|
|
}
|
|
|
|
return fPerUser;
|
|
}
|
|
|