Click here to Skip to main content
12,299,086 members (49,073 online)
Click here to Skip to main content

Stats

18.7K views
472 downloads
18 bookmarked
Posted

Hiding and Storing/caching of Application Specific data in MS Word 2003 documents

, 9 Oct 2008 CPOL
Proof of concept on how the application specific (small/large amount of) data can be stored in ms word document as well as how it can be made hidden from end user’s eye.
Common
Common
bin
Debug
Release
Common.dll
Common.pdb
obj
Debug
TempPE
Release
Common.dll
Common.pdb
TempPE
Properties
Common.suo
DocumentIDReader
DocumentIDReader
bin
Debug
Release
DocumentIDReader.exe
DocumentIDReader.pdb
DocumentIDReader.vshost.exe
DocumentIDReader.csproj.user
obj
Debug
TempPE
Release
DocumentIDReader.csproj.GenerateResource.Cache
DocumentIDReader.exe
DocumentIDReader.Form1.resources
DocumentIDReader.pdb
DocumentIDReader.Properties.Resources.resources
TempPE
Properties
DocumentIDReader.suo
FileStorage
FileStorage
FileStorage.def
FileStorage.vcproj.NECHCLDC01.atul.suyal.user
FileStorage.vcproj.NECHCLDC01.vinita.batra.user
FileStorage.vcproj.RAIREKI.mahendra.gupta.user
res
vssver2.scc
vssver2.scc
FileStorage.suo
SocketServer
SocketServer
bin
Release
Common.dll
Common.pdb
SocketServer.exe
SocketServer.pdb
SocketServer.vshost.exe
obj
Debug
SocketServer.exe
SocketServer.pdb
TempPE
Release
SocketServer.exe
SocketServer.pdb
TempPE
Properties
SocketServer.csproj.user
SocketServer.suo
WordAddIn1
WordAddIn1
bin
Debug
Common.dll
Common.pdb
WordAddIn1.dll
WordAddIn1.dll.manifest
WordAddIn1.pdb
obj
Debug
TempPE
WordAddIn1.csproj.GenerateResource.Cache
WordAddIn1.csproj.ResolveComReference.cache
WordAddIn1.dll
WordAddIn1.pdb
WordAddIn1.Properties.Resources.resources
Properties
WordAddIn1.csproj.user
WordAddIn1.suo
WordAddIn1Setup
Debug
Release
WordAddIn1Setup
// FileStorage.cpp : Defines the initialization routines for the DLL.
//

#include "stdafx.h"
#include "FileStorage.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

//
//TODO: If this DLL is dynamically linked against the MFC DLLs,
//		any functions exported from this DLL which call into
//		MFC must have the AFX_MANAGE_STATE macro added at the
//		very beginning of the function.
//
//		For example:
//
//		extern "C" BOOL PASCAL EXPORT ExportedFunction()
//		{
//			AFX_MANAGE_STATE(AfxGetStaticModuleState());
//			// normal function body here
//		}
//
//		It is very important that this macro appear in each
//		function, prior to any calls into MFC.  This means that
//		it must appear as the first statement within the 
//		function, even before any object variable declarations
//		as their constructors may generate calls into the MFC
//		DLL.
//
//		Please see MFC Technical Notes 33 and 58 for additional
//		details.
//


// CFileStorageApp

BEGIN_MESSAGE_MAP(CFileStorageApp, CWinApp)
END_MESSAGE_MAP()


// CFileStorageApp construction

CFileStorageApp::CFileStorageApp()
{
	// TODO: add construction code here,
	// Place all significant initialization in InitInstance
}


// The one and only CFileStorageApp object

CFileStorageApp theApp;


// CFileStorageApp initialization

BOOL CFileStorageApp::InitInstance()
{
	CWinApp::InitInstance();

	return TRUE;
}

