// 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;
}