COleFileManager - OLE Compound File Class

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 file\n" + 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 file\n" + 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 "
  "file\n" + 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 file\n" + 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 stream\n 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



Comments

  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • The explosion in mobile devices and applications has generated a great deal of interest in APIs. Today's businesses are under increased pressure to make it easy to build apps, supply tools to help developers work more quickly, and deploy operational analytics so they can track users, developers, application performance, and more. Apigee Edge provides comprehensive API delivery tools and both operational and business-level analytics in an integrated platform. It is available as on-premise software or through …

  • A global data storage provider whose business is booming needed a best-in-class data center to serve as the backbone of its technical operations going forward—and it needed it delivered within a year.

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds