Reading Non-Ole File Property
-
We are trying to read Non-Ole File Properties (eg office 2007) using dsofile.dll. We can easily read properties of both Ole(doc file 97,2003) and non-ole(office 2007) using dsofile.dll(com dll). We did not use dsofile com dll because it has to be registered and take reference in the calling C# project. Actually we re-wrote our own dll using visual c++.net. The main interface for reading ole file property is IStoragePropertySet object. Here is the code snippets // If the file is an OLE Storage DocFile... if(StgIsStorageFile(m_bstrFileName)==S_OK) { IStorage *pStorage = NULL; IPropertySetStorage *pPropSetStg = NULL; HRESULT hr; // Open the document as an OLE compound document. hr = ::StgOpenStorage(wcFilename, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, NULL, 0, &pStorage); } else { //How to get non-ole file properties } As I showed the code snippets, there is no problem in getting ole-file properties. What we are struck in is getting non-ole file property. Here is the code snippets from the original source code of dsofile com dll.
// If the file is an OLE Storage DocFile...
_if (StgIsStorageFile(m_bstrFileName) == S_OK)
{
// Get the data from IStorage...
hr = StgOpenStorage(m_bstrFileName, NULL, dwOpenMode, NULL, 0, &m_pStorage);// If we failed to gain write access, try to just read access if caller allows // it. This function will open the OLE file in transacted read mode, which // covers cases where the file is in use or is on a read-only share. We can't // save after the open so we force the read-only flag on... if (((hr == STG\_E\_ACCESSDENIED) || (hr == STG\_E\_SHAREVIOLATION)) && (m\_dwFlags & dsoOptionOpenReadOnlyIfNoWriteAccess)) { m\_fReadOnly = TRUE; hr = StgOpenStorage(m\_bstrFileName, NULL, (STGM\_READ | STGM\_TRANSACTED | STGM\_SHARE\_DENY\_NONE), NULL, 0, &m\_pStorage); } // If we are lucky, we have a storage to read from, so ask OLE to open the // associated property set for the file and return the IPSS iface... if (SUCCEEDED(hr)) { hr = m\_pStorage->QueryInterface(IID\_IPropertySetStorage, (void\*\*)&m\_pPropSetStg); }_ } **else if ((m\_dwFlags & dsoOptionOnlyOpenOLEFiles) != dsoOptionOnlyOpenOLEFiles) { // If caller would like non-OLE property sets, we can try to provide them. There // are two types: (1) explicit metadata handlers registered by file type; or (2) // NTFS 5.0+ pro**
-
We are trying to read Non-Ole File Properties (eg office 2007) using dsofile.dll. We can easily read properties of both Ole(doc file 97,2003) and non-ole(office 2007) using dsofile.dll(com dll). We did not use dsofile com dll because it has to be registered and take reference in the calling C# project. Actually we re-wrote our own dll using visual c++.net. The main interface for reading ole file property is IStoragePropertySet object. Here is the code snippets // If the file is an OLE Storage DocFile... if(StgIsStorageFile(m_bstrFileName)==S_OK) { IStorage *pStorage = NULL; IPropertySetStorage *pPropSetStg = NULL; HRESULT hr; // Open the document as an OLE compound document. hr = ::StgOpenStorage(wcFilename, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, NULL, 0, &pStorage); } else { //How to get non-ole file properties } As I showed the code snippets, there is no problem in getting ole-file properties. What we are struck in is getting non-ole file property. Here is the code snippets from the original source code of dsofile com dll.
// If the file is an OLE Storage DocFile...
_if (StgIsStorageFile(m_bstrFileName) == S_OK)
{
// Get the data from IStorage...
hr = StgOpenStorage(m_bstrFileName, NULL, dwOpenMode, NULL, 0, &m_pStorage);// If we failed to gain write access, try to just read access if caller allows // it. This function will open the OLE file in transacted read mode, which // covers cases where the file is in use or is on a read-only share. We can't // save after the open so we force the read-only flag on... if (((hr == STG\_E\_ACCESSDENIED) || (hr == STG\_E\_SHAREVIOLATION)) && (m\_dwFlags & dsoOptionOpenReadOnlyIfNoWriteAccess)) { m\_fReadOnly = TRUE; hr = StgOpenStorage(m\_bstrFileName, NULL, (STGM\_READ | STGM\_TRANSACTED | STGM\_SHARE\_DENY\_NONE), NULL, 0, &m\_pStorage); } // If we are lucky, we have a storage to read from, so ask OLE to open the // associated property set for the file and return the IPSS iface... if (SUCCEEDED(hr)) { hr = m\_pStorage->QueryInterface(IID\_IPropertySetStorage, (void\*\*)&m\_pPropSetStg); }_ } **else if ((m\_dwFlags & dsoOptionOnlyOpenOLEFiles) != dsoOptionOnlyOpenOLEFiles) { // If caller would like non-OLE property sets, we can try to provide them. There // are two types: (1) explicit metadata handlers registered by file type; or (2) // NTFS 5.0+ pro**
for non- ole file types we have to get pointer of IID_IPropertySetStorage rather than istorage and the rest will be the same. only problme here is we cant update office 2007 file type as the file structure of office 2007 file type is bit different. if you fine any solution for accessing office 2007 do let me know. if(nFileType == non- ole) { hr =SetPropertySetStorage(pszFilePath); if (hr == S_OK ) { hr = SetSummaryInfoStorage(); if(FAILED(hr)) { printf(" Summaryinfo storage failed w/error %08lx", hr); return hr; } hr = SetCustomInfoStorage(); if(FAILED(hr)) { printf(" Custom storage failed w/error %08lx", hr); return hr; } } else { return hr; } } HRESULT CFileProperties::SetPropertySetStorage(const char * pszFilePath ) { HRESULT hr = S_OK; if(pszFilePath == NULL && m_pStorage != NULL) { hr = m_pStorage->QueryInterface(IID_IPropertySetStorage, (void **)&m_pPropSetStg); if(FAILED(hr)) { printf("QI for IPropertySetStorage failed w/error %08lx", hr); //Releasing IStorage m_pStorage->Release(); m_pStorage = NULL; return hr; } } else if(pszFilePath != NULL && m_pStorage == NULL) { // Translate filename to Unicode. WCHAR wcFilename[1024]; setlocale( LC_ALL, "" ); int i = mbstowcs(wcFilename, pszFilePath , strlen(pszFilePath )); setlocale( LC_ALL, "C" ); wcFilename[i] = 0; // Open the document as an OLE compound document. hr = StgOpenStorageEx( wcFilename, STGM_READ|STGM_SHARE_DENY_WRITE, STGFMT_ANY, 0, NULL, NULL, IID_IPropertySetStorage, reinterpret_cast<void**>(&m_pPropSetStg) ); if(FAILED(hr)) { if(hr == STG_E_FILENOTFOUND) printf("File not found."); else if(hr == STG_E_FILEALREADYEXISTS) printf("Not a compound file."); else pr
-
We are trying to read Non-Ole File Properties (eg office 2007) using dsofile.dll. We can easily read properties of both Ole(doc file 97,2003) and non-ole(office 2007) using dsofile.dll(com dll). We did not use dsofile com dll because it has to be registered and take reference in the calling C# project. Actually we re-wrote our own dll using visual c++.net. The main interface for reading ole file property is IStoragePropertySet object. Here is the code snippets // If the file is an OLE Storage DocFile... if(StgIsStorageFile(m_bstrFileName)==S_OK) { IStorage *pStorage = NULL; IPropertySetStorage *pPropSetStg = NULL; HRESULT hr; // Open the document as an OLE compound document. hr = ::StgOpenStorage(wcFilename, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, NULL, 0, &pStorage); } else { //How to get non-ole file properties } As I showed the code snippets, there is no problem in getting ole-file properties. What we are struck in is getting non-ole file property. Here is the code snippets from the original source code of dsofile com dll.
// If the file is an OLE Storage DocFile...
_if (StgIsStorageFile(m_bstrFileName) == S_OK)
{
// Get the data from IStorage...
hr = StgOpenStorage(m_bstrFileName, NULL, dwOpenMode, NULL, 0, &m_pStorage);// If we failed to gain write access, try to just read access if caller allows // it. This function will open the OLE file in transacted read mode, which // covers cases where the file is in use or is on a read-only share. We can't // save after the open so we force the read-only flag on... if (((hr == STG\_E\_ACCESSDENIED) || (hr == STG\_E\_SHAREVIOLATION)) && (m\_dwFlags & dsoOptionOpenReadOnlyIfNoWriteAccess)) { m\_fReadOnly = TRUE; hr = StgOpenStorage(m\_bstrFileName, NULL, (STGM\_READ | STGM\_TRANSACTED | STGM\_SHARE\_DENY\_NONE), NULL, 0, &m\_pStorage); } // If we are lucky, we have a storage to read from, so ask OLE to open the // associated property set for the file and return the IPSS iface... if (SUCCEEDED(hr)) { hr = m\_pStorage->QueryInterface(IID\_IPropertySetStorage, (void\*\*)&m\_pPropSetStg); }_ } **else if ((m\_dwFlags & dsoOptionOnlyOpenOLEFiles) != dsoOptionOnlyOpenOLEFiles) { // If caller would like non-OLE property sets, we can try to provide them. There // are two types: (1) explicit metadata handlers registered by file type; or (2) // NTFS 5.0+ pro**
For reading Non ole files(office 2007 files) if (NonOLEGetMetaHandler(m_bstrFileName, &clsidMetaHandler) == S_OK) { CoInitialize(NULL); // Create instance of the Metadata Handler object... hr = CoCreateInstance(clsidMetaHandler, NULL, CLSCTX_INPROC, IID_IPersistFile,(void**)&prtsf); if (SUCCEEDED(hr)) { // Ask it to load the file for parsing... hr = prtsf->Load(m_bstrFileName, (STGM_READWRITE | STGM_SHARE_EXCLUSIVE)); if (SUCCEEDED(hr)) { // If it succeeded, ask for the property set storage... hr = prtsf->QueryInterface(IID_IPropertySetStorage,(void**)&m_pPropSetStg); if (SUCCEEDED(hr)) { //ASSIGN_INTERFACE(m_pPrstFile, prtsf); // hr= m_pPropSetStg->Create(FMTID_SummaryInformation, // 0, // PROPSETFLAG_DEFAULT, // STGM_READWRITE | STGM_SHARE_EXCLUSIVE,&m_pSummaryInfoStg); hr = SetSummaryInfoStorage(); if(FAILED(hr)) { printf(" Summaryinfo storage failed w/error %08lx", hr); return hr; } hr = SetCustomInfoStorage(); if(FAILED(hr)) { printf(" Custom storage failed w/error %08lx", hr); return hr; } prtsf->Release(); } } HRESULT CFileProperties::NonOLEGetMetaHandler(LPCWSTR pwszFile, LPCLSID lpClsid) { HRESULT hret = REGDB_E_CLASSNOTREG; // Assume no handler HKEY hkeyExt, hkeyHandler = NULL; LPSTR pszExt; if ((pwszFile == NULL) || (*pwszFile == L'\0') || (lpClsid == NULL)) return E_INVALIDARG; // Get the extension for the file... pszExt = NonOLEConvertToMBCS(GetExtensionPart(pwszFile), CP_ACP); if (pszExt == NULL) return E_OUTOFMEMORY; // Now get the key that is associated with that extension... hkeyExt = GetHKCRKey("%s", pszExt); if (hkeyExt) { // Check for the handler under that ke