| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_shell.hxx" |
| |
| //-------------------------------------------------------------------------- |
| // File: ooofilt.cxx |
| // |
| // Contents: Filter Implementation for OpenOffice.Org Document using |
| // Indexing Service |
| // |
| // Summary: The OpenOffice.org filter reads OpenOffice.org files (with the |
| // extension .sxw .sxi, etc) and extract their content, author, |
| // keywords,subject,comments and title to be filtered. |
| // |
| // Platform: Windows 2000, Windows XP |
| // |
| //-------------------------------------------------------------------------- |
| #include "internal/contentreader.hxx" |
| #include "internal/metainforeader.hxx" |
| //#include "internal/utilities.hxx" |
| #include "internal/registry.hxx" |
| #include "internal/fileextensions.hxx" |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Include file Purpose |
| // |
| // windows.h Win32 declarations |
| // string.h string wstring declarations |
| // filter.h IFilter interface declarations |
| // filterr.h FACILITY_ITF error definitions for IFilter |
| // ntquery.h Indexing Service declarations |
| // assert.h assertion function. |
| // ooofilt.hxx OpenOffice.org filter declarations |
| // propspec.hxx PROPSPEC |
| // |
| //-------------------------------------------------------------------------- |
| |
| #if defined _MSC_VER |
| #pragma warning(push, 1) |
| #endif |
| #include <windows.h> |
| #if defined _MSC_VER |
| #pragma warning(pop) |
| #endif |
| #include <string.h> |
| #include <filter.h> |
| #include <filterr.h> |
| #include <ntquery.h> |
| #include "assert.h" |
| #include "ooofilt.hxx" |
| #include <objidl.h> |
| #include <stdio.h> |
| #include "propspec.hxx" |
| #ifdef __MINGW32__ |
| #include <algorithm> |
| using ::std::min; |
| #endif |
| |
| #include "internal/stream_helper.hxx" |
| |
| //C------------------------------------------------------------------------- |
| // |
| // Class: COooFilter |
| // |
| // Summary: Implements OpenOffice.org filter class |
| // |
| //-------------------------------------------------------------------------- |
| //M------------------------------------------------------------------------- |
| // |
| // Method: COooFilter::COooFilter |
| // |
| // Summary: Class constructor |
| // |
| // Arguments: void |
| // |
| // Purpose: Manages global instance count |
| // |
| //-------------------------------------------------------------------------- |
| COooFilter::COooFilter() : |
| m_lRefs(1), |
| m_pContentReader(NULL), |
| m_pMetaInfoReader(NULL), |
| m_eState(FilteringContent), |
| m_ulUnicodeBufferLen(0), |
| m_ulUnicodeCharsRead(0), |
| m_ulPropertyNum(0), |
| m_ulCurrentPropertyNum(0), |
| m_ulChunkID(1), |
| m_fContents(FALSE), |
| m_fEof(FALSE), |
| m_ChunkPosition(0), |
| m_cAttributes(0), |
| m_pAttributes(0), |
| m_pStream(NULL) |
| |
| { |
| InterlockedIncrement( &g_lInstances ); |
| } |
| //M------------------------------------------------------------------------- |
| // |
| // Method: COooFilter::~COooFilter |
| // |
| // Summary: Class destructor |
| // |
| // Arguments: void |
| // |
| // Purpose: Manages global instance count and file handle |
| // |
| //-------------------------------------------------------------------------- |
| COooFilter::~COooFilter() |
| { |
| delete [] m_pAttributes; |
| |
| if (m_pContentReader) |
| delete m_pContentReader; |
| if (m_pMetaInfoReader) |
| delete m_pMetaInfoReader; |
| |
| InterlockedDecrement( &g_lInstances ); |
| } |
| |
| //M------------------------------------------------------------------------- |
| // |
| // Method: COooFilter::QueryInterface (IUnknown::QueryInterface) |
| // |
| // Summary: Queries for requested interface |
| // |
| // Arguments: riid |
| // [in] Reference IID of requested interface |
| // ppvObject |
| // [out] Address that receives requested interface pointer |
| // |
| // Returns: S_OK |
| // Interface is supported |
| // E_NOINTERFACE |
| // Interface is not supported |
| // |
| //-------------------------------------------------------------------------- |
| SCODE STDMETHODCALLTYPE COooFilter::QueryInterface( |
| REFIID riid, |
| void ** ppvObject) |
| { |
| IUnknown *pUnkTemp = 0; |
| if ( IID_IFilter == riid ) |
| pUnkTemp = (IUnknown *)(IFilter *)this; |
| else if ( IID_IPersistFile == riid ) |
| pUnkTemp = (IUnknown *)(IPersistFile *)this; |
| else if ( IID_IPersist == riid ) |
| pUnkTemp = (IUnknown *)(IPersist *)(IPersistFile *)this; |
| else if (IID_IPersistStream == riid) |
| pUnkTemp = (IUnknown *)(IPersistStream *)this; |
| else if ( IID_IUnknown == riid ) |
| pUnkTemp = (IUnknown *)(IPersist *)(IPersistFile *)this; |
| else |
| { |
| *ppvObject = NULL; |
| return E_NOINTERFACE; |
| } |
| *ppvObject = (void *)pUnkTemp; |
| pUnkTemp->AddRef(); |
| return S_OK; |
| } |
| //M------------------------------------------------------------------------- |
| // |
| // Method: COooFilter::AddRef (IUnknown::AddRef) |
| // |
| // Summary: Increments interface refcount |
| // |
| // Arguments: void |
| // |
| // Returns: Value of incremented interface refcount |
| // |
| //-------------------------------------------------------------------------- |
| ULONG STDMETHODCALLTYPE COooFilter::AddRef() |
| { |
| return InterlockedIncrement( &m_lRefs ); |
| } |
| //M------------------------------------------------------------------------- |
| // |
| // Method: COooFilter::Release (IUnknown::Release) |
| // |
| // Summary: Decrements interface refcount, deleting if unreferenced |
| // |
| // Arguments: void |
| // |
| // Returns: Value of decremented interface refcount |
| // |
| //-------------------------------------------------------------------------- |
| ULONG STDMETHODCALLTYPE COooFilter::Release() |
| { |
| ULONG ulTmp = InterlockedDecrement( &m_lRefs ); |
| |
| if ( 0 == ulTmp ) |
| delete this; |
| return ulTmp; |
| } |
| //M------------------------------------------------------------------------- |
| // |
| // Method: COooFilter::Init (IFilter::Init) |
| // |
| // Summary: Initializes OpenOffice.org filter instance |
| // |
| // Arguments: grfFlags |
| // [in] Flags for filter behavior |
| // cAttributes |
| // [in] Number attributes in array aAttributes |
| // aAttributes |
| // [in] Array of requested attribute strings |
| // pFlags |
| // [out] Pointer to return flags for additional properties |
| // |
| // Returns: S_OK |
| // Initialization succeeded |
| // E_FAIL |
| // File not previously loaded |
| // E_INVALIDARG |
| // Count and contents of attributes do not agree |
| // FILTER_E_ACCESS |
| // Unable to access file to be filtered |
| // FILTER_E_PASSWORD |
| // (not implemented) |
| // |
| //-------------------------------------------------------------------------- |
| const int COUNT_ATTRIBUTES = 5; |
| |
| SCODE STDMETHODCALLTYPE COooFilter::Init( |
| ULONG grfFlags, |
| ULONG cAttributes, |
| FULLPROPSPEC const * aAttributes, |
| ULONG * pFlags) |
| { |
| // Enumerate OLE properties, since any NTFS file can have them |
| *pFlags = IFILTER_FLAGS_OLE_PROPERTIES; |
| try |
| { |
| m_fContents = FALSE; |
| m_ulPropertyNum = 0; |
| m_ulCurrentPropertyNum = 0; |
| if ( m_cAttributes > 0 ) |
| { |
| delete[] m_pAttributes; |
| m_pAttributes = 0; |
| m_cAttributes = 0; |
| } |
| if( 0 < cAttributes ) |
| { |
| // Filter properties specified in aAttributes |
| if ( 0 == aAttributes ) |
| return E_INVALIDARG; |
| m_pAttributes = new CFullPropSpec[cAttributes]; |
| m_cAttributes = cAttributes; |
| // Is caller want to filter contents? |
| CFullPropSpec *pAttrib = (CFullPropSpec *) aAttributes; |
| ULONG ulNumAttr; |
| for ( ulNumAttr = 0 ; ulNumAttr < cAttributes; ulNumAttr++ ) |
| { |
| if ( pAttrib[ulNumAttr].IsPropertyPropid() && |
| pAttrib[ulNumAttr].GetPropertyPropid() == PID_STG_CONTENTS && |
| pAttrib[ulNumAttr].GetPropSet() == guidStorage ) |
| { |
| m_fContents = TRUE; |
| } |
| // save the requested properties. |
| m_pAttributes[ulNumAttr] = pAttrib[ulNumAttr]; |
| } |
| } |
| else if ( grfFlags & IFILTER_INIT_APPLY_INDEX_ATTRIBUTES ) |
| { |
| // Filter contents and all pseudo-properties |
| m_fContents = TRUE; |
| |
| m_pAttributes = new CFullPropSpec[COUNT_ATTRIBUTES]; |
| m_cAttributes = COUNT_ATTRIBUTES; |
| m_pAttributes[0].SetPropSet( FMTID_SummaryInformation ); |
| m_pAttributes[0].SetProperty( PIDSI_AUTHOR ); |
| m_pAttributes[1].SetPropSet( FMTID_SummaryInformation ); |
| m_pAttributes[1].SetProperty( PIDSI_TITLE ); |
| m_pAttributes[2].SetPropSet( FMTID_SummaryInformation ); |
| m_pAttributes[2].SetProperty( PIDSI_SUBJECT ); |
| m_pAttributes[3].SetPropSet( FMTID_SummaryInformation ); |
| m_pAttributes[3].SetProperty( PIDSI_KEYWORDS ); |
| m_pAttributes[4].SetPropSet( FMTID_SummaryInformation ); |
| m_pAttributes[4].SetProperty( PIDSI_COMMENTS ); |
| } |
| else if ( 0 == grfFlags ) |
| { |
| // Filter only contents |
| m_fContents = TRUE; |
| } |
| else |
| m_fContents = FALSE; |
| // Re-initialize |
| if ( m_fContents ) |
| { |
| m_fEof = FALSE; |
| m_eState = FilteringContent; |
| m_ulUnicodeCharsRead = 0; |
| m_ChunkPosition = 0; |
| } |
| else |
| { |
| m_fEof = TRUE; |
| m_eState = FilteringProperty; |
| } |
| m_ulChunkID = 1; |
| } |
| catch (const std::exception&) |
| { |
| return E_FAIL; |
| } |
| |
| return S_OK; |
| } |
| //M------------------------------------------------------------------------- |
| // |
| // Method: COooFilter::GetChunk (IFilter::GetChunk) |
| // |
| // Summary: Gets the next chunk |
| // |
| // Arguments: ppStat |
| // [out] Pointer to description of current chunk |
| // Returns: S_OK |
| // Chunk was successfully retrieved |
| // E_FAIL |
| // Character conversion failed |
| // FILTER_E_ACCESS |
| // General access failure occurred |
| // FILTER_E_END_OF_CHUNKS |
| // Previous chunk was the last chunk |
| // FILTER_E_EMBEDDING_UNAVAILABLE |
| // (not implemented) |
| // FILTER_E_LINK_UNAVAILABLE |
| // (not implemented) |
| // FILTER_E_PASSWORD |
| // (not implemented) |
| // |
| //-------------------------------------------------------------------------- |
| SCODE STDMETHODCALLTYPE COooFilter::GetChunk(STAT_CHUNK * pStat) |
| { |
| for(;;) |
| { |
| switch ( m_eState ) |
| { |
| case FilteringContent: |
| { |
| // Read Unicodes from buffer. |
| if( m_ChunkPosition == m_pContentReader ->getChunkBuffer().size() ) |
| { |
| m_ulUnicodeBufferLen=0; |
| m_fEof = TRUE; |
| } |
| |
| if ( !m_fContents || m_fEof ) |
| { |
| m_eState = FilteringProperty; |
| continue; |
| } |
| m_pwsBuffer = m_pContentReader -> getChunkBuffer()[m_ChunkPosition].second; |
| m_ulUnicodeBufferLen = m_pwsBuffer.length(); |
| DWORD ChunkLCID = LocaleSetToLCID( m_pContentReader -> getChunkBuffer()[m_ChunkPosition].first ); |
| // Set chunk description |
| pStat->idChunk = m_ulChunkID; |
| pStat->breakType = CHUNK_NO_BREAK; |
| pStat->flags = CHUNK_TEXT; |
| pStat->locale = ChunkLCID; |
| pStat->attribute.guidPropSet = guidStorage; |
| pStat->attribute.psProperty.ulKind = PRSPEC_PROPID; |
| pStat->attribute.psProperty.propid = PID_STG_CONTENTS; |
| pStat->idChunkSource = m_ulChunkID; |
| pStat->cwcStartSource = 0; |
| pStat->cwcLenSource = 0; |
| m_ulUnicodeCharsRead = 0; |
| m_ulChunkID++; |
| m_ChunkPosition++; |
| return S_OK; |
| } |
| case FilteringProperty: |
| { |
| if ( m_cAttributes == 0 ) |
| return FILTER_E_END_OF_CHUNKS; |
| while( !( ( m_pAttributes[m_ulPropertyNum].IsPropertyPropid() ) && |
| ( m_pAttributes[m_ulPropertyNum].GetPropSet() == FMTID_SummaryInformation ) )|| |
| ( ( m_pAttributes[m_ulPropertyNum].GetPropertyPropid() != PIDSI_AUTHOR ) && |
| ( m_pAttributes[m_ulPropertyNum].GetPropertyPropid() != PIDSI_TITLE ) && |
| ( m_pAttributes[m_ulPropertyNum].GetPropertyPropid() != PIDSI_SUBJECT ) && |
| ( m_pAttributes[m_ulPropertyNum].GetPropertyPropid() != PIDSI_KEYWORDS ) && |
| ( m_pAttributes[m_ulPropertyNum].GetPropertyPropid() != PIDSI_COMMENTS ) ) ) |
| { |
| if ( m_ulPropertyNum < m_cAttributes ) |
| m_ulPropertyNum++; |
| else |
| break; |
| } |
| if ( m_ulPropertyNum == m_cAttributes) |
| return FILTER_E_END_OF_CHUNKS; |
| else |
| { |
| // Set chunk description |
| pStat->idChunk = m_ulChunkID; |
| pStat->breakType = CHUNK_EOS; |
| pStat->flags = CHUNK_VALUE; |
| pStat->locale = GetSystemDefaultLCID(); |
| pStat->attribute.guidPropSet = FMTID_SummaryInformation; |
| pStat->attribute.psProperty.ulKind = PRSPEC_PROPID; |
| pStat->attribute.psProperty.propid = m_pAttributes[m_ulPropertyNum].GetPropertyPropid(); |
| pStat->idChunkSource = m_ulChunkID; |
| pStat->cwcStartSource = 0; |
| pStat->cwcLenSource = 0; |
| m_ulCurrentPropertyNum = m_ulPropertyNum; |
| m_ulPropertyNum++; |
| m_ulChunkID++; |
| return S_OK; |
| } |
| } |
| default: |
| return E_FAIL; |
| }//switch(...) |
| }//for(;;) |
| } |
| //M------------------------------------------------------------------------- |
| // |
| // Method: COooFilter::GetText (IFilter::GetText) |
| // |
| // Summary: Retrieves UNICODE text for index |
| // |
| // Arguments: pcwcBuffer |
| // [in] Pointer to size of UNICODE buffer |
| // [out] Pointer to count of UNICODE characters returned |
| // awcBuffer |
| // [out] Pointer to buffer to receive UNICODE text |
| // |
| // Returns: S_OK |
| // Text successfully retrieved, but text remains in chunk |
| // FILTER_E_NO_MORE_TEXT |
| // All of the text in the current chunk has been returned |
| // FILTER_S_LAST_TEXT |
| // Next call to GetText will return FILTER_E_NO_MORE_TEXT |
| // |
| //-------------------------------------------------------------------------- |
| SCODE STDMETHODCALLTYPE COooFilter::GetText(ULONG * pcwcBuffer, WCHAR * awcBuffer) |
| { |
| switch ( m_eState ) |
| { |
| case FilteringProperty: |
| return FILTER_E_NO_TEXT; |
| case FilteringContent: |
| { |
| if ( !m_fContents || 0 == m_ulUnicodeBufferLen ) |
| { |
| *pcwcBuffer = 0; |
| return FILTER_E_NO_MORE_TEXT; |
| } |
| // Copy UNICODE characters in chunk buffer to output UNICODE buffer |
| ULONG ulToCopy = min( *pcwcBuffer, m_ulUnicodeBufferLen - m_ulUnicodeCharsRead ); |
| ZeroMemory(awcBuffer, sizeof(awcBuffer)); |
| wmemcpy( awcBuffer, m_pwsBuffer.c_str() + m_ulUnicodeCharsRead, ulToCopy ); |
| m_ulUnicodeCharsRead += ulToCopy; |
| *pcwcBuffer = ulToCopy; |
| if ( m_ulUnicodeBufferLen == m_ulUnicodeCharsRead ) |
| { |
| m_ulUnicodeCharsRead = 0; |
| m_ulUnicodeBufferLen = 0; |
| return FILTER_S_LAST_TEXT; |
| } |
| return S_OK; |
| } |
| default: |
| return E_FAIL; |
| } |
| } |
| //M------------------------------------------------------------------------- |
| // |
| // Method: GetMetaInfoNameFromPropertyId |
| // |
| // Summary: helper function to convert PropertyID into respective |
| // MetaInfo names. |
| // |
| // Arguments: ulPropID |
| // [in] property ID |
| // |
| // Returns: corresponding metainfo names. |
| // |
| //-------------------------------------------------------------------------- |
| |
| ::std::wstring GetMetaInfoNameFromPropertyId( ULONG ulPropID ) |
| { |
| switch ( ulPropID ) |
| { |
| case PIDSI_AUTHOR: return META_INFO_AUTHOR; |
| case PIDSI_TITLE: return META_INFO_TITLE; |
| case PIDSI_SUBJECT: return META_INFO_SUBJECT; |
| case PIDSI_KEYWORDS: return META_INFO_KEYWORDS; |
| case PIDSI_COMMENTS: return META_INFO_DESCRIPTION; |
| default: return EMPTY_STRING; |
| } |
| } |
| //M------------------------------------------------------------------------- |
| // |
| // Method: COooFilter::GetValue (IFilter::GetValue) |
| // |
| // Summary: Retrieves properites for index |
| // |
| // Arguments: ppPropValue |
| // [out] Address that receives pointer to property value |
| // |
| // Returns: FILTER_E_NO_VALUES |
| // Always |
| // FILTER_E_NO_MORE_VALUES |
| // (not implemented) |
| // |
| //-------------------------------------------------------------------------- |
| |
| SCODE STDMETHODCALLTYPE COooFilter::GetValue(PROPVARIANT ** ppPropValue) |
| { |
| if (m_eState == FilteringContent) |
| return FILTER_E_NO_VALUES; |
| else if (m_eState == FilteringProperty) |
| { |
| if ( m_cAttributes == 0 || ( m_ulCurrentPropertyNum == m_ulPropertyNum ) ) |
| return FILTER_E_NO_MORE_VALUES; |
| PROPVARIANT *pPropVar = (PROPVARIANT *) CoTaskMemAlloc( sizeof (PROPVARIANT) ); |
| if ( pPropVar == 0 ) |
| return E_OUTOFMEMORY; |
| ::std::wstring wsTagName= GetMetaInfoNameFromPropertyId( m_pAttributes[m_ulCurrentPropertyNum].GetPropertyPropid() ); |
| if ( wsTagName == EMPTY_STRING ) |
| return FILTER_E_NO_VALUES; |
| ::std::wstring wsTagData = m_pMetaInfoReader->getTagData(wsTagName); |
| pPropVar->vt = VT_LPWSTR; |
| size_t cw = wsTagData.length() + 1; // reserve one for the '\0' |
| pPropVar->pwszVal = static_cast<WCHAR*>( CoTaskMemAlloc(cw*sizeof(WCHAR)) ); |
| if (pPropVar->pwszVal == 0) |
| { |
| CoTaskMemFree(pPropVar); |
| return E_OUTOFMEMORY; |
| } |
| wmemcpy(pPropVar->pwszVal, wsTagData.c_str(), cw); |
| *ppPropValue = pPropVar; |
| m_ulCurrentPropertyNum = m_ulPropertyNum; |
| return S_OK; |
| } |
| else |
| return E_FAIL; |
| } |
| //M------------------------------------------------------------------------- |
| // |
| // Method: COooFilter::BindRegion (IFilter::BindRegion) |
| // |
| // Summary: Creates moniker or other interface for indicated text |
| // |
| // Arguments: origPos |
| // [in] Description of text location and extent |
| // riid |
| // [in] Reference IID of specified interface |
| // ppunk |
| // [out] Address that receives requested interface pointer |
| // |
| // Returns: E_NOTIMPL |
| // Always |
| // FILTER_W_REGION_CLIPPED |
| // (not implemented) |
| // |
| //-------------------------------------------------------------------------- |
| |
| SCODE STDMETHODCALLTYPE COooFilter::BindRegion( |
| FILTERREGION /*origPos*/, |
| REFIID /*riid*/, |
| void ** /*ppunk*/) |
| { |
| // BindRegion is currently reserved for future use |
| return E_NOTIMPL; |
| } |
| //M------------------------------------------------------------------------- |
| // |
| // Method: COooFilter::GetClassID (IPersist::GetClassID) |
| // |
| // Summary: Retrieves the class id of the filter class |
| // |
| // Arguments: pClassID |
| // [out] Pointer to the class ID of the filter |
| // |
| // Returns: S_OK |
| // Always |
| // E_FAIL |
| // (not implemented) |
| //-------------------------------------------------------------------------- |
| SCODE STDMETHODCALLTYPE COooFilter::GetClassID(CLSID * pClassID) |
| { |
| *pClassID = CLSID_COooFilter; |
| return S_OK; |
| } |
| //M------------------------------------------------------------------------- |
| // |
| // Method: COooFilter::IsDirty (IPersistFile::IsDirty) |
| // |
| // Summary: Checks whether file has changed since last save |
| // |
| // Arguments: void |
| // |
| // Returns: S_FALSE |
| // Always |
| // S_OK |
| // (not implemented) |
| // |
| //-------------------------------------------------------------------------- |
| SCODE STDMETHODCALLTYPE COooFilter::IsDirty() |
| { |
| // File is opened read-only and never changes |
| return S_FALSE; |
| } |
| //M------------------------------------------------------------------------- |
| // |
| // Method: COooFilter::Load (IPersistFile::Load) |
| // |
| // Summary: Opens and initializes the specified file |
| // |
| // Arguments: pszFileName |
| // [in] Pointer to zero-terminated string |
| // of absolute path of file to open |
| // dwMode |
| // [in] Access mode to open the file |
| // |
| // Returns: S_OK |
| // File was successfully loaded |
| // E_OUTOFMEMORY |
| // File could not be loaded due to insufficient memory |
| // E_FAIL |
| // (not implemented) |
| // |
| //-------------------------------------------------------------------------- |
| SCODE STDMETHODCALLTYPE COooFilter::Load(LPCWSTR pszFileName, DWORD /*dwMode*/) |
| { |
| // Load just sets the filename for GetChunk to read and ignores the mode |
| m_pwszFileName = getShortPathName( pszFileName ); |
| |
| // Open the file previously specified in call to IPersistFile::Load and get content. |
| try |
| { |
| if (m_pMetaInfoReader) |
| delete m_pMetaInfoReader; |
| m_pMetaInfoReader = new CMetaInfoReader(WStringToString(m_pwszFileName)); |
| |
| if (m_pContentReader) |
| delete m_pContentReader; |
| m_pContentReader = new CContentReader(WStringToString(m_pwszFileName), m_pMetaInfoReader->getDefaultLocale()); |
| } |
| catch (const std::exception&) |
| { |
| return E_FAIL; |
| } |
| return S_OK; |
| } |
| //M------------------------------------------------------------------------- |
| // |
| // Method: COooFilter::Save (IPersistFile::Save) |
| // |
| // Summary: Saves a copy of the current file being filtered |
| // |
| // Arguments: pszFileName |
| // [in] Pointer to zero-terminated string of |
| // absolute path of where to save file |
| // fRemember |
| // [in] Whether the saved copy is made the current file |
| // |
| // Returns: E_FAIL |
| // Always |
| // S_OK |
| // (not implemented) |
| // |
| //-------------------------------------------------------------------------- |
| SCODE STDMETHODCALLTYPE COooFilter::Save(LPCWSTR /*pszFileName*/, BOOL /*fRemember*/) |
| { |
| // File is opened read-only; saving it is an error |
| return E_FAIL; |
| } |
| //M------------------------------------------------------------------------- |
| // |
| // Method: COooFilter::SaveCompleted (IPersistFile::SaveCompleted) |
| // |
| // Summary: Determines whether a file save is completed |
| // |
| // Arguments: pszFileName |
| // [in] Pointer to zero-terminated string of |
| // absolute path where file was previously saved |
| // |
| // Returns: S_OK |
| // Always |
| // |
| //-------------------------------------------------------------------------- |
| SCODE STDMETHODCALLTYPE COooFilter::SaveCompleted(LPCWSTR /*pszFileName*/) |
| { |
| // File is opened read-only, so "save" is always finished |
| return S_OK; |
| } |
| |
| //M------------------------------------------------------------------------- |
| // |
| // Method: COooFilter::Load (IPersistStream::Load) |
| // |
| // Summary: Initializes an object from the stream where it was previously saved |
| // |
| // Arguments: pStm |
| // [in] Pointer to stream from which object should be loaded |
| // |
| // |
| // Returns: S_OK |
| // E_OUTOFMEMORY |
| // E_FAIL |
| // |
| // |
| //-------------------------------------------------------------------------- |
| SCODE STDMETHODCALLTYPE COooFilter::Load(IStream *pStm) |
| { |
| zlib_filefunc_def z_filefunc; |
| |
| m_pStream = PrepareIStream( pStm, z_filefunc ); |
| |
| try |
| { |
| if (m_pMetaInfoReader) |
| delete m_pMetaInfoReader; |
| m_pMetaInfoReader = new CMetaInfoReader((void*)m_pStream, &z_filefunc); |
| |
| if (m_pContentReader) |
| delete m_pContentReader; |
| m_pContentReader = new CContentReader((void*)m_pStream, m_pMetaInfoReader->getDefaultLocale(), &z_filefunc); |
| } |
| catch (const std::exception&) |
| { |
| return E_FAIL; |
| } |
| return S_OK; |
| } |
| |
| //M------------------------------------------------------------------------- |
| // |
| // Method: COooFilter::GetSizeMax (IPersistStream::GetSizeMax) |
| // |
| // Summary: Returns the size in bytes of the stream neede to save the object. |
| // |
| // Arguments: pcbSize |
| // [out] Pointer to a 64 bit unsigned int indicating the size needed |
| // |
| // Returns: E_NOTIMPL |
| // |
| // |
| //-------------------------------------------------------------------------- |
| SCODE STDMETHODCALLTYPE COooFilter::GetSizeMax(ULARGE_INTEGER * /*pcbSize*/) |
| { |
| // |
| return E_NOTIMPL; |
| } |
| |
| //M------------------------------------------------------------------------- |
| // |
| // Method: COooFilter::Save (IPersistStream::Save) |
| // |
| // Summary: Save object to specified stream |
| // |
| // Arguments: pStm |
| // [in] Pointer to stream |
| // |
| // fClearDirty |
| // [in] Indicates whether to clear dirty flag |
| // |
| // Returns: E_NOTIMPL |
| // |
| // |
| //-------------------------------------------------------------------------- |
| SCODE STDMETHODCALLTYPE COooFilter::Save(IStream * /*pStm*/, BOOL ) |
| { |
| // |
| return E_NOTIMPL; |
| } |
| |
| //M------------------------------------------------------------------------- |
| // |
| // Method: COooFilter::GetCurFile (IPersistFile::GetCurFile) |
| // |
| // Summary: Returns a copy of the current file name |
| // |
| // Arguments: ppszFileName |
| // [out] Address to receive pointer to zero-terminated |
| // string for absolute path to current file |
| // |
| // Returns: S_OK |
| // A valid absolute path was successfully returned |
| // S_FALSE |
| // (not implemented) |
| // E_OUTOFMEMORY |
| // Operation failed due to insufficient memory |
| // E_FAIL |
| // Operation failed due to some reason |
| // other than insufficient memory |
| // |
| //------------------------------------------------------------------------- |
| SCODE STDMETHODCALLTYPE COooFilter::GetCurFile(LPWSTR * ppszFileName) |
| { |
| if ( EMPTY_STRING == m_pwszFileName ) |
| return E_FAIL; |
| else |
| *ppszFileName = (LPWSTR)m_pwszFileName.c_str(); |
| return S_OK; |
| } |
| |
| //M------------------------------------------------------------------------- |
| // |
| // Method: COooFilterCF::COooFilterCF |
| // |
| // Summary: Class factory constructor |
| // |
| // Arguments: void |
| // |
| // Purpose: Manages global instance count |
| // |
| //-------------------------------------------------------------------------- |
| COooFilterCF::COooFilterCF() : |
| m_lRefs(1) |
| { |
| InterlockedIncrement( &g_lInstances ); |
| } |
| //M------------------------------------------------------------------------- |
| // |
| // Method: COooFilterCF::~COooFilterCF |
| // |
| // Summary: Class factory destructor |
| // |
| // Arguments: void |
| // |
| // Purpose: Manages global instance count |
| // |
| //-------------------------------------------------------------------------- |
| COooFilterCF::~COooFilterCF() |
| { |
| InterlockedDecrement( &g_lInstances ); |
| } |
| //M------------------------------------------------------------------------- |
| // |
| // Method: COooFilterCF::QueryInterface (IUnknown::QueryInterface) |
| // |
| // Summary: Queries for requested interface |
| // |
| // Arguments: riid |
| // [in] Reference IID of requested interface |
| // ppvObject |
| // [out] Address that receives requested interface pointer |
| // |
| // Returns: S_OK |
| // Interface is supported |
| // E_NOINTERFACE |
| // Interface is not supported |
| // |
| //-------------------------------------------------------------------------- |
| SCODE STDMETHODCALLTYPE COooFilterCF::QueryInterface(REFIID riid, void ** ppvObject) |
| { |
| IUnknown *pUnkTemp; |
| |
| if ( IID_IClassFactory == riid ) |
| pUnkTemp = (IUnknown *)(IClassFactory *)this; |
| else if ( IID_IUnknown == riid ) |
| pUnkTemp = (IUnknown *)this; |
| else |
| { |
| *ppvObject = NULL; |
| return E_NOINTERFACE; |
| } |
| *ppvObject = (void *)pUnkTemp; |
| pUnkTemp->AddRef(); |
| return S_OK; |
| } |
| //M------------------------------------------------------------------------- |
| // |
| // Method: COooFilterCF::AddRef (IUknown::AddRef) |
| // |
| // Summary: Increments interface refcount |
| // |
| // Arguments: void |
| // |
| // Returns: Value of incremented interface refcount |
| // |
| //------------------------------------------------------------------------- |
| ULONG STDMETHODCALLTYPE COooFilterCF::AddRef() |
| { |
| return InterlockedIncrement( &m_lRefs ); |
| } |
| //M------------------------------------------------------------------------- |
| // |
| // Method: COooFilterCF::Release (IUnknown::Release) |
| // |
| // Summary: Decrements interface refcount, deleting if unreferenced |
| // |
| // Arguments: void |
| // |
| // Returns: Value of decremented refcount |
| // |
| //-------------------------------------------------------------------------- |
| ULONG STDMETHODCALLTYPE COooFilterCF::Release() |
| { |
| ULONG ulTmp = InterlockedDecrement( &m_lRefs ); |
| |
| if ( 0 == ulTmp ) |
| delete this; |
| return ulTmp; |
| } |
| //M------------------------------------------------------------------------- |
| // |
| // Method: COooFilterCF::CreateInstance (IClassFactory::CreateInstance) |
| // |
| // Summary: Creates new OpenOffice.org filter object |
| // |
| // Arguments: pUnkOuter |
| // [in] Pointer to IUnknown interface of aggregating object |
| // riid |
| // [in] Reference IID of requested interface |
| // ppvObject |
| // [out] Address that receives requested interface pointer |
| // |
| // Returns: S_OK |
| // OpenOffice.org filter object was successfully created |
| // CLASS_E_NOAGGREGATION |
| // pUnkOuter parameter was non-NULL |
| // E_NOINTERFACE |
| // (not implemented) |
| // E_OUTOFMEMORY |
| // OpenOffice.org filter object could not be created |
| // due to insufficient memory |
| // E_UNEXPECTED |
| // Unsuccessful due to an unexpected condition |
| // |
| //-------------------------------------------------------------------------- |
| SCODE STDMETHODCALLTYPE COooFilterCF::CreateInstance( |
| IUnknown * pUnkOuter, |
| REFIID riid, |
| void * * ppvObject) |
| { |
| COooFilter *pIUnk = 0; |
| if ( 0 != pUnkOuter ) |
| return CLASS_E_NOAGGREGATION; |
| pIUnk = new COooFilter(); |
| if ( 0 != pIUnk ) |
| { |
| if ( SUCCEEDED( pIUnk->QueryInterface( riid , ppvObject ) ) ) |
| { |
| // Release extra refcount from QueryInterface |
| pIUnk->Release(); |
| } |
| else |
| { |
| delete pIUnk; |
| return E_UNEXPECTED; |
| } |
| } |
| else |
| return E_OUTOFMEMORY; |
| return S_OK; |
| } |
| |
| //M------------------------------------------------------------------------- |
| // |
| // Method: COooFilterCF::LockServer (IClassFactory::LockServer) |
| // |
| // Summary: Forces/allows filter class to remain loaded/be unloaded |
| // |
| // Arguments: fLock |
| // [in] TRUE to lock, FALSE to unlock |
| // |
| // Returns: S_OK |
| // Always |
| // E_FAIL |
| // (not implemented) |
| // E_OUTOFMEMORY |
| // (not implemented) |
| // E_UNEXPECTED |
| // (not implemented) |
| // |
| //-------------------------------------------------------------------------- |
| SCODE STDMETHODCALLTYPE COooFilterCF::LockServer(BOOL fLock) |
| { |
| if( fLock ) |
| InterlockedIncrement( &g_lInstances ); |
| else |
| InterlockedDecrement( &g_lInstances ); |
| return S_OK; |
| } |
| //+------------------------------------------------------------------------- |
| // |
| // DLL: ooofilt.dll |
| // |
| // Summary: Implements Dynamic Link Library functions for OpenOffice.org filter |
| // |
| //-------------------------------------------------------------------------- |
| //F------------------------------------------------------------------------- |
| // |
| // Function: DllMain |
| // |
| // Summary: Called from C-Runtime on process/thread attach/detach |
| // |
| // Arguments: hInstance |
| // [in] Handle to the DLL |
| // fdwReason |
| // [in] Reason for calling DLL entry point |
| // lpReserve |
| // [in] Details of DLL initialization and cleanup |
| // |
| // Returns: TRUE |
| // Always |
| // |
| //-------------------------------------------------------------------------- |
| extern "C" BOOL WINAPI DllMain( |
| HINSTANCE hInstance, |
| DWORD fdwReason, |
| LPVOID /*lpvReserved*/ |
| ) |
| { |
| if ( DLL_PROCESS_ATTACH == fdwReason ) |
| DisableThreadLibraryCalls( hInstance ); |
| return TRUE; |
| } |
| //F------------------------------------------------------------------------- |
| // |
| // Function: DllGetClassObject |
| // |
| // Summary: Create OpenOffice.org filter class factory object |
| // |
| // Arguments: cid |
| // [in] Class ID of class that class factory creates |
| // iid |
| // [in] Reference IID of requested class factory interface |
| // ppvObj |
| // [out] Address that receives requested interface pointer |
| // |
| // Returns: S_OK |
| // Class factory object was created successfully |
| // CLASS_E_CLASSNOTAVAILABLE |
| // DLL does not support the requested class |
| // E_INVALIDARG |
| // (not implemented |
| // E_OUTOFMEMORY |
| // Insufficient memory to create the class factory object |
| // E_UNEXPECTED |
| // Unsuccessful due to an unexpected condition |
| // |
| //------------------------------------------------------------------------- |
| extern "C" SCODE STDMETHODCALLTYPE DllGetClassObject( |
| REFCLSID cid, |
| REFIID iid, |
| void ** ppvObj |
| ) |
| { |
| IUnknown *pResult = 0; |
| |
| if ( CLSID_COooFilter == cid ) |
| pResult = (IUnknown *) new COooFilterCF; |
| else |
| return CLASS_E_CLASSNOTAVAILABLE; |
| if ( 0 != pResult ) |
| { |
| if( SUCCEEDED( pResult->QueryInterface( iid, ppvObj ) ) ) |
| // Release extra refcount from QueryInterface |
| pResult->Release(); |
| else |
| { |
| delete pResult; |
| return E_UNEXPECTED; |
| } |
| } |
| else |
| return E_OUTOFMEMORY; |
| return S_OK; |
| } |
| //F------------------------------------------------------------------------- |
| // |
| // Function: DllCanUnloadNow |
| // |
| // Summary: Indicates whether it is possible to unload DLL |
| // |
| // Arguments: void |
| // |
| // Returns: S_OK |
| // DLL can be unloaded now |
| // S_FALSE |
| // DLL must remain loaded |
| // |
| //-------------------------------------------------------------------------- |
| extern "C" SCODE STDMETHODCALLTYPE DllCanUnloadNow() |
| { |
| if ( 0 >= g_lInstances ) |
| return S_OK; |
| else |
| return S_FALSE; |
| } |
| //F------------------------------------------------------------------------- |
| // |
| // Function: DllRegisterServer |
| // DllUnregisterServer |
| // |
| // Summary: Registers and unregisters DLL server |
| // |
| // Returns: DllRegisterServer |
| // S_OK |
| // Registration was successful |
| // SELFREG_E_CLASS |
| // Registration was unsuccessful |
| // SELFREG_E_TYPELIB |
| // (not implemented) |
| // E_OUTOFMEMORY |
| // (not implemented) |
| // E_UNEXPECTED |
| // (not implemented) |
| // DllUnregisterServer |
| // S_OK |
| // Unregistration was successful |
| // S_FALSE |
| // Unregistration was successful, but other |
| // entries still exist for the DLL's classes |
| // SELFREG_E_CLASS |
| // (not implemented) |
| // SELFREG_E_TYPELIB |
| // (not implemented) |
| // E_OUTOFMEMORY |
| // (not implemented) |
| // E_UNEXPECTED |
| // (not implemented) |
| // |
| //-------------------------------------------------------------------------- |
| |
| |
| //F------------------------------------------------------------------------- |
| // |
| // helper functions to register the Indexing Service. |
| // |
| //-------------------------------------------------------------------------- |
| |
| namespace /* private */ |
| { |
| const char* GUID_PLACEHOLDER = "{GUID}"; |
| const char* GUID_PERSIST_PLACEHOLDER = "{GUIDPERSIST}"; |
| const char* EXTENSION_PLACEHOLDER = "{EXT}"; |
| const char* FORWARDKEY_PLACEHOLDER = "{FWDKEY}"; |
| |
| const char* CLSID_GUID_INPROC_ENTRY = "CLSID\\{GUID}\\InProcServer32"; |
| const char* CLSID_GUID_ENTRY = "CLSID\\{GUID}"; |
| const char* CLSID_GUID_PERSIST_ADDIN_ENTRY = "CLSID\\{GUID}\\PersistentAddinsRegistered\\{GUIDPERSIST}"; |
| const char* CLSID_PERSIST_ENTRY = "CLSID\\{GUID}\\PersistentHandler"; |
| const char* EXT_PERSIST_ENTRY = "{EXT}\\PersistentHandler"; |
| |
| const char* INDEXING_FILTER_DLLSTOREGISTER = "SYSTEM\\CurrentControlSet\\Control\\ContentIndex"; |
| |
| //--------------------------- |
| // "String Placeholder" -> |
| // "String Replacement" |
| //--------------------------- |
| |
| void SubstitutePlaceholder(std::string& String, const std::string& Placeholder, const std::string& Replacement) |
| { |
| std::string::size_type idx = String.find(Placeholder); |
| std::string::size_type len = Placeholder.length(); |
| |
| while (std::string::npos != idx) |
| { |
| String.replace(idx, len, Replacement); |
| idx = String.find(Placeholder); |
| } |
| } |
| |
| //---------------------------------------------- |
| // Make the registry entry and set Filter Handler |
| // HKCR\CLSID\{7BC0E710-5703-45be-A29D-5D46D8B39262} = OpenOffice.org Filter |
| // InProcServer32 (Default) = Path\ooofilt.dll |
| // ThreadingModel = Both |
| //---------------------------------------------- |
| |
| HRESULT RegisterFilterHandler(const char* FilePath, const CLSID& FilterGuid) |
| { |
| std::string ClsidEntry = CLSID_GUID_ENTRY; |
| SubstitutePlaceholder(ClsidEntry, GUID_PLACEHOLDER, ClsidToString(FilterGuid)); |
| |
| if (!SetRegistryKey(HKEY_CLASSES_ROOT, ClsidEntry.c_str(), "", "OpenOffice.org XML Filter")) |
| return E_FAIL; |
| |
| ClsidEntry = CLSID_GUID_INPROC_ENTRY; |
| SubstitutePlaceholder(ClsidEntry, GUID_PLACEHOLDER, ClsidToString(FilterGuid)); |
| |
| if (!SetRegistryKey(HKEY_CLASSES_ROOT, ClsidEntry.c_str(), "", FilePath)) |
| return E_FAIL; |
| |
| if (!SetRegistryKey(HKEY_CLASSES_ROOT, ClsidEntry.c_str(), "ThreadingModel", "Both")) |
| return E_FAIL; |
| |
| return S_OK; |
| } |
| |
| //---------------------------------------------- |
| // Make the registry entry and set Persistent Handler |
| // HKCR\CLSID\{7BC0E713-5703-45be-A29D-5D46D8B39262} = OpenOffice.org Persistent Handler |
| // PersistentAddinsRegistered |
| // {89BCB740-6119-101A-BCB7-00DD010655AF} = {7BC0E710-5703-45be-A29D-5D46D8B39262} |
| //---------------------------------------------- |
| |
| HRESULT RegisterPersistentHandler(const CLSID& FilterGuid, const CLSID& PersistentGuid) |
| { |
| std::string ClsidEntry_Persist = CLSID_GUID_ENTRY; |
| SubstitutePlaceholder(ClsidEntry_Persist, GUID_PLACEHOLDER, ClsidToString(PersistentGuid)); |
| |
| |
| if (!SetRegistryKey(HKEY_CLASSES_ROOT, ClsidEntry_Persist.c_str(), "", "OpenOffice Persistent Handler")) |
| return E_FAIL; |
| |
| // Add missing entry |
| std::string ClsidEntry_Persist_Entry = CLSID_PERSIST_ENTRY; |
| SubstitutePlaceholder(ClsidEntry_Persist_Entry, |
| GUID_PLACEHOLDER, |
| ClsidToString(PersistentGuid)); |
| |
| if (!SetRegistryKey(HKEY_CLASSES_ROOT, ClsidEntry_Persist_Entry.c_str(), "", ClsidToString(PersistentGuid).c_str())) |
| return E_FAIL; |
| |
| std::string ClsidEntry_Persist_Addin = CLSID_GUID_PERSIST_ADDIN_ENTRY; |
| SubstitutePlaceholder(ClsidEntry_Persist_Addin, |
| GUID_PLACEHOLDER, |
| ClsidToString(PersistentGuid)); |
| SubstitutePlaceholder(ClsidEntry_Persist_Addin, |
| GUID_PERSIST_PLACEHOLDER, |
| ClsidToString(CLSID_PERSISTENT_HANDLER_ADDIN)); |
| |
| if (!SetRegistryKey(HKEY_CLASSES_ROOT, ClsidEntry_Persist_Addin.c_str(), "", ClsidToString(FilterGuid).c_str() )) |
| return E_FAIL; |
| |
| return S_OK; |
| } |
| |
| //--------------------------- |
| // Unregister Filter Handler or persistent handler |
| //--------------------------- |
| |
| HRESULT UnregisterHandler(const CLSID& Guid) |
| { |
| std::string tmp = "CLSID\\"; |
| tmp += ClsidToString(Guid); |
| return DeleteRegistryKey(HKEY_CLASSES_ROOT, tmp.c_str()) ? S_OK : E_FAIL; |
| } |
| |
| //--------------------------- |
| // Register Indexing Service ext and class. |
| // HKCR\{EXT}\PersistentHandler = {7BC0E713-5703-45be-A29D-5D46D8B39262} |
| // HKCR\{GUID\PersistentHandler = {7BC0E713-5703-45be-A29D-5D46D8B39262} |
| //--------------------------- |
| |
| HRESULT RegisterSearchHandler(const char* ModuleFileName) |
| { |
| if (FAILED(RegisterFilterHandler(ModuleFileName, CLSID_FILTER_HANDLER))) |
| return E_FAIL; |
| |
| if (FAILED(RegisterPersistentHandler(CLSID_FILTER_HANDLER, CLSID_PERSISTENT_HANDLER ))) |
| return E_FAIL; |
| |
| std::string sExtPersistEntry; |
| |
| for(size_t i = 0; i < OOFileExtensionTableSize; i++) |
| { |
| // first, register extension. |
| sExtPersistEntry = EXT_PERSIST_ENTRY; |
| SubstitutePlaceholder(sExtPersistEntry, EXTENSION_PLACEHOLDER, OOFileExtensionTable[i].ExtensionAnsi); |
| if (!SetRegistryKey(HKEY_CLASSES_ROOT, |
| sExtPersistEntry.c_str(), |
| "", |
| ClsidToString(CLSID_PERSISTENT_HANDLER).c_str())) |
| return E_FAIL; |
| |
| // second, register class. |
| char extClassName[MAX_PATH]; |
| if (QueryRegistryKey(HKEY_CLASSES_ROOT, OOFileExtensionTable[i].ExtensionAnsi, "", extClassName,MAX_PATH)) |
| { |
| ::std::string extCLSIDName( extClassName ); |
| extCLSIDName += "\\CLSID"; |
| char extCLSID[MAX_PATH]; |
| |
| if (QueryRegistryKey( HKEY_CLASSES_ROOT, extCLSIDName.c_str(), "", extCLSID, MAX_PATH)) |
| { |
| std::string ClsidEntry_CLSID_Persist = CLSID_PERSIST_ENTRY; |
| SubstitutePlaceholder(ClsidEntry_CLSID_Persist, |
| GUID_PLACEHOLDER, |
| extCLSID); |
| |
| if (!SetRegistryKey(HKEY_CLASSES_ROOT, |
| ClsidEntry_CLSID_Persist.c_str(), |
| "", |
| ClsidToString(CLSID_PERSISTENT_HANDLER).c_str() )) |
| return E_FAIL; |
| } |
| } |
| } |
| |
| return S_OK; |
| } |
| |
| // Register Indexing Service ext and class. |
| HRESULT UnregisterSearchHandler() |
| { |
| std::string sExtPersistEntry; |
| |
| for (size_t i = 0; i < OOFileExtensionTableSize; i++) |
| { |
| // first, unregister extension |
| sExtPersistEntry = EXT_PERSIST_ENTRY; |
| SubstitutePlaceholder(sExtPersistEntry, EXTENSION_PLACEHOLDER, OOFileExtensionTable[i].ExtensionAnsi); |
| DeleteRegistryKey(HKEY_CLASSES_ROOT, sExtPersistEntry.c_str()); |
| |
| // second, unregister class |
| char extClassName[MAX_PATH]; |
| if (QueryRegistryKey(HKEY_CLASSES_ROOT, OOFileExtensionTable[i].ExtensionAnsi, "", extClassName,MAX_PATH)) |
| { |
| ::std::string extCLSIDName( extClassName ); |
| extCLSIDName += "\\CLSID"; |
| char extCLSID[MAX_PATH]; |
| |
| if (QueryRegistryKey( HKEY_CLASSES_ROOT, extCLSIDName.c_str(), "", extCLSID, MAX_PATH)) |
| { |
| std::string ClsidEntry_CLSID_Persist = CLSID_PERSIST_ENTRY; |
| SubstitutePlaceholder(ClsidEntry_CLSID_Persist, |
| GUID_PLACEHOLDER, |
| extCLSID); |
| |
| DeleteRegistryKey(HKEY_CLASSES_ROOT, ClsidEntry_CLSID_Persist.c_str()); |
| } |
| } |
| } |
| |
| return ((UnregisterHandler(CLSID_FILTER_HANDLER)==S_OK) && (UnregisterHandler(CLSID_PERSISTENT_HANDLER)==S_OK))?S_OK:E_FAIL; |
| } |
| |
| //--------------------------- |
| // add or remove an entry to DllsToRegister entry of Indexing |
| // Filter to let Indexing Service register our filter automatically |
| // each time. |
| //--------------------------- |
| HRESULT AddOrRemoveDllsToRegisterList( const ::std::string & DllPath, bool isAdd ) |
| { |
| char DllsToRegisterList[4096]; |
| if (QueryRegistryKey(HKEY_LOCAL_MACHINE, |
| INDEXING_FILTER_DLLSTOREGISTER, |
| "DLLsToRegister", |
| DllsToRegisterList, |
| 4096)) |
| { |
| char * pChar = DllsToRegisterList; |
| for ( ; *pChar != '\0' || *(pChar +1) != '\0'; pChar++) |
| if ( *pChar == '\0') |
| *pChar = ';'; |
| *pChar = ';'; |
| *(pChar+1) = '\0'; |
| |
| ::std::string DllList(DllsToRegisterList); |
| if ( ( isAdd )&&( DllList.find( DllPath ) == ::std::string::npos ) ) |
| DllList.append( DllPath ); |
| else if ( ( !isAdd )&&( DllList.find( DllPath ) != ::std::string::npos ) ) |
| DllList.erase( DllList.find( DllPath )-1, DllPath.length()+1 ); |
| else |
| return S_OK; |
| |
| pChar = DllsToRegisterList; |
| for ( size_t nChar = 0; nChar < DllList.length(); pChar++,nChar++) |
| { |
| if ( DllList[nChar] == ';') |
| *pChar = '\0'; |
| else |
| *pChar = DllList[nChar]; |
| } |
| *pChar = *( pChar+1 ) ='\0'; |
| |
| HKEY hSubKey; |
| int rc = RegCreateKeyExA(HKEY_LOCAL_MACHINE, |
| INDEXING_FILTER_DLLSTOREGISTER, |
| 0, |
| "", |
| REG_OPTION_NON_VOLATILE, |
| KEY_WRITE, |
| 0, |
| &hSubKey, |
| 0); |
| |
| if (ERROR_SUCCESS == rc) |
| { |
| rc = RegSetValueExA( hSubKey, |
| "DLLsToRegister", |
| 0, |
| REG_MULTI_SZ, |
| reinterpret_cast<const BYTE*>(DllsToRegisterList), |
| DllList.length() + 2); |
| |
| RegCloseKey(hSubKey); |
| } |
| |
| return (ERROR_SUCCESS == rc)?S_OK:E_FAIL; |
| } |
| |
| return S_OK; |
| } |
| |
| } // namespace /* private */ |
| |
| STDAPI DllRegisterServer() |
| { |
| /* |
| TCHAR ModuleFileName[MAX_PATH]; |
| |
| GetModuleFileName( |
| GetModuleHandle(MODULE_NAME_FILTER), |
| ModuleFileName, |
| sizeof(ModuleFileName)); |
| |
| HRESULT hr = S_OK; |
| |
| |
| // register search handler |
| #ifdef UNICODE |
| if (FAILED(RegisterSearchHandler(WStringToString(ModuleFileName).c_str()))) |
| hr = E_FAIL; |
| if (FAILED(AddOrRemoveDllsToRegisterList(WStringToString(ModuleFileName).c_str(), true))) |
| hr = E_FAIL; |
| #else |
| if (FAILED(RegisterSearchHandler(ModuleFileName))) |
| hr = E_FAIL; |
| if (FAILED(AddOrRemoveDllsToRegisterList(ModuleFileName, true))) |
| hr = E_FAIL; |
| #endif |
| |
| |
| return hr; |
| */ |
| return S_OK; |
| } |
| |
| //--------------------------- |
| // |
| //--------------------------- |
| |
| STDAPI DllUnregisterServer() |
| { |
| /* |
| TCHAR ModuleFileName[MAX_PATH]; |
| |
| GetModuleFileName( |
| GetModuleHandle(MODULE_NAME_FILTER), |
| ModuleFileName, |
| sizeof(ModuleFileName)); |
| |
| HRESULT hr = S_OK; |
| |
| // unregister search handler |
| if (FAILED(UnregisterSearchHandler())) |
| hr = E_FAIL; |
| |
| #ifdef UNICODE |
| if (FAILED(AddOrRemoveDllsToRegisterList(WStringToString(ModuleFileName).c_str(),false))) |
| hr = E_FAIL; |
| #else |
| if (FAILED(AddOrRemoveDllsToRegisterList(ModuleFileName, false))) |
| hr = E_FAIL; |
| #endif |
| |
| return hr; |
| */ |
| return S_OK; |
| } |