mirror of https://github.com/lianthony/NT4.0
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.
175 lines
5.9 KiB
175 lines
5.9 KiB
//+---------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1992 - 1994.
|
|
//
|
|
// File: extents.hxx
|
|
//
|
|
// Contents: Moniker extent definitions
|
|
//
|
|
// Classes: CExtentList
|
|
//
|
|
// Functions:
|
|
//
|
|
// History: 1-08-94 kevinro Created
|
|
// 17-Jul-95 BruceMa Add mutex to protect AddExtent (Cairo only)
|
|
// 10-10-95 stevebl moved mutex to CFileMoniker as part of
|
|
// adding general threadsafety to monikers
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Monikers need to be extendable. The on disk representation of a moniker
|
|
// has a reserved field that is treated as a bag of bits. This field,
|
|
// called achMonikerExtents (formerly read into m_pchMacAlias) contains
|
|
// a list of MONIKEREXTENT structures. The length of the achMonikerExtents
|
|
// cbMonikerExents.
|
|
//
|
|
// (Historical note: This bag of bits was once reserved for storing a
|
|
// Macintosh alias. The MAC and Win32 versions of the moniker code have
|
|
// agreed to share this field. There are several extents already in the
|
|
// works, such as the UNICODE extent, and the DFS extent. KevinRo 1/94)
|
|
//
|
|
// The format for the serialized data types is x86 (little endian).
|
|
//
|
|
// As seralized in the stream, the MONIKEREXENT looks like:
|
|
// -------------------------------------------------------------------------
|
|
// | | | < achMonikerExtents> |
|
|
// | <other data> | cbMonikerExtents | [MONIKEREXENT] [MONIKEREXENT]|
|
|
// -------------------------------------------------------------------------
|
|
// ^ ^
|
|
// -- cbMonikerExtent bytes --
|
|
//
|
|
// Each MONIKEREXENT has an internal structure that is represented below.
|
|
// Each has a size, and a key value, followed by a series of bytes.
|
|
//
|
|
// -------------------------------------------------------------------------
|
|
// | cbExtentBytes | usKeyValue | achExtentBytes[m_cbExentBytes] |
|
|
// -------------------------------------------------------------------------
|
|
//
|
|
// Therefore, the total length of an extent equals
|
|
// sizeof(cbExtentBytes) + sizeof(usKeyValue) + cbExtentBytes
|
|
//
|
|
// To read in the list, the following algorithm could be used
|
|
//
|
|
// Read cbMonikerExtents
|
|
//
|
|
// while( cbMonikerExtents != 0)
|
|
// {
|
|
// Read cbExtentBytes and usKeyValue to determine size of buffer
|
|
// Alloc sizeof(MONIKEREXENT) + cbExtentBytes - 1;
|
|
// Read achExtentBytes[cbExtentBytes]
|
|
//
|
|
// cbMonikerExtents -= sizeof(cbExtentBytes) +
|
|
// sizeof(usKeyValue) +
|
|
// cbExtentBytes
|
|
// }
|
|
//
|
|
// The alternative is to read the entire block at once, and parse through
|
|
// it. See CExentList for details.
|
|
//
|
|
// The philosophy here is to keep the moniker serialized format up and down
|
|
// level compatible by storing new information in extents. Not all extents
|
|
// will exist at all times, therefore we have a dynamic list of possible
|
|
// extents. If a particular implemenation doesn't understand an extent, it
|
|
// has the repsonsiblity of storing the extent as a bag of bits.
|
|
//
|
|
// For example, the MacAlias extent is only used when the Mac has seralized
|
|
// a moniker. The UNICODE extent is only used when the UNICODE path used to
|
|
// create the moniker could not be converted into an ANSI string without
|
|
// data loss.
|
|
//
|
|
|
|
#ifndef _EXTENTS_HXX_
|
|
#define _EXTENTS_HXX_
|
|
|
|
typedef struct _MONIKEREXTENT
|
|
{
|
|
ULONG cbExtentBytes; // Number of data bytes in extent
|
|
USHORT usKeyValue; // Key value for this extent
|
|
BYTE achExtentBytes[1]; // Data bytes for extent
|
|
|
|
} MONIKEREXTENT;
|
|
typedef MONIKEREXTENT * LPMONIKEREXTENT;
|
|
|
|
#define MONIKEREXTENT_HEADERSIZE (sizeof(ULONG) + sizeof(USHORT))
|
|
#define MonikerExtentSize(pExtent) (pExtent->cbExtentBytes + MONIKEREXTENT_HEADERSIZE)
|
|
|
|
|
|
//
|
|
// The following are the currently known values of extent keys.
|
|
//
|
|
// NEVER EVER CHANGE THE ORDER OR VALUES.
|
|
//
|
|
// You may add one to the end. Never allow them to conflict.
|
|
//
|
|
|
|
enum ExtentKeys
|
|
{
|
|
mnk_MAC = 1,
|
|
mnk_DFS = 2,
|
|
mnk_UNICODE = 3,
|
|
mnk_MacPathName = 4,
|
|
mnk_ShellLink = 5,
|
|
mnk_TrackingInformation = 6
|
|
};
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Class: CExtentList (private)
|
|
//
|
|
// Purpose:
|
|
//
|
|
// If we get a set of MONIKEREXTENTS, it would be much friendlier throughout
|
|
// the code to abstract the MONIKEREXENTS into a list, rather than having
|
|
// to munge our way through the buffer each time.
|
|
//
|
|
// CExentList acts as that abstraction. It has the advantages of reading
|
|
// and writing the extents as a single large blob.
|
|
//
|
|
//
|
|
// Interface: m_pchMonikerExtents --
|
|
// CoMemFree --
|
|
// FindExtent --
|
|
// AddExetent --
|
|
// PutExtent -- creates or overwrites extent.
|
|
// m_cbMonikerExents --
|
|
//
|
|
// History: 1-08-94 kevinro Created
|
|
//
|
|
// Notes:
|
|
//
|
|
// To day, I haven't found a need for a remove function for this list
|
|
//
|
|
// WARNINGS:
|
|
//
|
|
// An extent is not aligned when returned from the Find routine. The pointer
|
|
// returned must be UNALIGNED, or we will fault on RISC machines. Take
|
|
// appropriate precautions. Items returned from find are pointers into the
|
|
// list. Be carefule about modificiations.
|
|
//
|
|
// This list is not multi-thread safe. Be sure to serialize access to it.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
class CExtentList : public CPrivAlloc
|
|
{
|
|
public:
|
|
CExtentList();
|
|
~CExtentList();
|
|
|
|
MONIKEREXTENT UNALIGNED * FindExtent(USHORT usKeyValue);
|
|
HRESULT AddExtent(MONIKEREXTENT const * pExtent);
|
|
#ifdef _TRACKLINK_
|
|
HRESULT PutExtent(MONIKEREXTENT const * pExtent);
|
|
HRESULT DeleteExtent(USHORT usKeyValue);
|
|
#endif
|
|
HRESULT Save(IStream * pStm);
|
|
HRESULT Load(IStream * pStm,ULONG ulSize);
|
|
ULONG GetSize();
|
|
HRESULT Copy(CExtentList & newExtent);
|
|
|
|
private:
|
|
ULONG m_cbMonikerExtents;
|
|
BYTE * m_pchMonikerExtents;
|
|
};
|
|
#endif //_EXTENTS_HXX_
|