A
ashish
We are working on development of an IFilter component for Jpeg and tiff
files.First ever test resulted in following error. We are using
ifilttst.exe(which comes with windows 2003 resource kit.) to test the
filter. Source code snippet has been attached at the end of message. We are
stuck at this point for the last 5 days and still unable to resolve it.
380.396 : +TEST+INFO **** Input file : C:\Program Files\Windows Resource
Kits\Tools\wizard.jpg
380.396 : +TEST+INFO **** New configuration ****
380.396 : +TEST+INFO Section name : default
380.396 : +TEST+INFO grfFlags : 16
380.396 : +TEST+INFO cAttributes : 0
380.396 : +TEST+INFO aAttributes : NONE
380.396 : +TEST+INFO pdwFlags : 0
380.396 : +TEST+SEV1 Unable to bind filter to file C:\Program Files\Windows
Resource Kits\Tools\wizard.jpg Return code is 0x80004005
LOG REPORT---------------------------
Total Tests : 1
-------------------------------------
Tests Passed 0 0%
Tests Warned 0 0%
Tests Failed SEV3 0 0%
Tests Failed SEV2 0 0%
Tests Failed SEV1 1 100%
Tests Blocked 0 0%
Tests Aborted 0 0%
-------------------------------------
#pragma once
#include "resource.h" // main symbols
#include "Filter.h"
#include "filterr.h"
#include "ObjIdl.h"
#include "IPTCLoader.h"
#include "IPTCJPEGLoader.h"
#include "IPTCTIFFLoader.h"
// IPTCMetadataIFilter
[
coclass,
threading("free"),
vi_progid("IPTCIFilterLib.IPTCMetadataIFilter"),
progid("IPTCIFilterLib.IPTCMetadataIFilter.1"),
version(1.0),
uuid("CA7EF3B8-B13E-42A0-8F4A-96970E31ECA3"),
helpstring("IPTCMetadataIFilter Class")
]
class ATL_NO_VTABLE IPTCMetadataIFilter :
public IPersistFile, public IFilter {
public:
IPTCMetadataIFilter()
{
currLoader = NULL;
jpegLoader = new IPTCJPEGLoader();
tiffLoader = new IPTCTIFFLoader();
}
DECLARE_PROTECT_FINAL_CONSTRUCT()
HRESULT FinalConstruct()
{
return S_OK;
}
void FinalRelease()
{
}
// IFilter Methods
public:
STDMETHOD_(SCODE, Init)(ULONG grfFlags, ULONG cAttributes,
const FULLPROPSPEC * aAttributes,
ULONG * pFlags)
{
__try
{
jpegLoader->Initialise(grfFlags,cAttributes,aAttributes);
tiffLoader->Initialise(grfFlags,cAttributes,aAttributes);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
return E_FAIL;
}
return S_OK;
}
STDMETHOD_(SCODE, GetChunk)(STAT_CHUNK * pStat)
{
if (currLoader==NULL) return FILTER_E_END_OF_CHUNKS;
__try
{
currChunk = currLoader->GetNextChunk();
currChunk->GetChunk(pStat);
return S_OK;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
// Check for specific exceptions and corresponding error codes.
return S_FALSE;
}
}
STDMETHOD_(SCODE, GetText)(ULONG * pcwcBuffer, WCHAR * awcBuffer)
{
STAT_CHUNK ch;
this->currChunk->GetChunk(&ch);
if (ch.flags!=CHUNK_TEXT) return FILTER_E_NO_TEXT;
__try
{
IPTCTextChunk *textChunk = (IPTCTextChunk *)currChunk;
// GetText method returns either of S_OK/FILTER_S_LAST_TEXT
// or throws an exception
SCODE sc = textChunk->GetText(pcwcBuffer,awcBuffer);
return sc;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
// FilterNoMoreText is thrown if no more text is available
return FILTER_E_NO_MORE_TEXT;
}
}
STDMETHOD_(SCODE, GetValue)(PROPVARIANT ** ppPropValue)
{
// If value has been retrieved once
if (valueRetrieved) return FILTER_E_NO_MORE_VALUES;
STAT_CHUNK *ch = NULL;
this->currChunk->GetChunk(ch);
if (ch->flags!=CHUNK_VALUE) return FILTER_E_NO_VALUES;
__try
{
IPTCPropertyChunk *propChunk = (IPTCPropertyChunk *)currChunk;
bool *lastProperty = NULL;
**ppPropValue = propChunk->GetValue(lastProperty);
this->valueRetrieved = true;
if (lastProperty) return FILTER_E_NO_MORE_VALUES;
else return S_OK;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
// Check for specific exceptions and corresponding error codes.
return FILTER_E_NO_MORE_VALUES;
}
}
STDMETHOD_(SCODE, BindRegion)(FILTERREGION origPos,
REFIID riid,
void ** ppunk)
{
// This method is currently reserved for future use. Always return
E_NOTIMPL.
// Source: MSDN - IFilter::BindRegion - "Notes to Implementers")
return E_NOTIMPL;
}
// IPersistFile Methods
public:
STDMETHOD(IsDirty)()
{
// File would never change at all - always return S_FALSE
return S_FALSE;
}
STDMETHOD(Load)(LPCOLESTR pszFileName, DWORD dwMode)
{
// Setting current file to specified file name
this->pszFileName = (const wstring)pszFileName;
// Checking extension...
wstring ext;
size_t index;
index = this->pszFileName.find_last_of(L'.',this->pszFileName.length()-1);
if (index==-1) return E_FAIL;
ext = this->pszFileName.substr(index+1,this->pszFileName.length()-index);
// Check for JPEG file
if ((_wcsicmp(&ext[0],L"jfif")==0)||
(_wcsicmp(&ext[0],L"jpe")==0)||
(_wcsicmp(&ext[0],L"jpeg")==0)||
(_wcsicmp(&ext[0],L"jpg")==0))
{
this->IsJPEG = true;
currLoader = jpegLoader;
}
// Checking for TIFF files
else if ((_wcsicmp(&ext[0],L"tiff")==0)||
(_wcsicmp(&ext[0],L"tif")==0))
{
this->IsJPEG = false;
currLoader = tiffLoader;
}
// None of jpeg or tiff file format.
else return E_FAIL;
// Load the file using current loader instance...
if (SUCCEEDED(currLoader->Load(&this->pszFileName[0])))
{
valueRetrieved = false;
return S_OK;
}
else return E_FAIL;
}
STDMETHOD(Save)(LPCOLESTR pszFileName, BOOL fRemember)
{
return E_FAIL;
}
STDMETHOD(SaveCompleted)(LPCOLESTR pszFileName)
{
return E_FAIL;
}
STDMETHOD(GetCurFile)(LPOLESTR * ppszFileName)
{
if (pszFileName.empty())
return E_FAIL;
else *ppszFileName = W2OLE(&pszFileName[0]);
return S_OK;
}
// IPersist Methods - Must be implemented if implementing IPersistFile
public:
STDMETHOD(GetClassID)(CLSID * pClassID)
{
*pClassID = this->GetObjectCLSID();
return S_OK;
}
// IUnknown methods
/*
HRESULT STDMETHODCALLTYPE IUnknown::QueryInterface(REFIID iid, void
**ppvObject)
{
if ( 0 == ppvObject )
return E_INVALIDARG;
*ppvObject = 0;
if ( IID_IPersistFile == riid )
*ppvObject = (IUnknown *)(IPersist *)(IPersistFile *)this;
else if ( IID_IFilter == riid )
*ppvObject = (IUnknown *)(IFilter *)this;
else if ( IID_IPersist == riid )
*ppvObject = (IUnknown *)(IPersist *)(IPersistFile *)this;
else if ( IID_IPersistFile == riid )
*ppvObject = (IUnknown *)(IPersistFile *)this;
else if ( IID_IUnknown == riid )
*ppvObject = (IUnknown *)(IPersistFile *)this;
else
return E_NOINTERFACE;
AddRef();
return S_OK;
}
*/
private:
// File name specified by the caller to load metadata from
wstring pszFileName;
// Current FileType - if it's a JPEG file, should not return true, false if
TIFF
bool IsJPEG;
// Loader instance to be used to load metadata from files.
IPTCLoader *jpegLoader,*tiffLoader;
// The loader being used currently;
IPTCLoader *currLoader;
// Current chunk
IPTCChunk *currChunk;
// Last text chunk
bool lastTextChunk;
// Value retrieved or not.
bool valueRetrieved;
};
files.First ever test resulted in following error. We are using
ifilttst.exe(which comes with windows 2003 resource kit.) to test the
filter. Source code snippet has been attached at the end of message. We are
stuck at this point for the last 5 days and still unable to resolve it.
380.396 : +TEST+INFO **** Input file : C:\Program Files\Windows Resource
Kits\Tools\wizard.jpg
380.396 : +TEST+INFO **** New configuration ****
380.396 : +TEST+INFO Section name : default
380.396 : +TEST+INFO grfFlags : 16
380.396 : +TEST+INFO cAttributes : 0
380.396 : +TEST+INFO aAttributes : NONE
380.396 : +TEST+INFO pdwFlags : 0
380.396 : +TEST+SEV1 Unable to bind filter to file C:\Program Files\Windows
Resource Kits\Tools\wizard.jpg Return code is 0x80004005
LOG REPORT---------------------------
Total Tests : 1
-------------------------------------
Tests Passed 0 0%
Tests Warned 0 0%
Tests Failed SEV3 0 0%
Tests Failed SEV2 0 0%
Tests Failed SEV1 1 100%
Tests Blocked 0 0%
Tests Aborted 0 0%
-------------------------------------
#pragma once
#include "resource.h" // main symbols
#include "Filter.h"
#include "filterr.h"
#include "ObjIdl.h"
#include "IPTCLoader.h"
#include "IPTCJPEGLoader.h"
#include "IPTCTIFFLoader.h"
// IPTCMetadataIFilter
[
coclass,
threading("free"),
vi_progid("IPTCIFilterLib.IPTCMetadataIFilter"),
progid("IPTCIFilterLib.IPTCMetadataIFilter.1"),
version(1.0),
uuid("CA7EF3B8-B13E-42A0-8F4A-96970E31ECA3"),
helpstring("IPTCMetadataIFilter Class")
]
class ATL_NO_VTABLE IPTCMetadataIFilter :
public IPersistFile, public IFilter {
public:
IPTCMetadataIFilter()
{
currLoader = NULL;
jpegLoader = new IPTCJPEGLoader();
tiffLoader = new IPTCTIFFLoader();
}
DECLARE_PROTECT_FINAL_CONSTRUCT()
HRESULT FinalConstruct()
{
return S_OK;
}
void FinalRelease()
{
}
// IFilter Methods
public:
STDMETHOD_(SCODE, Init)(ULONG grfFlags, ULONG cAttributes,
const FULLPROPSPEC * aAttributes,
ULONG * pFlags)
{
__try
{
jpegLoader->Initialise(grfFlags,cAttributes,aAttributes);
tiffLoader->Initialise(grfFlags,cAttributes,aAttributes);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
return E_FAIL;
}
return S_OK;
}
STDMETHOD_(SCODE, GetChunk)(STAT_CHUNK * pStat)
{
if (currLoader==NULL) return FILTER_E_END_OF_CHUNKS;
__try
{
currChunk = currLoader->GetNextChunk();
currChunk->GetChunk(pStat);
return S_OK;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
// Check for specific exceptions and corresponding error codes.
return S_FALSE;
}
}
STDMETHOD_(SCODE, GetText)(ULONG * pcwcBuffer, WCHAR * awcBuffer)
{
STAT_CHUNK ch;
this->currChunk->GetChunk(&ch);
if (ch.flags!=CHUNK_TEXT) return FILTER_E_NO_TEXT;
__try
{
IPTCTextChunk *textChunk = (IPTCTextChunk *)currChunk;
// GetText method returns either of S_OK/FILTER_S_LAST_TEXT
// or throws an exception
SCODE sc = textChunk->GetText(pcwcBuffer,awcBuffer);
return sc;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
// FilterNoMoreText is thrown if no more text is available
return FILTER_E_NO_MORE_TEXT;
}
}
STDMETHOD_(SCODE, GetValue)(PROPVARIANT ** ppPropValue)
{
// If value has been retrieved once
if (valueRetrieved) return FILTER_E_NO_MORE_VALUES;
STAT_CHUNK *ch = NULL;
this->currChunk->GetChunk(ch);
if (ch->flags!=CHUNK_VALUE) return FILTER_E_NO_VALUES;
__try
{
IPTCPropertyChunk *propChunk = (IPTCPropertyChunk *)currChunk;
bool *lastProperty = NULL;
**ppPropValue = propChunk->GetValue(lastProperty);
this->valueRetrieved = true;
if (lastProperty) return FILTER_E_NO_MORE_VALUES;
else return S_OK;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
// Check for specific exceptions and corresponding error codes.
return FILTER_E_NO_MORE_VALUES;
}
}
STDMETHOD_(SCODE, BindRegion)(FILTERREGION origPos,
REFIID riid,
void ** ppunk)
{
// This method is currently reserved for future use. Always return
E_NOTIMPL.
// Source: MSDN - IFilter::BindRegion - "Notes to Implementers")
return E_NOTIMPL;
}
// IPersistFile Methods
public:
STDMETHOD(IsDirty)()
{
// File would never change at all - always return S_FALSE
return S_FALSE;
}
STDMETHOD(Load)(LPCOLESTR pszFileName, DWORD dwMode)
{
// Setting current file to specified file name
this->pszFileName = (const wstring)pszFileName;
// Checking extension...
wstring ext;
size_t index;
index = this->pszFileName.find_last_of(L'.',this->pszFileName.length()-1);
if (index==-1) return E_FAIL;
ext = this->pszFileName.substr(index+1,this->pszFileName.length()-index);
// Check for JPEG file
if ((_wcsicmp(&ext[0],L"jfif")==0)||
(_wcsicmp(&ext[0],L"jpe")==0)||
(_wcsicmp(&ext[0],L"jpeg")==0)||
(_wcsicmp(&ext[0],L"jpg")==0))
{
this->IsJPEG = true;
currLoader = jpegLoader;
}
// Checking for TIFF files
else if ((_wcsicmp(&ext[0],L"tiff")==0)||
(_wcsicmp(&ext[0],L"tif")==0))
{
this->IsJPEG = false;
currLoader = tiffLoader;
}
// None of jpeg or tiff file format.
else return E_FAIL;
// Load the file using current loader instance...
if (SUCCEEDED(currLoader->Load(&this->pszFileName[0])))
{
valueRetrieved = false;
return S_OK;
}
else return E_FAIL;
}
STDMETHOD(Save)(LPCOLESTR pszFileName, BOOL fRemember)
{
return E_FAIL;
}
STDMETHOD(SaveCompleted)(LPCOLESTR pszFileName)
{
return E_FAIL;
}
STDMETHOD(GetCurFile)(LPOLESTR * ppszFileName)
{
if (pszFileName.empty())
return E_FAIL;
else *ppszFileName = W2OLE(&pszFileName[0]);
return S_OK;
}
// IPersist Methods - Must be implemented if implementing IPersistFile
public:
STDMETHOD(GetClassID)(CLSID * pClassID)
{
*pClassID = this->GetObjectCLSID();
return S_OK;
}
// IUnknown methods
/*
HRESULT STDMETHODCALLTYPE IUnknown::QueryInterface(REFIID iid, void
**ppvObject)
{
if ( 0 == ppvObject )
return E_INVALIDARG;
*ppvObject = 0;
if ( IID_IPersistFile == riid )
*ppvObject = (IUnknown *)(IPersist *)(IPersistFile *)this;
else if ( IID_IFilter == riid )
*ppvObject = (IUnknown *)(IFilter *)this;
else if ( IID_IPersist == riid )
*ppvObject = (IUnknown *)(IPersist *)(IPersistFile *)this;
else if ( IID_IPersistFile == riid )
*ppvObject = (IUnknown *)(IPersistFile *)this;
else if ( IID_IUnknown == riid )
*ppvObject = (IUnknown *)(IPersistFile *)this;
else
return E_NOINTERFACE;
AddRef();
return S_OK;
}
*/
private:
// File name specified by the caller to load metadata from
wstring pszFileName;
// Current FileType - if it's a JPEG file, should not return true, false if
TIFF
bool IsJPEG;
// Loader instance to be used to load metadata from files.
IPTCLoader *jpegLoader,*tiffLoader;
// The loader being used currently;
IPTCLoader *currLoader;
// Current chunk
IPTCChunk *currChunk;
// Last text chunk
bool lastTextChunk;
// Value retrieved or not.
bool valueRetrieved;
};