WindowsXP-SP1/admin/snapin/corecopy/npd.h
2020-09-30 16:53:49 +02:00

417 lines
12 KiB
C++

#ifndef NPD_H
#define NPD_H
#ifndef COMPTR_H
#include <comptrs.h>
#endif
#ifndef COMDBG_H
#include <comdbg.h>
#endif
// {118B559C-6D8C-11d0-B503-00C04FD9080A}
extern const GUID IID_PersistData;
#if _MSC_VER < 1100
class PersistData : public IUnknown, public CComObjectRoot
#else
class __declspec(uuid("118B559C-6D8C-11d0-B503-00C04FD9080A")) PersistData :
public IUnknown, public CComObjectRoot
#endif
{
public:
BEGIN_COM_MAP(PersistData)
COM_INTERFACE_ENTRY(PersistData)
END_COM_MAP()
DECLARE_NOT_AGGREGATABLE(PersistData)
HRESULT Initialize(IStorage* pRoot, BOOL bSameAsLoad)
{
m_spRoot = pRoot;
ASSERT(m_spRoot != NULL);
if (m_spRoot == NULL)
return E_INVALIDARG;
m_bSameAsLoad = bSameAsLoad;
if (bSameAsLoad)
return Open();
return Create();
}
HRESULT Create(IStorage* pRoot)
{
m_spRoot = pRoot;
ASSERT(m_spRoot != NULL);
if (m_spRoot == NULL)
return E_INVALIDARG;
m_bSameAsLoad = TRUE;
return Create();
}
HRESULT Open(IStorage* pRoot)
{
m_spRoot = pRoot;
ASSERT(m_spRoot != NULL);
if (m_spRoot == NULL)
return E_INVALIDARG;
m_bSameAsLoad = TRUE;
return Open();
}
IStorage* GetRoot()
{
return m_spRoot;
}
BOOL SameAsLoad()
{
return m_bSameAsLoad;
}
void SetSameAsLoad(BOOL bSame = TRUE)
{
m_bSameAsLoad = bSame;
}
void ClearSameAsLoad()
{
m_bSameAsLoad = FALSE;
}
IStream* GetTreeStream()
{
return m_spTreeStream;
}
IStorage* GetNodeStorage()
{
return m_spNodeStorage;
}
protected:
PersistData() explicit
: m_bSameAsLoad(TRUE)
{
}
virtual ~PersistData()
{
}
private:
IStorageCIP m_spRoot;
BOOL m_bSameAsLoad;
IStreamCIP m_spTreeStream;
IStorageCIP m_spNodeStorage;
PersistData(const PersistData&) explicit;
// No copy.
PersistData& operator=(const PersistData&);
// No copy.
HRESULT Create()
{
ASSERT(m_bSameAsLoad || (!m_bSameAsLoad && m_spRoot != NULL));
if (!m_bSameAsLoad && m_spRoot == NULL)
return E_INVALIDARG;
// Create the stream for the tree
HRESULT hr = CreateDebugStream(m_spRoot, L"tree",
STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, L"\\tree",
&m_spTreeStream);
ASSERT(SUCCEEDED(hr) && m_spTreeStream != NULL);
if (FAILED(hr))
return hr;
// Create the storage for the nodes
hr = CreateDebugStorage(m_spRoot, L"nodes",
STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, L"\\nodes",
&m_spNodeStorage);
ASSERT(SUCCEEDED(hr) && m_spNodeStorage != NULL);
if (FAILED(hr))
return hr;
return S_OK;
}
HRESULT Open()
{
ASSERT(m_bSameAsLoad || (!m_bSameAsLoad && m_spRoot != NULL));
if (!m_bSameAsLoad && m_spRoot == NULL)
return E_INVALIDARG;
// Open the stream for the trees persistent data.
HRESULT hr = OpenDebugStream(m_spRoot, L"tree",
STGM_SHARE_EXCLUSIVE | STGM_READWRITE, L"\\tree", &m_spTreeStream);
ASSERT(SUCCEEDED(hr) && m_spTreeStream != NULL);
if (FAILED(hr))
return hr;
// Open the storage for the nodes
hr = OpenDebugStorage(m_spRoot, L"nodes",
STGM_SHARE_EXCLUSIVE | STGM_READWRITE, L"\\nodes",
&m_spNodeStorage);
ASSERT(SUCCEEDED(hr) && m_spNodeStorage != NULL);
if (FAILED(hr))
return hr;
return S_OK;
}
}; // class PersistData
DEFINE_CIP(PersistData);
#if 0
class PersistData
{
public: PersistData() explicit throw()
: m_bFailed(false)
{
}
private: PersistData(const PersistData& pd) explicit throw();
// Copying is currently not allowed.
public: void Initialize(IStorage& root)
// Saves the root storage and creates the standard streams and
// storages.
{
ASSERT(&root);
ASSERT(!static_cast<bool>(m_pRoot));
// An assertion here would indicate that this function has been
// previously called.
m_pRoot = &root;
CreateTreeStorage();
CreateTreeStream();
CreateStorageForStreams();
CreateStorageForStorages();
}
public: void Open(IStorage& root)
// Saves the root, and opens the standard streams and storages.
{
ASSERT(&root);
ASSERT(m_pRoot == NULL);
// An assertion here would indicate that this function has been
// previously called.
m_pRoot = &root;
OpenTreeStorage();
OpenTreeStream();
OpenStorageForStreams();
OpenStorageForStorages();
}
public: bool IsOpen()
{
return m_pRoot;
}
public: IStorage& GetRootStorage() const
{
ANT(m_pRoot, MMCEX(InvalidInstanceData));
return *m_pRoot;
}
public: IStorage& GetTreeStorage() const
{
ANT(m_pTreeStorage, MMCEX(InvalidInstanceData));
// This will assert if this object hasn't been initialized, or
// opened.
return *m_pTreeStorage;
}
public: IStream& GetTreeStream() const
{
ANT(m_pTreeStream, MMCEX(InvalidInstanceData));
// This will assert if this object hasn't been initialized, or
// opened.
return *m_pTreeStream;
}
public: IStorage& GetStorageForStreams() const
{
ANT(m_pStreams, MMCEX(InvalidInstanceData));
// This will assert if this object hasn't been initialized, or
// opened.
return *m_pStreams;
}
public: IStorage& GetStorageForStorages() const
{
ANT(m_pStorages, MMCEX(InvalidInstanceData));
// This will assert if this object hasn't been initialized, or
// opened.
return *m_pStorages;
}
public: bool Failed()
// Returns true if any of the persist operations failed without
// throwing an exception.
{
return m_bFailed;
}
public: void SetFailed(bool bFailed = true)
// Sets the failed flag in the event of a failure.
{
m_bFailed = bFailed;
}
public: void Delete(const wchar_t* name)
{
ANT(static_cast<bool>(m_pStorages) && static_cast<bool>(m_pStreams), MMCEX(InvalidInstanceData));
try {
Delete(*m_pStorages, name);
return;
}
catch(const MMCX& e)
{
}
Delete(*m_pStreams, name);
}
private: IStorageCIP m_pRoot;
// This is the most parent storage, which immediately contains all
// of the other required storages. Most especially the others
// contained in this class.
private: IStorageCIP m_pTreeStorage;
// The storage which contains a stream for each node. This stream is
// used by the console to persist the information unique to each
// particular type of node.
private: IStorageCIP m_pStreams;
// This storage contains a stream for each component, which implements
// IPersistSteam, or IPersistStreamInit.
private: IStorageCIP m_pStorages;
// This storage contains a storage for each component, which
// implements IPersistStorage.
private: IStreamCIP m_pTreeStream;
// The stream containing the tree reconstruction data.
private: bool m_bFailed;
// Set to true if any of the persistant operations failed without
// throwing an exception.
private: static const wchar_t* GetTreeStorageName()
// Returns the name of the tree's storage.
{
return L"treessorage";
}
private: static const wchar_t* GetTreeStreamName()
// Returns the name of the tree's storage.
{
return L"treesdream";
}
private: static const wchar_t* GetStorageNameForStreams()
// Returns the name of the Streams storage.
{
return L"smreams";
}
private: static const wchar_t* GetStorageNameForStorages()
// Returns the name of the storages storage.
{
return L"sborages";
}
private: void CreateStorage(const wchar_t* name, const wchar_t* instanceName, IStorage** ppStorage)
// First attempt to open the storage. If one is not found, the
// storage is then created.
{
ASSERT(name && *name && ppStorage);
try {
OpenStorage(name, instanceName, ppStorage);
return;
}
catch (const MMCX& e)
{
}
ANT(m_pRoot, MMCEX(InvalidInstanceData));
const HRESULT hr = CreateDebugStorage(m_pRoot, name,
STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, instanceName,
ppStorage);
ANT(SUCCEEDED(hr), COMEX(hr, UnableToCreateStorage));
ASSERT(*ppStorage);
}
private: void OpenStorage(const wchar_t* name, const wchar_t* instanceName, IStorage** ppStorage)
{
ASSERT(name && *name && ppStorage);
ANT(m_pRoot, MMCEX(InvalidInstanceData));
const HRESULT hr = OpenDebugStorage(m_pRoot, name,
STGM_SHARE_EXCLUSIVE | STGM_READWRITE, instanceName, ppStorage);
if (FAILED(hr) || !*ppStorage)
throw COMEX(hr, UnableToOpenStorage);
}
private: void CreateStream(const wchar_t* name, const wchar_t* instanceName, IStream** ppStream)
{
ASSERT(name && *name && ppStream);
ANT(m_pRoot, MMCEX(InvalidInstanceData));
const HRESULT hr = CreateDebugStream(m_pRoot, name,
STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, instanceName,
ppStream);
ANT(SUCCEEDED(hr), COMEX(hr, UnableToCreateStream));
ASSERT(*ppStream);
}
private: void OpenStream(const wchar_t* name, const wchar_t* instanceName, IStream** ppStream)
{
ASSERT(name && *name && ppStream);
ANT(m_pRoot, MMCEX(InvalidInstanceData));
const HRESULT hr = OpenDebugStream(m_pRoot, name,
STGM_SHARE_EXCLUSIVE | STGM_READWRITE, instanceName, ppStream);
ANT(SUCCEEDED(hr), COMEX(hr, UnableToOpenStream));
ASSERT(*ppStream);
}
private: void CreateTreeStorage()
// Creates the storage for the primary tree data. This function
// will assert if called more than once.
{
ASSERT(m_pTreeStorage == NULL);
CreateStorage(GetTreeStorageName(), L"PrimaryTree", &m_pTreeStorage);
}
private: void CreateTreeStream()
{
ASSERT(m_pTreeStream == NULL);
CreateStream(GetTreeStreamName(), L"PrimaryTree", &m_pTreeStream);
}
private: void CreateStorageForStreams()
// Creates the storage for the primary tree data. This function
// will assert if called more than once.
{
ASSERT(m_pStreams == NULL);
CreateStorage(GetStorageNameForStreams(), L"Nodes", &m_pStreams);
}
private: void CreateStorageForStorages()
// Creates the storage for the primary tree data. This function
// will assert if called more than once.
{
ASSERT(m_pStorages == NULL);
CreateStorage(GetStorageNameForStorages(), L"Nodes", &m_pStorages);
}
private: void OpenTreeStorage()
// Opens the storage for the primary tree data. This function
// will assert if called more than once.
{
ASSERT(m_pTreeStorage == NULL);
OpenStorage(GetTreeStorageName(), L"PrimaryTree", &m_pTreeStorage);
}
private: void OpenTreeStream()
// Opens the stream containing the primary tree data. This function
// asserts if called more than once.
{
ASSERT(m_pTreeStream == NULL);
OpenStream(GetTreeStreamName(), L"PrimaryTree", &m_pTreeStream);
}
private: void OpenStorageForStreams()
// Creates the storage for the primary tree data. This function
// will assert if called more than once.
{
ASSERT(m_pStreams == NULL);
OpenStorage(GetStorageNameForStreams(), L"Nodes", &m_pStreams);
}
private: void OpenStorageForStorages()
// Creates the storage for the primary tree data. This function
// will assert if called more than once.
{
ASSERT(m_pStorages == NULL);
OpenStorage(GetStorageNameForStorages(), L"Nodes", &m_pStorages);
}
private: void Delete(IStorage& storage, const wchar_t* name)
// Deletes the element with the specified name from the provided
// storage.
{
ASSERT(name && *name);
const HRESULT hr = storage.DestroyElement(name);
if (FAILED(hr))
throw COMEX(hr, UnableToDestroyElement);
}
}; // PersistData
#endif // 0
#endif // NPD_H