BOOLEAN CFileStorageApp::AddDataToFile(WCHAR *pwszFileName,int typeOfData,WCHAR * data,BOOLEAN officeFile )
{
	//This function adds/embeds the DocumentID in office file.
	//The filename is obtained in pwszFileName argument.
	//The office file can be ms word or ms excel or ms powerpoint.
    //DocumentID would not be visible to the user when user opens the office file.
	//FILE *fp=_tfopen(_T("c:\\filelog.txt"),_T("a"));
	int errorcode=0;
	HRESULT hr=S_OK;
	if(officeFile==TRUE)
	{
		if(typeOfData==STRINGDATA_DOCUMENTID)
		{
			
			Sleep(100);//50
			 for(int i=0;i<MAX_RETRY;i++)
			{
				errorcode=0;
				 hr=S_FALSE;
			 hr=AddToStorage(pwszFileName,data,StreamName_DocumentID,&errorcode);
			 if(errorcode==Error_OpenFile||hr==S_OK)
			 {
				
				 if(hr==S_OK)
				 {
				     for(int retry=0;retry<20;retry++)
					 {
						 Sleep(200);
						 hr=AddToStorage(pwszFileName,data,StreamName_DocumentID,&errorcode);
					 }
					 hr=S_OK;
				 }
		 
				 break;
			  }
			 
			 Sleep(200);//50
			}

			if(hr==S_FALSE||hr == E_INVALIDARG)
			{
//				_fputts(_T("AddToStorage returns false  "),fp);
//				fclose(fp);
				return FALSE;
			}
			else
			{
//				_fputts(_T("AddToStorage returns true  "),fp);	
//				fclose(fp);
				return TRUE;
			}
		}
	}
	return TRUE;
}


