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.
293 lines
7.8 KiB
293 lines
7.8 KiB
//+---------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1991 - 1992.
|
|
//
|
|
// File: Borrow.hxx
|
|
//
|
|
// Contents: Smart encapsulation of buffer
|
|
//
|
|
// Classes: CBorrowed
|
|
//
|
|
// History: 27-Dec-19 KyleP Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#pragma once
|
|
|
|
#include <propstor.hxx>
|
|
#include <proprec.hxx>
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Class: CBorrowed
|
|
//
|
|
// Purpose: Smart wrapper for bowwowing (and returning!) buffer.
|
|
//
|
|
// History: 27-Dec-95 KyleP Created
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
class CBorrowed
|
|
{
|
|
public:
|
|
|
|
inline CBorrowed( CPhysPropertyStore & store,
|
|
ULONG cRecPerPage,
|
|
ULONG culRec );
|
|
|
|
inline CBorrowed( CPhysPropertyStore & store,
|
|
WORKID wid,
|
|
ULONG cRecPerPage,
|
|
ULONG culRec,
|
|
BOOL fIntentToWrite = TRUE );
|
|
|
|
inline CBorrowed( CBorrowed & src );
|
|
|
|
inline ~CBorrowed();
|
|
|
|
inline CBorrowed & operator=( CBorrowed & src );
|
|
|
|
inline void Set( WORKID wid, BOOL fIntentToWrite = TRUE );
|
|
inline void SetMaybeNew( WORKID wid );
|
|
|
|
inline void Release();
|
|
|
|
inline COnDiskPropertyRecord * Get();
|
|
|
|
private:
|
|
|
|
COnDiskPropertyRecord * _prec;
|
|
ULONG _nLargePage;
|
|
ULONG _cRecPerPage;
|
|
ULONG _culRec;
|
|
CPhysPropertyStore & _store;
|
|
};
|
|
|
|
#if CIDBG == 1
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Class: XBorrowExisting
|
|
//
|
|
// Purpose: Smart wrapper for borrowing (and returning!) buffer.
|
|
//
|
|
// History: 16-Oct-97 KyleP Created
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
class XBorrowExisting
|
|
{
|
|
public:
|
|
|
|
XBorrowExisting( CPhysPropertyStore & store, ULONG nLargePage, BOOL fWrite = FALSE )
|
|
: _store( store ),
|
|
_nLargePage( nLargePage ),
|
|
_pulPage( _store.BorrowLargeBuffer( nLargePage, fWrite ) )
|
|
{
|
|
}
|
|
|
|
~XBorrowExisting()
|
|
{
|
|
_store.ReturnLargeBuffer( _nLargePage );
|
|
}
|
|
|
|
BYTE * Get() { return (BYTE *)_pulPage; }
|
|
|
|
private:
|
|
|
|
CPhysStorage & _store;
|
|
ULONG _nLargePage;
|
|
ULONG * _pulPage;
|
|
};
|
|
#endif
|
|
|
|
inline CBorrowed::CBorrowed( CPhysPropertyStore & store,
|
|
ULONG cRecPerPage,
|
|
ULONG culRec )
|
|
: _store( store ),
|
|
_prec( 0 ),
|
|
_nLargePage( 0xFFFFFFFF ),
|
|
_cRecPerPage( cRecPerPage ),
|
|
_culRec( culRec )
|
|
{
|
|
}
|
|
|
|
|
|
inline CBorrowed::CBorrowed( CPhysPropertyStore & store,
|
|
WORKID wid,
|
|
ULONG cRecPerPage,
|
|
ULONG culRec,
|
|
BOOL fIntentToWrite )
|
|
: _store( store ),
|
|
_prec( 0 ),
|
|
_nLargePage( 0xFFFFFFFF ),
|
|
_cRecPerPage( cRecPerPage ),
|
|
_culRec( culRec )
|
|
{
|
|
Set( wid, fIntentToWrite );
|
|
}
|
|
|
|
inline CBorrowed::CBorrowed( CBorrowed & src )
|
|
: _store( src._store ),
|
|
_prec( 0 ),
|
|
_nLargePage( 0xFFFFFFFF ),
|
|
_cRecPerPage( src._cRecPerPage ),
|
|
_culRec( src._culRec )
|
|
{
|
|
*this = src;
|
|
}
|
|
|
|
inline CBorrowed::~CBorrowed()
|
|
{
|
|
Release();
|
|
}
|
|
|
|
inline CBorrowed & CBorrowed::operator=( CBorrowed & src )
|
|
{
|
|
Win4Assert( &_store == &src._store );
|
|
Win4Assert( _cRecPerPage == src._cRecPerPage );
|
|
|
|
Win4Assert( 0xFFFFFFFF == _nLargePage );
|
|
|
|
_nLargePage = src._nLargePage;
|
|
src._nLargePage = 0xFFFFFFFF;
|
|
|
|
_prec = src._prec;
|
|
src._prec = 0;
|
|
|
|
return *this;
|
|
}
|
|
|
|
inline void CBorrowed::Set( WORKID wid, BOOL fIntentToWrite )
|
|
{
|
|
Win4Assert( 0xFFFFFFFF == _nLargePage && "Borrow buffer not released" );
|
|
Win4Assert( 0 == _prec );
|
|
|
|
if (widInvalid == wid || 0 == wid)
|
|
{
|
|
ciDebugOut((DEB_PROPSTORE, "CBorrowed::Set: Attempted to set wid 0x%x!\n", wid));
|
|
}
|
|
else
|
|
{
|
|
|
|
WORKID widInRec = wid % _cRecPerPage;
|
|
ULONG nLargePage = wid / _cRecPerPage;
|
|
|
|
// Borrow the buffer for write and pass the intent to write flag
|
|
|
|
|
|
#if 0 // compiler bug 3/27/02 in Windows Server 2003 tree 13.01.2035
|
|
|
|
_prec = new( widInRec,
|
|
(BYTE *)_store.BorrowLargeBuffer( nLargePage,
|
|
TRUE,
|
|
fIntentToWrite ),
|
|
_culRec ) COnDiskPropertyRecord();
|
|
|
|
#else
|
|
|
|
BYTE * pb = (BYTE *) _store.BorrowLargeBuffer( nLargePage,
|
|
TRUE,
|
|
fIntentToWrite );
|
|
|
|
_prec = (COnDiskPropertyRecord *) ( pb + ( widInRec * _culRec * 4 ) );
|
|
|
|
#endif
|
|
|
|
_nLargePage = nLargePage;
|
|
|
|
ciDebugOut(( DEB_PROPSTORE, "Wid %u (0x%x) --> wid %u of %u on %uK page %u. p = 0x%x\n",
|
|
wid, wid,
|
|
widInRec,
|
|
_cRecPerPage,
|
|
COMMON_PAGE_SIZE / 1024,
|
|
_nLargePage,
|
|
_prec ));
|
|
}
|
|
}
|
|
|
|
inline void CBorrowed::SetMaybeNew( WORKID wid )
|
|
{
|
|
Win4Assert( 0xFFFFFFFF == _nLargePage );
|
|
Win4Assert( 0 != wid );
|
|
|
|
WORKID widInRec = wid % _cRecPerPage;
|
|
ULONG nLargePage = wid / _cRecPerPage;
|
|
|
|
// The first valid wid is 1, so when we are writing the first
|
|
// record, we need to borrow a new large buffer.
|
|
if ( 1 == wid || 0 == widInRec )
|
|
{
|
|
|
|
#if 0 // compiler bug 3/27/02 in Windows Server 2003 tree 13.01.2035
|
|
|
|
_prec = new( (1 == wid) ? 1 : 0,
|
|
(BYTE *)_store.BorrowNewLargeBuffer( nLargePage ),
|
|
_culRec ) COnDiskPropertyRecord();
|
|
|
|
#else
|
|
|
|
BYTE * pb = (BYTE *) _store.BorrowNewLargeBuffer( nLargePage );
|
|
|
|
WORKID wir = (1 == wid) ? 1 : 0;
|
|
|
|
_prec = (COnDiskPropertyRecord *) ( pb + ( wir * _culRec * 4 ) );
|
|
|
|
#endif
|
|
|
|
#if CIDBG == 1
|
|
// verify that we are always getting zero filled pages. We rely on that
|
|
ULONG ulLen = COMMON_PAGE_SIZE/sizeof(ULONG);
|
|
// Start from the first record in page. Most times it is record 0, but
|
|
// it could be 1 on occassion.
|
|
if (1 == wid)
|
|
ulLen -= _culRec;
|
|
for (ULONG i = 0; i < ulLen ; i++)
|
|
Win4Assert(0 == ((ULONG *)_prec)[i]);
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
|
|
#if 0 // compiler bug 3/27/02 in Windows Server 2003 tree 13.01.2035
|
|
|
|
_prec = new( widInRec,
|
|
(BYTE *)_store.BorrowLargeBuffer( nLargePage ),
|
|
_culRec ) COnDiskPropertyRecord();
|
|
|
|
#else
|
|
|
|
BYTE * pb = (BYTE *) _store.BorrowLargeBuffer( nLargePage );
|
|
|
|
_prec = (COnDiskPropertyRecord *) ( pb + ( widInRec * _culRec * 4 ) );
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
_nLargePage = nLargePage;
|
|
|
|
ciDebugOut(( DEB_PROPSTORE, "Wid %u (0x%x) --> wid %u of %u on %uK page %u. p = 0x%x\n",
|
|
wid, wid,
|
|
widInRec,
|
|
_cRecPerPage,
|
|
COMMON_PAGE_SIZE / 1024,
|
|
_nLargePage,
|
|
_prec ));
|
|
}
|
|
|
|
inline void CBorrowed::Release()
|
|
{
|
|
if ( 0xFFFFFFFF != _nLargePage )
|
|
{
|
|
_store.ReturnLargeBuffer( _nLargePage );
|
|
_nLargePage = 0xFFFFFFFF;
|
|
_prec = 0;
|
|
}
|
|
}
|
|
|
|
inline COnDiskPropertyRecord * CBorrowed::Get()
|
|
{
|
|
return _prec;
|
|
}
|
|
|