514 lines
12 KiB
C++
514 lines
12 KiB
C++
//+---------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1992 - 1994.
|
|
//
|
|
// File: mapfile.hxx
|
|
//
|
|
// Contents: Mapped File class definition
|
|
//
|
|
// Classes:
|
|
//
|
|
// Functions:
|
|
//
|
|
// History: 12-Feb-96 PhilipLa Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#ifndef __MAPFILE_HXX__
|
|
#define __MAPFILE_HXX__
|
|
|
|
#ifdef _MAC
|
|
extern void swap(char *src, int nSize);
|
|
#else
|
|
#define swap(x, y)
|
|
#endif // _MAC
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Class: CMappedFile
|
|
//
|
|
// Purpose: Provides a wrapper over a file mapping
|
|
//
|
|
// Interface:
|
|
//
|
|
// History: 12-Feb-96 PhilipLa Created
|
|
//
|
|
// Notes:
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
class CMappedFile
|
|
{
|
|
public:
|
|
inline CMappedFile();
|
|
~CMappedFile();
|
|
|
|
SCODE Init(OLECHAR const *pwcsFileName,
|
|
DWORD dwSize,
|
|
DWORD dwAccess,
|
|
DWORD dwCreationDisposition,
|
|
void *pbDesiredBaseAddress);
|
|
SCODE InitFromHandle(HANDLE h,
|
|
BOOL fReadOnly,
|
|
BOOL fDuplicate,
|
|
void *pbDesiredBaseAddress);
|
|
inline void * GetBaseAddress(void);
|
|
inline ULONG GetSize(void);
|
|
|
|
//Stuff for unmappable mode
|
|
inline SECT operator[](ULONG uOffset);
|
|
|
|
inline USHORT GetUSHORT(ULONG uOffset);
|
|
inline ULONG GetULONG(ULONG uOffset);
|
|
|
|
inline CMSFHeaderData * GetCMSFHeaderData(void);
|
|
inline CFatSect * GetCFatSect (ULONG uOffset);
|
|
inline CDirSect * GetCDirSect (ULONG uOffset);
|
|
|
|
|
|
inline SCODE ReadFromFile( BYTE *pbBuffer,
|
|
ULONG uOffset,
|
|
ULONG uSize );
|
|
inline SCODE WriteToFile( BYTE *pbBuffer,
|
|
ULONG uOffset,
|
|
ULONG uSize );
|
|
|
|
inline SCODE WriteToFile (CMSFHeaderData *pheader);
|
|
inline SCODE WriteToFile (CFatSect *pfs);
|
|
inline SCODE WriteToFile (CDirSect *pds);
|
|
|
|
inline void Remove (CMSFHeaderData *pheader);
|
|
inline void Remove (CFatSect *pfs);
|
|
inline void Remove (CDirSect *pds);
|
|
|
|
inline void SetSectorSize(ULONG cbSectorSize);
|
|
|
|
private:
|
|
HANDLE _hFile;
|
|
|
|
#ifdef SUPPORT_FILE_MAPPING
|
|
HANDLE _hMapping;
|
|
#endif
|
|
|
|
void *_pbBase;
|
|
DWORD _dwFatSectOffset;
|
|
DWORD _dwDirSectOffset;
|
|
DWORD _dwHeaderOffset;
|
|
ULONG _uSectorSize;
|
|
};
|
|
|
|
|
|
inline SECT CMappedFile::operator[](ULONG uOffset)
|
|
{
|
|
SECT sect;
|
|
DWORD dwBytesRead = 0;
|
|
|
|
if (_pbBase == NULL)
|
|
{
|
|
Verify (-1 != SetFilePointer(_hFile,
|
|
uOffset * sizeof(SECT),
|
|
0,
|
|
FILE_BEGIN));
|
|
|
|
|
|
Verify (ReadFile( _hFile, §, sizeof(SECT), &dwBytesRead, NULL));
|
|
|
|
// we are writing the script as is
|
|
// swap((char *) §, sizeof(ULONG));
|
|
}
|
|
else
|
|
{
|
|
sect = ((ULONG *)_pbBase)[uOffset];
|
|
}
|
|
|
|
return sect;
|
|
|
|
}
|
|
|
|
inline USHORT CMappedFile::GetUSHORT(ULONG uOffset)
|
|
{
|
|
USHORT ushort;
|
|
DWORD dwBytesRead = 0;
|
|
|
|
if (_pbBase == NULL)
|
|
{
|
|
Verify (-1 != SetFilePointer(_hFile, uOffset, 0, FILE_BEGIN));
|
|
|
|
Verify (ReadFile( _hFile,
|
|
&ushort,
|
|
sizeof(USHORT),
|
|
&dwBytesRead,
|
|
NULL));
|
|
}
|
|
else
|
|
{
|
|
ushort = *(USHORT *)((BYTE *)_pbBase+ uOffset);
|
|
}
|
|
|
|
swap((char *) &ushort, sizeof(USHORT));
|
|
|
|
return ushort;
|
|
|
|
}
|
|
|
|
inline ULONG CMappedFile::GetULONG(ULONG uOffset)
|
|
{
|
|
ULONG ulong;
|
|
DWORD dwBytesRead = 0;
|
|
|
|
if (_pbBase == NULL)
|
|
{
|
|
Verify (-1 != SetFilePointer(_hFile, uOffset, 0, FILE_BEGIN));
|
|
|
|
Verify (ReadFile( _hFile, &ulong, sizeof(ULONG), &dwBytesRead, NULL));
|
|
}
|
|
else
|
|
{
|
|
ulong = *(ULONG *)((BYTE *)_pbBase+ uOffset);
|
|
}
|
|
|
|
swap((char *) &ulong, sizeof(ULONG));
|
|
|
|
return ulong;
|
|
|
|
}
|
|
|
|
inline CMSFHeaderData * CMappedFile::GetCMSFHeaderData(void)
|
|
{
|
|
CMSFHeaderData *ph;
|
|
|
|
if (_pbBase == NULL)
|
|
{
|
|
// We should never be working on more than one at a time
|
|
Assert (_dwHeaderOffset == (DWORD) -1);
|
|
|
|
DWORD dwBytesRead = 0;
|
|
ph = (CMSFHeaderData *) CoTaskMemAlloc(sizeof(CMSFHeaderData));
|
|
|
|
Assert (ph != NULL);
|
|
|
|
_dwHeaderOffset = 0;
|
|
|
|
Verify (-1 != SetFilePointer(_hFile, 0, 0, FILE_BEGIN));
|
|
Verify (ReadFile( _hFile,
|
|
ph,
|
|
sizeof(CMSFHeaderData),
|
|
&dwBytesRead,
|
|
NULL));
|
|
}
|
|
else
|
|
{
|
|
ph = (CMSFHeaderData *)_pbBase;
|
|
}
|
|
|
|
|
|
swap((char *) &(ph->_uMinorVersion), sizeof(USHORT));
|
|
swap((char *)&(ph->_uDllVersion), sizeof(USHORT));
|
|
swap((char *)&(ph->_uByteOrder), sizeof(USHORT));
|
|
swap((char *)&(ph->_uSectorShift), sizeof(USHORT));
|
|
swap((char *)&(ph->_uMiniSectorShift), sizeof(USHORT));
|
|
swap((char *)&(ph->_usReserved), sizeof(USHORT));
|
|
swap((char *)&(ph->_ulReserved1), sizeof(ULONG));
|
|
swap((char *)&(ph->_ulReserved2), sizeof(ULONG));
|
|
swap((char *)&(ph->_csectFat), sizeof(FSINDEX));
|
|
swap((char *)&(ph->_sectDirStart), sizeof(SECT));
|
|
swap((char *)&(ph->_signature), sizeof(DFSIGNATURE));
|
|
swap((char *)&(ph->_ulMiniSectorCutoff), sizeof(ULONG));
|
|
swap((char *)&(ph->_sectMiniFatStart), sizeof(SECT));
|
|
swap((char *)&(ph->_csectMiniFat), sizeof(FSINDEX));
|
|
swap((char *)&(ph->_sectDifStart), sizeof(SECT));
|
|
swap((char *)&(ph->_csectDif), sizeof(FSINDEX));
|
|
for (ULONG i = 0; i < CSECTFAT; i++)
|
|
{
|
|
swap((char *)&(ph->_sectFat[i]), sizeof(SECT));
|
|
|
|
}
|
|
|
|
return ph;
|
|
}
|
|
|
|
|
|
inline CFatSect * CMappedFile::GetCFatSect (ULONG uOffset)
|
|
{
|
|
UINT i;
|
|
CFatSect *pfs;
|
|
|
|
if (_pbBase == NULL)
|
|
{
|
|
// We should never be working on more than one at a time
|
|
Assert (_dwFatSectOffset == (DWORD) -1);
|
|
|
|
|
|
DWORD dwBytesRead = 0;
|
|
pfs = (CFatSect *) CoTaskMemAlloc (_uSectorSize );
|
|
|
|
Assert (pfs != NULL);
|
|
_dwFatSectOffset = uOffset;
|
|
|
|
Verify(-1 != SetFilePointer(_hFile, uOffset, 0, FILE_BEGIN));
|
|
Verify (ReadFile( _hFile, pfs, _uSectorSize, &dwBytesRead, NULL));
|
|
}
|
|
else
|
|
{
|
|
pfs = (CFatSect *)((BYTE *)_pbBase + uOffset);
|
|
}
|
|
|
|
for (i = 0; i < _uSectorSize; i += sizeof(SECT))
|
|
{
|
|
swap((char *) &(pfs[i]), sizeof(SECT) );
|
|
}
|
|
return pfs;
|
|
}
|
|
|
|
|
|
inline CDirSect * CMappedFile::GetCDirSect (ULONG uOffset)
|
|
{
|
|
CDirSect *pds;
|
|
|
|
if (_pbBase == NULL)
|
|
{
|
|
// We should never be working on more than one at a time
|
|
Assert (_dwDirSectOffset == (DWORD) -1);
|
|
|
|
|
|
DWORD dwBytesRead = 0;
|
|
pds = (CDirSect *) CoTaskMemAlloc (_uSectorSize);
|
|
|
|
Assert (pds != NULL);
|
|
_dwDirSectOffset = uOffset;
|
|
|
|
Verify (-1 != SetFilePointer(_hFile, uOffset, 0, FILE_BEGIN));
|
|
Verify (ReadFile( _hFile, pds, _uSectorSize, &dwBytesRead, NULL));
|
|
}
|
|
else
|
|
{
|
|
pds = (CDirSect *)((BYTE *)_pbBase + uOffset);
|
|
}
|
|
// don't swap this all here, because it is a byte array.
|
|
// We will have to individual members separately
|
|
|
|
return pds;
|
|
}
|
|
|
|
inline SCODE CMappedFile::ReadFromFile(BYTE *pbBuffer,
|
|
ULONG uOffset,
|
|
ULONG uSize)
|
|
{
|
|
DWORD dwBytesRead = 0;
|
|
|
|
if (pbBuffer == NULL)
|
|
{
|
|
return STG_E_INVALIDPARAMETER;
|
|
}
|
|
if (-1 == SetFilePointer(_hFile, uOffset, 0, FILE_BEGIN))
|
|
{
|
|
return GetLastError();
|
|
}
|
|
if (!ReadFile( _hFile, pbBuffer, uSize, &dwBytesRead, NULL))
|
|
{
|
|
return GetLastError();
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
inline SCODE CMappedFile::WriteToFile( BYTE *pbBuffer,
|
|
ULONG uOffset,
|
|
ULONG uSize )
|
|
{
|
|
DWORD dwBytesWritten = 0;
|
|
|
|
if (pbBuffer == NULL)
|
|
{
|
|
return STG_E_INVALIDPARAMETER;
|
|
}
|
|
if (-1 == SetFilePointer(_hFile, uOffset, 0, FILE_BEGIN))
|
|
{
|
|
return GetLastError();
|
|
}
|
|
if (!WriteFile( _hFile, pbBuffer, uSize, &dwBytesWritten, NULL))
|
|
{
|
|
return GetLastError();
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
inline SCODE CMappedFile::WriteToFile (CMSFHeaderData *pheader)
|
|
{
|
|
DWORD dwBytesWritten = 0;
|
|
|
|
|
|
|
|
if (pheader == NULL)
|
|
{
|
|
return STG_E_INVALIDPARAMETER;
|
|
}
|
|
|
|
swap((char *) &(pheader->_uMinorVersion), sizeof(USHORT));
|
|
swap((char *) &(pheader->_uDllVersion), sizeof(USHORT));
|
|
swap((char *) &(pheader->_uByteOrder), sizeof(USHORT));
|
|
swap((char *) &(pheader->_uSectorShift), sizeof(USHORT));
|
|
swap((char *) &(pheader->_uMiniSectorShift), sizeof(USHORT));
|
|
swap((char *)&(pheader->_usReserved), sizeof(USHORT));
|
|
swap((char *)&(pheader->_ulReserved1), sizeof(ULONG));
|
|
swap((char *)&(pheader->_ulReserved2), sizeof(ULONG));
|
|
swap((char *)&(pheader->_csectFat), sizeof(FSINDEX));
|
|
swap((char *)&(pheader->_sectDirStart), sizeof(SECT));
|
|
swap((char *)&(pheader->_signature), sizeof(DFSIGNATURE));
|
|
swap((char *)&(pheader->_ulMiniSectorCutoff), sizeof(ULONG));
|
|
swap((char *)&(pheader->_sectMiniFatStart), sizeof(SECT));
|
|
swap((char *)&(pheader->_csectMiniFat), sizeof(FSINDEX));
|
|
swap((char *)&(pheader->_sectDifStart), sizeof(SECT));
|
|
swap((char *)&(pheader->_csectDif), sizeof(FSINDEX));
|
|
for (ULONG i = 0; i < CSECTFAT; i++)
|
|
{
|
|
swap((char *)&(pheader->_sectFat[i]), sizeof(SECT));
|
|
|
|
}
|
|
|
|
if (_pbBase == NULL)
|
|
{
|
|
if (-1 == SetFilePointer(_hFile, 0, 0, FILE_BEGIN))
|
|
{
|
|
return GetLastError();
|
|
}
|
|
|
|
if (!WriteFile(_hFile,
|
|
pheader,
|
|
sizeof (CMSFHeaderData),
|
|
&dwBytesWritten,
|
|
NULL))
|
|
{
|
|
return GetLastError();
|
|
}
|
|
}
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
inline SCODE CMappedFile::WriteToFile (CFatSect *pfs)
|
|
{
|
|
DWORD dwBytesWritten = 0;
|
|
UINT i;
|
|
|
|
if (pfs == NULL)
|
|
{
|
|
return STG_E_INVALIDPARAMETER;
|
|
}
|
|
|
|
for (i =0; i < _uSectorSize; i += sizeof(SECT))
|
|
{
|
|
swap((char *) &(pfs[i]), sizeof(SECT) );
|
|
}
|
|
|
|
if (_pbBase == NULL)
|
|
{
|
|
if (-1 == SetFilePointer(_hFile, _dwFatSectOffset, 0, FILE_BEGIN))
|
|
{
|
|
return GetLastError();
|
|
}
|
|
|
|
if (!WriteFile( _hFile, pfs, _uSectorSize, &dwBytesWritten, NULL))
|
|
{
|
|
return GetLastError();
|
|
}
|
|
}
|
|
return S_OK;
|
|
}
|
|
|
|
inline SCODE CMappedFile::WriteToFile (CDirSect *pds)
|
|
{
|
|
DWORD dwBytesWritten = 0;
|
|
|
|
if (pds == NULL)
|
|
{
|
|
return STG_E_INVALIDPARAMETER;
|
|
}
|
|
|
|
if (_pbBase == NULL)
|
|
{
|
|
if (-1 == SetFilePointer(_hFile, _dwDirSectOffset, 0, FILE_BEGIN))
|
|
{
|
|
return GetLastError();
|
|
}
|
|
// don't swap this all here, because it is a byte array.
|
|
// We will have to individual members separately
|
|
|
|
if (!WriteFile( _hFile, pds, _uSectorSize, &dwBytesWritten, NULL))
|
|
{
|
|
return GetLastError();
|
|
}
|
|
}
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
inline void CMappedFile::Remove (CMSFHeaderData *pheader)
|
|
{
|
|
if (_pbBase == NULL)
|
|
{
|
|
_dwHeaderOffset = (DWORD) -1;
|
|
CoTaskMemFree(pheader);
|
|
}
|
|
}
|
|
|
|
inline void CMappedFile::Remove (CFatSect *pfs)
|
|
{
|
|
if (_pbBase == NULL)
|
|
{
|
|
_dwFatSectOffset = (DWORD) -1;
|
|
CoTaskMemFree (pfs);
|
|
}
|
|
|
|
}
|
|
|
|
inline void CMappedFile::Remove (CDirSect *pds)
|
|
{
|
|
if (_pbBase == NULL)
|
|
{
|
|
_dwDirSectOffset = (DWORD) -1;
|
|
CoTaskMemFree (pds);
|
|
}
|
|
|
|
}
|
|
|
|
inline void CMappedFile::SetSectorSize(ULONG cbSectorSize)
|
|
{
|
|
_uSectorSize = cbSectorSize;
|
|
|
|
}
|
|
|
|
|
|
inline CMappedFile::CMappedFile(void)
|
|
{
|
|
_hFile = INVALID_HANDLE_VALUE;
|
|
|
|
#ifdef SUPPORT_FILE_MAPPING
|
|
_hMapping = INVALID_HANDLE_VALUE;
|
|
#endif
|
|
|
|
_pbBase = NULL;
|
|
_dwFatSectOffset = (DWORD) -1;
|
|
_dwDirSectOffset = (DWORD) -1;
|
|
_dwHeaderOffset = (DWORD) -1;
|
|
_uSectorSize = 512; //default sector size
|
|
}
|
|
|
|
inline void * CMappedFile::GetBaseAddress(void)
|
|
{
|
|
return _pbBase;
|
|
}
|
|
|
|
|
|
inline ULONG CMappedFile::GetSize(void)
|
|
{
|
|
layAssert(_hFile != INVALID_HANDLE_VALUE);
|
|
return GetFileSize(_hFile, NULL);
|
|
}
|
|
|
|
#endif // #ifndef __MAPFILE_HXX__
|