HRESULT CFileStorageApp::AddToStorage(WCHAR *pwszFileName,WCHAR* pwszData,WCHAR *pwszStreamName,int* errorcode )
{
	//Ms word, excel and powerpoint files are compound files 
	//Therefore Compound fle implementation of structured storage is used.
	FILE *fp=_tfopen(_T("c:\\filelog.txt"),_T("a"));
	HRESULT		hr					= S_OK;
	IStorage*	pStorage			= NULL;
	IStorage*	pDataSpaceStorage	= NULL;
	IStream*	pStream	= NULL;
     *errorcode=0;
	 	CFile file;
	
	if ( pwszFileName == NULL )
	{
		hr = S_FALSE ;
		goto e_Exit;
	} 
	_fputts(_T("AddToStorage called  "),fp);
	//The StgOpenStorageEx function opens open an existing compound file object 
	//and get its root IStorage pointer
	
/*	
	hr = StgOpenStorageEx(	pwszFileName,							// Compound file name
							STGM_READWRITE | STGM_SHARE_EXCLUSIVE,	// file access
							STGFMT_STORAGE,							// specifies compound file
							0,
							NULL,
							0,
							IID_IStorage,							// return an IStorage reference
							(void **)&pStorage );					// receives IStorage reference
	if ( FAILED(hr) )
	{
		if(hr==STG_E_ACCESSDENIED)
		{
				_fputts(_T("access denied  "),fp);
		}
		else if((hr==STG_E_SHAREVIOLATION)||(hr==STG_E_LOCKVIOLATION))
		{
			_fputts(_T("STG_E_SHAREVIOLATION   "),fp);
		}
		else if(hr==STG_E_LOCKVIOLATION)
		{
		_fputts(_T("STG_E_LOCKVIOLATION   "),fp);
		}

		hr=S_FALSE ;
		_fputts(_T("StgOpenStorageEx failed  "),fp);
		goto e_Exit;
		
	}*/
  while(1)
	{
		
		BOOL retval=file.Open(pwszFileName,CFile::modeReadWrite|CFile::shareExclusive,NULL);
		
		      if(retval!=false)
			  {
				file.Flush();			
				  break;
			  }
		
	}
	file.Close();

	for (int nIndex = 0; nIndex < 100; nIndex++)
	{
		
			hr = StgOpenStorageEx(pwszFileName,							// Compound file name
							STGM_READWRITE | STGM_SHARE_EXCLUSIVE,	// file access
							STGFMT_STORAGE,							// specifies compound file
							0,
							NULL,
							0,
							IID_IStorage,							// return an IStorage reference
							(void **)&pStorage );					// receives IStorage reference
		if (FAILED(hr))
		{
			if ((hr == STG_E_SHAREVIOLATION)|| (hr==STG_E_LOCKVIOLATION))
			{
				Sleep(50);
			}
			else
			{
				break;
			}
		}
		else
			break;
	}
	if ( FAILED(hr) )
	{
		hr = S_FALSE ;
		*errorcode=Error_OpenFile;
		_fputts(_T("StgOpenStorageEx fail  "),fp);
		goto e_Exit;
	}
     _fputts(_T("StgOpenStorageEx sucess  "),fp);



	//Opens an existing storage object with the specified name in the specified access mode.
	//hr = pStorage->OpenStorage(	StorageName_DataStorage,
	//							NULL,
	//							STGM_READWRITE | STGM_SHARE_EXCLUSIVE,
	//							NULL,
	//							0,
	//							&pDataSpaceStorage );

 //  _fputts(_T("OpenStorage called   "),fp);
	//if(hr==STG_E_FILENOTFOUND)
	//{
		//Creates and opens a new storage object with the specified name in the specified access mode.
		hr = pStorage->CreateStorage(	StorageName_DataStorage,
										STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_FAILIFTHERE,
										0,
										0,
										&pDataSpaceStorage );
		
   _fputts(_T("CreateStorage called  "),fp);

		if ( FAILED(hr) )
		{
			
			if(hr==STG_E_FILEALREADYEXISTS)
				_fputts(_T("CreateStorage failed  due to STG_E_FILEALREADYEXISTS"),fp);
		if(hr==STG_E_ACCESSDENIED)
      _fputts(_T("CreateStorage failed  due to access denied"),fp);
		else if(hr==STG_E_INSUFFICIENTMEMORY)
		 _fputts(_T("CreateStorage failed  due toSTG_E_INSUFFICIENTMEMORY"),fp);
		else if (hr==E_PENDING)
		 _fputts(_T("CreateStorage failed  due to E_PENDING"),fp);
		else if(hr==STG_E_INVALIDFUNCTION)
			 _fputts(_T("CreateStorage failed  due to STG_E_INVALIDFUNCTION"),fp);
		else if(hr==STG_E_INVALIDPOINTER)
			 _fputts(_T("CreateStorage failed  due to STG_E_INVALIDPOINTER"),fp);
		else if(hr==STG_E_INVALIDFLAG)
			 _fputts(_T("CreateStorage failed  due to STG_E_INVALIDFLAG"),fp);
		else if (hr==STG_E_INVALIDNAME)
			 _fputts(_T("CreateStorage failed  due to STG_E_INVALIDNAME"),fp);
		else if(hr==STG_E_INVALIDPARAMETER)
			 _fputts(_T("CreateStorage failed  due to STG_E_INVALIDPARAMETER"),fp);
		else if(hr==STG_E_REVERTED)
			 _fputts(_T("CreateStorage failed  due to STG_E_REVERTED"),fp);
		else if(hr==STG_E_TOOMANYOPENFILES)
			 _fputts(_T("CreateStorage failed  due to STG_E_TOOMANYOPENFILES"),fp);
		else if(hr==STG_S_CONVERTED)
			 _fputts(_T("CreateStorage failed  due to  STG_S_CONVERTED"),fp);

		
		_fputts(_T("CreateStorage failed  "),fp);
		     hr=S_FALSE ;
			goto e_Exit;
	}

	//Creates a stream "DocumentID" in storage "DataStorage" in 
	//file specified by pwszFileName  
streamCreate:
	hr=CreateStream(pDataSpaceStorage,&pStream,pwszStreamName);
	//	_fputts(_T("CreateStream called   "),fp);
	if ( FAILED(hr) )
	{
			hr=S_FALSE    ;
			_fputts(_T("CreateStream failed  "),fp);
			goto e_Exit;
	}
	ULONG  ulDataSize= (int)(wcslen(pwszData)+1) * sizeof(WCHAR); 
	//Writes the documentid value in stream DocumentID.
	hr=WriteToStream(pStream,(void *)pwszData,ulDataSize);
	_fputts(_T("WriteToStream called  "),fp);
	if ( FAILED(hr) )
	{
		hr=S_FALSE;
		_fputts(_T("WriteToStream failed  "),fp);
		goto e_Exit;
	}
	//saves the changes made to the file.
	hr = pStorage->Commit(STGC_DEFAULT);
	_fputts(_T("Commit called  "),fp);
	if ( FAILED(hr) )
	{
		hr=S_FALSE    ;
		_fputts(_T("Commit failed  "),fp);
		goto e_Exit;
	}

e_Exit:
	//performs the cleanup.
	fclose(fp);
	if ( pDataSpaceStorage != NULL )
	{
		pDataSpaceStorage->Release();
		pDataSpaceStorage = NULL;
	}
	if ( pStorage != NULL )
	{
		pStorage->Release();
		pStorage = NULL;
	}
	if ( pStream!= NULL )
	{
		pStream->Release();
		pStream = NULL;
	}
	return hr;
}

