COleFileManager – OLE Compound File Class

CodeGuru content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

If you have ever tried to implement structured storage in a MFC application you quickly
realize that its not a trival task. Opening, closing, creating and removing storage
objects and streams can get very confusing very fast. The COleStreamManager wraps these
complicated procedures into a tidy class.

The interface’s supplied to use this class is as follow’s (examples to use them are below)

User functions



BOOL NewProject(CString csPath, BOOL bEncrypt);
void CloseProject();
BOOL IsRootSet();

Stream functions



BOOL AddStream( LPSTORAGE lpStorage, CString csName,
void* pData, UINT uLength );

BOOL AddStream( LPSTORAGE lpStorage, CString csName,
CString csPath );

BOOL RemoveStream( LPSTORAGE lpStorage, CString csName );

BOOL ReloadStream( LPSTORAGE lpStorage, CString csName,
CString csPath );

COleStreamFile* GetHeadStream(LPSTORAGE lpStorage );

COleStreamFile* GetNextStream();

inline CString GetSavePath() { return m_csSavePath; };

inline int GetRootCount() { return m_nStorageCount; };

NOTES:



  1. This class was written to work with only one level of storage. Another words..a storage object cannot
    contain other storage objects. At the time of development that functionality was not needed
    and thus left out. Although to add nested storages to this class would be a trival task…I leave it up to you!

  2. This class DOES support multiple streams inside a storage object. Also, at the time of development there was
    no need to be able to enumerate through multiple streams. Thus, the class only supports the retrieval of the first
    stream of every storage object. I’m currently adding the ability to access all the streams and will post when completed.
    You will notice that the function that will support this will be GetNextStream() which returns a pointer to the stream or
    NULL if your past the last stream.

  3. The following header files must be included in your project. I suggest to put them in the stdafx.h file.
    #include “afxole.h”
    #include “afxconv.h”

  4. The COleFileManager class DOES (if specified) implement a simple encryption algorithm which simply makes end users (who may
    possibly have the means of viewing compound files) unable to view the streams contents. The algorithm encrypts
    and decrypts with the same call. If you use encryption in the COleFileStream class you must implement the decryption
    outside the class (or re-write it so it is handled by the class itself) using the same algorithm. The algorithm can
    be found in the function Encrypt(BYTE* pData, int nDataSize)

I hope this class will help take some of the headache out of working with compound files as it has for me. If you
increase the COleFileStreams’s functionality please send me copy…I’d love to see it and use it.

Examples

The following examples use the functions listed above to create, add and remove files to a compound file:


// cspath = where the file will be created,
// FALSE = means no encryption
if( !m_OleFileManager.NewProject( csPath, FALSE ))
return FALSE;

// Create the storage for this file where csStorageName is
// the name of the storage item
// it returns a pointer to the current storage item or NULL
LPSTORAGE lpStorage =
m_OleFileManager.CreateStorage(csStorageName);

if( lpStorage == NULL )
{
AfxMessageBox(“Storage was unable to be created for ”
“the filen” + m_csCurrentFileName );

return FALSE;
}

// Add a FILE to the storage we just got back!
// “Contents” = the name of the stream inside the storage
// csPath = the location of a file (anyfile)
if( !m_OleFileManager.AddStream(lpStorage, “Contents”, csPath ))
{
AfxMessageBox(“A Stream was unable to be created for ”
“the filen” + m_csCurrentFileName );

return FALSE;
}

// Add a BUFFER to the storage we just got back!
// “Contents” = the name of the stream inside the storage
// pData = a pointer to a buffer in memory (void*)
// uLength = the size of the pData buffer
if( !m_OleFileManager.AddStream( lpStorage, “Contents”, pData, uSize ))
{
AfxMessageBox(“A Stream was unable to be created for the ”
“filen” + m_csCurrentFileName );

return FALSE;
}

// Re-add this file to this storage object
// Effectively this removes the stream and then adds it again
// I use this with conjuction with the CHTMLView MFC class –
// when a user refreshes in the IE browser, I reload the file
// into the stream incase the HTML file has been edited!

// Check for NULL return!!
LPSTORAGE lpStorage = m_OleFileManager.GetStorage(csStorageName);
if( lpStorage )
{
if( !m_OleFileManager.ReloadStream( lpStorage,
“Contents”, csPath ))
{
AfxMessageBox(“A Stream was unable to be re-added for ”
“the filen” + csPath );

return FALSE;
}
}

// This function returns the first stream from that storage

// Check for NULL return!!
LPSTORAGE lpStorage =
m_OleFileManager.GetStorage(csStorageName);

if( lpStorage )
{
COleStreamFile* pOleFile =
m_OleFileManager.GetHeadStream(lpStorage);

if( !pOleFile )
{
AfxMessageBox(“Unable to open the head stream from ”
“storage: ” + csStorageName);

return;
}

// WORKING ON THIS NOW!! BUT IT DOESN”T WORK YET
while( pOleFile )
{
pOleFile = m_OleFileManager.GetNextStream(lpStorage);
}
}

// This function removes a stream from a storage object
// Check for NULL return!!
LPSTORAGE lpStorage =
m_OleFileManager.GetStorage(csStorageName);

if( lpStorage )
{
if( !m_OleFileManager.RemoveStream( lpStorage, “Contents” ))
{
AfxMessageBox(“Unable to remove the streamn Contents” );
return FALSE;
}
}

// The rest of the following functions are pretty straight
// forward
if( !m_OleFileManager.FindStorage(csStorageName) )

// this removes all streams inside this storage!!
if( !RemoveStorage(csStorageName) )

Downloads

Download source – 4 KB

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read