windows-nt/Source/XPSP1/NT/com/ole32/stg/async/layout/mapfile.cxx
2020-09-26 16:20:57 +08:00

243 lines
5.9 KiB
C++

//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1994.
//
// File: mapfile.cxx
//
// Contents: Mapped file class implementation
//
// Classes:
//
// Functions:
//
// History: 12-Feb-96 PhilipLa Created
//
//----------------------------------------------------------------------------
#include "layouthd.cxx"
#pragma hdrstop
//#define TEST_MAPPING_LOWMEM
CMappedFile::~CMappedFile(void)
{
#ifdef SUPPORT_FILE_MAPPING
if (_pbBase != NULL)
{
UnmapViewOfFile(_pbBase);
}
if (_hMapping != INVALID_HANDLE_VALUE)
{
CloseHandle(_hMapping);
}
#endif
if (_hFile != INVALID_HANDLE_VALUE)
{
CloseHandle(_hFile);
}
}
//+---------------------------------------------------------------------------
//
// Member: CMappedFile::InitFromHandle, public
//
// Synopsis: Initialize object based on file handle
//
// Arguments: [h] -- File handle
// [fReadOnly] -- TRUE if mapping is to be read-only
// [fDuplicate] -- TRUE if handle is to be duplicated
// [pvDesiredBaseAddress] -- Desired address for mapping
//
// Returns: Appropriate status code
//
// History: 13-Feb-96 PhilipLa Created
//
//----------------------------------------------------------------------------
SCODE CMappedFile::InitFromHandle(HANDLE h,
BOOL fReadOnly,
BOOL fDuplicate,
void *pvDesiredBaseAddress)
{
SCODE sc = S_OK;
if (fDuplicate)
{
if (!DuplicateHandle(GetCurrentProcess(),
h,
GetCurrentProcess(),
&_hFile,
0,
TRUE,
DUPLICATE_SAME_ACCESS))
{
layErr(Err, STG_SCODE(GetLastError()));
}
}
else
{
_hFile = h;
}
#ifdef SUPPORT_FILE_MAPPING
#ifndef UNICODE
_hMapping = CreateFileMappingA
#else
_hMapping = CreateFileMapping
#endif
(_hFile,
NULL, // No security
(fReadOnly) ? PAGE_READONLY : PAGE_READWRITE,
0,
0, //File size determines map size
NULL); // Unnamed
#ifdef TEST_MAPPING_LOWMEM
CloseHandle(_hMapping);
_hMapping = NULL;
#endif
if (_hMapping != NULL)
{
//Mapping created OK, now map view
_pbBase = MapViewOfFileEx(_hMapping,
(fReadOnly) ? FILE_MAP_READ : FILE_MAP_WRITE,
0,
0,
0,
pvDesiredBaseAddress);
if (_pbBase == NULL)
{
CloseHandle(_hMapping);
_hMapping = INVALID_HANDLE_VALUE;
}
}
#endif //SUPPORT_FILE_MAPPING
Err:
return sc;
}
//+---------------------------------------------------------------------------
//
// Member: CMappedFile::Init, public
//
// Synopsis: Initialize based on a filename
//
// Arguments: [pwcsName] -- Filename for file
// [dwSize] -- Desired size of file, 0 for no size change
// [dwAccess] -- Access mode for file (see CreateFile)
// [dwCreationDisposition] -- Creation for file (see CreateFile)
// [pvDesiredBaseAddress] -- Desired base address for mapping
//
// Returns: Appropriate status code
//
// History: 13-Feb-96 PhilipLa Created
//
//----------------------------------------------------------------------------
SCODE CMappedFile::Init(OLECHAR const *pwcsName,
DWORD dwSize,
DWORD dwAccess,
DWORD dwCreationDisposition,
void *pvDesiredBaseAddress)
{
SCODE sc;
BOOL fReadOnly = ((dwAccess & GENERIC_WRITE) == 0);
layAssert(!fReadOnly || (dwSize == 0));
if (pwcsName == NULL)
return STG_E_INVALIDNAME;
#if (!defined(UNICODE) && !defined(_MAC))
TCHAR atcPath[MAX_PATH + 1];
UINT uCodePage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
if (!WideCharToMultiByte(
uCodePage,
0,
pwcsName,
-1,
atcPath,
MAX_PATH + 1,
NULL,
NULL))
{
return STG_E_INVALIDNAME;
}
_hFile = CreateFileA(atcPath,
dwAccess,
0, //No sharing
NULL, //No security
dwCreationDisposition,
FILE_ATTRIBUTE_NORMAL,
NULL); // No template file
#else
_hFile = CreateFile(pwcsName,
dwAccess,
0, //No sharing
NULL, //No security
dwCreationDisposition,
FILE_ATTRIBUTE_NORMAL,
NULL); // No template file
#endif
if (_hFile == INVALID_HANDLE_VALUE)
{
layErr(Err, STG_SCODE(GetLastError()));
}
if (dwSize != 0)
{
DWORD dw = SetFilePointer(_hFile,
dwSize,
NULL,
FILE_BEGIN);
if (dw == 0xFFFFFFFF)
{
layErr(Err, STG_SCODE(GetLastError()));
}
if (!SetEndOfFile(_hFile))
{
layErr(Err, STG_SCODE(GetLastError()));
}
}
else
{
DWORD dwFileSize;
dwFileSize = GetFileSize(_hFile, NULL);
if (dwFileSize == 0xFFFFFFFF)
{
layErr(Err, STG_SCODE(GetLastError()));
}
if ( dwFileSize == 0 )
{
return STG_S_FILEEMPTY;
}
}
layChk(InitFromHandle(_hFile, fReadOnly, FALSE, pvDesiredBaseAddress));
Err:
return sc;
}