HRESULT CFileStorageApp::CreateStream(IStorage* pDataSpaceStorage,	IStream**	pStream, WCHAR *pwszStreamName)
{
	FILE *fp=_tfopen(_T("c:\\filelog.txt"),_T("a"));
	HRESULT	hr = S_FALSE;
	if(pDataSpaceStorage==NULL)
	{
		//hr=S_FALSE    ;
		return hr;
	}
	//hr=pDataSpaceStorage->OpenStream(pwszStreamName,NULL,
	//	     STGM_READWRITE | STGM_SHARE_EXCLUSIVE ,/*|STGM_FAILIFTHERE,*/
	//										0,
	//										pStream );

	//	 _fputts(_T("OpenStream called   "),fp);
	//if(hr==STG_E_FILENOTFOUND)
	//{
	//	
		hr = pDataSpaceStorage->CreateStream(pwszStreamName,
											STGM_READWRITE | STGM_SHARE_EXCLUSIVE |STGM_FAILIFTHERE,
											0,
											0,
											pStream );
		
      _fputts(_T("CreateStream called  "),fp);

		if ( FAILED(hr) )
		{
			hr=S_FALSE;
    if(hr==STG_E_FILEALREADYEXISTS)
      _fputts(_T("createsteram failed  due to STG_E_FILEALREADYEXISTS"),fp);
	else if(hr==STG_E_ACCESSDENIED)
      _fputts(_T("createsteram failed  due to access denied"),fp);
		else if(hr==STG_E_INSUFFICIENTMEMORY)
		 _fputts(_T("createsteram failed  due toSTG_E_INSUFFICIENTMEMORY"),fp);
		else if (hr==E_PENDING)
		 _fputts(_T("createsteram failed  due to E_PENDING"),fp);
		else if(hr==STG_E_INVALIDFUNCTION)
			 _fputts(_T("createsteram failed  due to STG_E_INVALIDFUNCTION"),fp);
		else if(hr==STG_E_INVALIDPOINTER)
			 _fputts(_T("createsteram failed  due to STG_E_INVALIDPOINTER"),fp);
		else if(hr==STG_E_INVALIDFLAG)
			 _fputts(_T("createsteram failed  due to STG_E_INVALIDFLAG"),fp);
		else if (hr==STG_E_INVALIDNAME)
			 _fputts(_T("createsteram failed  due to STG_E_INVALIDNAME"),fp);
		else if(hr==STG_E_INVALIDPARAMETER)
			 _fputts(_T("createsteram failed  due to STG_E_INVALIDPARAMETER"),fp);
		else if(hr==STG_E_REVERTED)
			 _fputts(_T("createsteram failed  due to STG_E_REVERTED"),fp);
		else if(hr==STG_E_TOOMANYOPENFILES)
			 _fputts(_T("createsteram failed  due to STG_E_TOOMANYOPENFILES"),fp);
		/*else if(hr==STG_S_CONVERTED)
			 _fputts(_T("OpenStorage failed  due to  STG_S_CONVERTED"),fp);*/

		
	}
	 //if(hr!=S_OK)
		 
	 fclose(fp);
	 return hr;
	
}


HRESULT CFileStorageApp::WriteToStream(IStream* pStream, void* pData, int ulDataSize)
{
	
	HRESULT hr = S_OK;
	ULONG pcbWritten=0;
	
	if ( pStream == NULL || pData == NULL || ulDataSize <= 0 )
	{
		hr=S_FALSE    ;
		goto e_Exit;
	}

	hr=pStream->Write( pData,ulDataSize,&pcbWritten);
	if (FAILED(hr) || (ulDataSize != pcbWritten))
	{
		    hr=S_FALSE    ;
			goto e_Exit;
	}
			
e_Exit:
	
	return hr;
}



BOOLEAN CFileStorageApp::ReadDataFromFile(WCHAR *pwszFileName,int typeOfData,WCHAR* data,ULONG ulDataSize,BOOLEAN officeFile )
{
	//This function reads the DocumentID from office file.
	//The filename is obtained in pwszFileName argument.
	HRESULT hr=S_OK;
	if(officeFile==TRUE)
	{
		if(typeOfData==STRINGDATA_DOCUMENTID)
		{
			hr=GetFromStorage(pwszFileName,(void *)data,ulDataSize,StreamName_DocumentID);
			if(hr==S_FALSE||hr == E_INVALIDARG)
				return FALSE;
			else
				return TRUE;
		}
	}
	return TRUE;
}

HRESULT CFileStorageApp::GetFromStorage(WCHAR *pwszFileName,void * pBuff,ULONG ulDataSize,WCHAR *pwszStreamName )
{
	HRESULT		hr					= S_OK;
	int			nDataSize			= 0;
	ULONG		ulReadSize			= 0;
	IStorage*	pStorage			= NULL;
	IStorage*	pDataSpaceStorage	= NULL;
	IStream*	pStream				= NULL;

	if ( pwszFileName == NULL || pwszStreamName == NULL || ulDataSize<=0||pBuff == NULL)
	{
		hr = E_INVALIDARG;
		goto e_Exit;
	}
	for (int nIndex = 0; nIndex < MAX_RETRY; nIndex++)
	{
		
			hr = StgOpenStorageEx(	pwszFileName,							// Compound file name
								STGM_DIRECT_SWMR|STGM_READ | STGM_SHARE_DENY_NONE,
								//STGM_READ | STGM_SHARE_DENY_WRITE,		// file access
								STGFMT_STORAGE,							// specifies compound file
								0,
								NULL,
								0,
								IID_IStorage,							// return an IStorage reference
								(void **)&pStorage );					// receives IStorage reference
		if (FAILED(hr))
		{
			if (hr == STG_E_SHAREVIOLATION)
			{
				Sleep(1);
			}
			else
			{
				break;
			}
		}
		else
			break;
	}
	if ( FAILED(hr) )
	{
		hr = S_FALSE ;
		goto e_Exit;
	}

    
	hr = pStorage->OpenStorage(	StorageName_DataStorage,
								NULL,
								STGM_READ | STGM_SHARE_EXCLUSIVE,
								NULL,
								0,
								&pDataSpaceStorage );
	if ( FAILED(hr) )
	{
		hr = S_FALSE ;
		goto e_Exit;
	}
	hr = pDataSpaceStorage->OpenStream(	pwszStreamName,
										NULL,
										STGM_READ | STGM_SHARE_EXCLUSIVE,
										0,
										&pStream );
	if ( FAILED(hr) )
	{
		hr = S_FALSE ;
		goto e_Exit;
	}
	//Reads the documentid from DocumentID stream
	hr=ReadFromStream(pStream,pBuff,ulDataSize);
	TCHAR *str=(TCHAR*)pBuff;

	if ( FAILED(hr) )
	{
		hr = S_FALSE ;
		goto e_Exit;
	}
	e_Exit:

	if ( pStream != NULL )
	{
		pStream->Release();
		pStream = NULL;
	}
	if ( pDataSpaceStorage != NULL )
	{
		pDataSpaceStorage->Release();
		pDataSpaceStorage = NULL;
	}
	if ( pStorage != NULL )
	{
		pStorage->Release();
		pStorage = NULL;
	}
	return hr;
}



HRESULT CFileStorageApp::ReadFromStream(IStream *pStream,void * pBuff,ULONG ulDataSize)
{

	HRESULT hr = S_OK;
	ULONG ulReadSize=0;
	if ( pStream == NULL || pBuff == NULL || ulDataSize <= 0 )
	{
		hr = E_INVALIDARG;
		
		goto e_Exit;
	}
	hr = pStream->Read(pBuff, ulDataSize, &ulReadSize );

	if (FAILED(hr) || (ulReadSize == 0) )
	{
		
			hr = S_FALSE ;
			goto e_Exit;
	}
	e_Exit:
		return hr;
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

No Biography provided

You may also be interested in...

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.160525.2 | Last Updated 10 Oct 2008
Article Copyright 2008 by batra.vinita@gmail.com
Everything else Copyright © CodeProject, 1999-2016
Layout: fixed | fluid