1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_shell.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir //--------------------------------------------------------------------------
32*cdf0e10cSrcweir //  File:       ooofilt.cxx
33*cdf0e10cSrcweir //
34*cdf0e10cSrcweir //  Contents:   Filter Implementation for OpenOffice.Org Document using
35*cdf0e10cSrcweir //              Indexing Service
36*cdf0e10cSrcweir //
37*cdf0e10cSrcweir //  Summary:    The OpenOffice.org filter reads OpenOffice.org files (with the
38*cdf0e10cSrcweir //              extension .sxw .sxi, etc) and extract their content, author,
39*cdf0e10cSrcweir //              keywords,subject,comments and title to be filtered.
40*cdf0e10cSrcweir //
41*cdf0e10cSrcweir //  Platform:   Windows 2000, Windows XP
42*cdf0e10cSrcweir //
43*cdf0e10cSrcweir //--------------------------------------------------------------------------
44*cdf0e10cSrcweir #include "internal/contentreader.hxx"
45*cdf0e10cSrcweir #include "internal/metainforeader.hxx"
46*cdf0e10cSrcweir //#include "internal/utilities.hxx"
47*cdf0e10cSrcweir #include "internal/registry.hxx"
48*cdf0e10cSrcweir #include "internal/fileextensions.hxx"
49*cdf0e10cSrcweir 
50*cdf0e10cSrcweir //--------------------------------------------------------------------------
51*cdf0e10cSrcweir //
52*cdf0e10cSrcweir //  Include file    Purpose
53*cdf0e10cSrcweir //
54*cdf0e10cSrcweir //  windows.h       Win32 declarations
55*cdf0e10cSrcweir //  string.h        string wstring declarations
56*cdf0e10cSrcweir //  filter.h        IFilter interface declarations
57*cdf0e10cSrcweir //  filterr.h       FACILITY_ITF error definitions for IFilter
58*cdf0e10cSrcweir //  ntquery.h       Indexing Service declarations
59*cdf0e10cSrcweir //  assert.h        assertion function.
60*cdf0e10cSrcweir //  ooofilt.hxx     OpenOffice.org filter declarations
61*cdf0e10cSrcweir //  propspec.hxx    PROPSPEC
62*cdf0e10cSrcweir //
63*cdf0e10cSrcweir //--------------------------------------------------------------------------
64*cdf0e10cSrcweir 
65*cdf0e10cSrcweir #if defined _MSC_VER
66*cdf0e10cSrcweir #pragma warning(push, 1)
67*cdf0e10cSrcweir #endif
68*cdf0e10cSrcweir #include <windows.h>
69*cdf0e10cSrcweir #if defined _MSC_VER
70*cdf0e10cSrcweir #pragma warning(pop)
71*cdf0e10cSrcweir #endif
72*cdf0e10cSrcweir #include <string.h>
73*cdf0e10cSrcweir #include <filter.h>
74*cdf0e10cSrcweir #include <filterr.h>
75*cdf0e10cSrcweir #include <ntquery.h>
76*cdf0e10cSrcweir #include "assert.h"
77*cdf0e10cSrcweir #include "ooofilt.hxx"
78*cdf0e10cSrcweir #include <objidl.h>
79*cdf0e10cSrcweir #include <stdio.h>
80*cdf0e10cSrcweir #include "propspec.hxx"
81*cdf0e10cSrcweir #ifdef __MINGW32__
82*cdf0e10cSrcweir #include <algorithm>
83*cdf0e10cSrcweir using ::std::min;
84*cdf0e10cSrcweir #endif
85*cdf0e10cSrcweir 
86*cdf0e10cSrcweir #include "internal/stream_helper.hxx"
87*cdf0e10cSrcweir 
88*cdf0e10cSrcweir //C-------------------------------------------------------------------------
89*cdf0e10cSrcweir //
90*cdf0e10cSrcweir //  Class:      COooFilter
91*cdf0e10cSrcweir //
92*cdf0e10cSrcweir //  Summary:    Implements OpenOffice.org filter class
93*cdf0e10cSrcweir //
94*cdf0e10cSrcweir //--------------------------------------------------------------------------
95*cdf0e10cSrcweir //M-------------------------------------------------------------------------
96*cdf0e10cSrcweir //
97*cdf0e10cSrcweir //  Method:     COooFilter::COooFilter
98*cdf0e10cSrcweir //
99*cdf0e10cSrcweir //  Summary:    Class constructor
100*cdf0e10cSrcweir //
101*cdf0e10cSrcweir //  Arguments:  void
102*cdf0e10cSrcweir //
103*cdf0e10cSrcweir //  Purpose:    Manages global instance count
104*cdf0e10cSrcweir //
105*cdf0e10cSrcweir //--------------------------------------------------------------------------
106*cdf0e10cSrcweir COooFilter::COooFilter() :
107*cdf0e10cSrcweir     m_lRefs(1),
108*cdf0e10cSrcweir     m_pContentReader(NULL),
109*cdf0e10cSrcweir     m_pMetaInfoReader(NULL),
110*cdf0e10cSrcweir     m_eState(FilteringContent),
111*cdf0e10cSrcweir     m_ulUnicodeBufferLen(0),
112*cdf0e10cSrcweir     m_ulUnicodeCharsRead(0),
113*cdf0e10cSrcweir     m_ulPropertyNum(0),
114*cdf0e10cSrcweir     m_ulCurrentPropertyNum(0),
115*cdf0e10cSrcweir     m_ulChunkID(1),
116*cdf0e10cSrcweir     m_fContents(FALSE),
117*cdf0e10cSrcweir     m_fEof(FALSE),
118*cdf0e10cSrcweir     m_ChunkPosition(0),
119*cdf0e10cSrcweir     m_cAttributes(0),
120*cdf0e10cSrcweir     m_pAttributes(0),
121*cdf0e10cSrcweir 	m_pStream(NULL)
122*cdf0e10cSrcweir 
123*cdf0e10cSrcweir {
124*cdf0e10cSrcweir     InterlockedIncrement( &g_lInstances );
125*cdf0e10cSrcweir }
126*cdf0e10cSrcweir //M-------------------------------------------------------------------------
127*cdf0e10cSrcweir //
128*cdf0e10cSrcweir //  Method:     COooFilter::~COooFilter
129*cdf0e10cSrcweir //
130*cdf0e10cSrcweir //  Summary:    Class destructor
131*cdf0e10cSrcweir //
132*cdf0e10cSrcweir //  Arguments:  void
133*cdf0e10cSrcweir //
134*cdf0e10cSrcweir //  Purpose:    Manages global instance count and file handle
135*cdf0e10cSrcweir //
136*cdf0e10cSrcweir //--------------------------------------------------------------------------
137*cdf0e10cSrcweir COooFilter::~COooFilter()
138*cdf0e10cSrcweir {
139*cdf0e10cSrcweir     delete [] m_pAttributes;
140*cdf0e10cSrcweir 
141*cdf0e10cSrcweir     if (m_pContentReader)
142*cdf0e10cSrcweir         delete m_pContentReader;
143*cdf0e10cSrcweir     if (m_pMetaInfoReader)
144*cdf0e10cSrcweir         delete m_pMetaInfoReader;
145*cdf0e10cSrcweir 
146*cdf0e10cSrcweir     InterlockedDecrement( &g_lInstances );
147*cdf0e10cSrcweir }
148*cdf0e10cSrcweir 
149*cdf0e10cSrcweir //M-------------------------------------------------------------------------
150*cdf0e10cSrcweir //
151*cdf0e10cSrcweir //  Method:     COooFilter::QueryInterface      (IUnknown::QueryInterface)
152*cdf0e10cSrcweir //
153*cdf0e10cSrcweir //  Summary:    Queries for requested interface
154*cdf0e10cSrcweir //
155*cdf0e10cSrcweir //  Arguments:  riid
156*cdf0e10cSrcweir //              [in] Reference IID of requested interface
157*cdf0e10cSrcweir //              ppvObject
158*cdf0e10cSrcweir //              [out] Address that receives requested interface pointer
159*cdf0e10cSrcweir //
160*cdf0e10cSrcweir //  Returns:    S_OK
161*cdf0e10cSrcweir //              Interface is supported
162*cdf0e10cSrcweir //              E_NOINTERFACE
163*cdf0e10cSrcweir //              Interface is not supported
164*cdf0e10cSrcweir //
165*cdf0e10cSrcweir //--------------------------------------------------------------------------
166*cdf0e10cSrcweir SCODE STDMETHODCALLTYPE COooFilter::QueryInterface(
167*cdf0e10cSrcweir     REFIID riid,
168*cdf0e10cSrcweir     void  ** ppvObject)
169*cdf0e10cSrcweir {
170*cdf0e10cSrcweir     IUnknown *pUnkTemp = 0;
171*cdf0e10cSrcweir     if ( IID_IFilter == riid )
172*cdf0e10cSrcweir         pUnkTemp = (IUnknown *)(IFilter *)this;
173*cdf0e10cSrcweir     else if ( IID_IPersistFile == riid )
174*cdf0e10cSrcweir         pUnkTemp = (IUnknown *)(IPersistFile *)this;
175*cdf0e10cSrcweir     else if ( IID_IPersist == riid )
176*cdf0e10cSrcweir         pUnkTemp = (IUnknown *)(IPersist *)(IPersistFile *)this;
177*cdf0e10cSrcweir 	else if (IID_IPersistStream == riid)
178*cdf0e10cSrcweir 		pUnkTemp = (IUnknown *)(IPersistStream *)this;
179*cdf0e10cSrcweir     else if ( IID_IUnknown == riid )
180*cdf0e10cSrcweir         pUnkTemp = (IUnknown *)(IPersist *)(IPersistFile *)this;
181*cdf0e10cSrcweir     else
182*cdf0e10cSrcweir     {
183*cdf0e10cSrcweir         *ppvObject = NULL;
184*cdf0e10cSrcweir         return E_NOINTERFACE;
185*cdf0e10cSrcweir     }
186*cdf0e10cSrcweir     *ppvObject = (void  *)pUnkTemp;
187*cdf0e10cSrcweir     pUnkTemp->AddRef();
188*cdf0e10cSrcweir     return S_OK;
189*cdf0e10cSrcweir }
190*cdf0e10cSrcweir //M-------------------------------------------------------------------------
191*cdf0e10cSrcweir //
192*cdf0e10cSrcweir //  Method:     COooFilter::AddRef              (IUnknown::AddRef)
193*cdf0e10cSrcweir //
194*cdf0e10cSrcweir //  Summary:    Increments interface refcount
195*cdf0e10cSrcweir //
196*cdf0e10cSrcweir //  Arguments:  void
197*cdf0e10cSrcweir //
198*cdf0e10cSrcweir //  Returns:    Value of incremented interface refcount
199*cdf0e10cSrcweir //
200*cdf0e10cSrcweir //--------------------------------------------------------------------------
201*cdf0e10cSrcweir ULONG STDMETHODCALLTYPE COooFilter::AddRef()
202*cdf0e10cSrcweir {
203*cdf0e10cSrcweir     return InterlockedIncrement( &m_lRefs );
204*cdf0e10cSrcweir }
205*cdf0e10cSrcweir //M-------------------------------------------------------------------------
206*cdf0e10cSrcweir //
207*cdf0e10cSrcweir //  Method:     COooFilter::Release             (IUnknown::Release)
208*cdf0e10cSrcweir //
209*cdf0e10cSrcweir //  Summary:    Decrements interface refcount, deleting if unreferenced
210*cdf0e10cSrcweir //
211*cdf0e10cSrcweir //  Arguments:  void
212*cdf0e10cSrcweir //
213*cdf0e10cSrcweir //  Returns:    Value of decremented interface refcount
214*cdf0e10cSrcweir //
215*cdf0e10cSrcweir //--------------------------------------------------------------------------
216*cdf0e10cSrcweir ULONG STDMETHODCALLTYPE COooFilter::Release()
217*cdf0e10cSrcweir {
218*cdf0e10cSrcweir     ULONG ulTmp = InterlockedDecrement( &m_lRefs );
219*cdf0e10cSrcweir 
220*cdf0e10cSrcweir     if ( 0 == ulTmp )
221*cdf0e10cSrcweir         delete this;
222*cdf0e10cSrcweir     return ulTmp;
223*cdf0e10cSrcweir }
224*cdf0e10cSrcweir //M-------------------------------------------------------------------------
225*cdf0e10cSrcweir //
226*cdf0e10cSrcweir //  Method:     COooFilter::Init                (IFilter::Init)
227*cdf0e10cSrcweir //
228*cdf0e10cSrcweir //  Summary:    Initializes OpenOffice.org filter instance
229*cdf0e10cSrcweir //
230*cdf0e10cSrcweir //  Arguments:  grfFlags
231*cdf0e10cSrcweir //                  [in] Flags for filter behavior
232*cdf0e10cSrcweir //              cAttributes
233*cdf0e10cSrcweir //                  [in] Number attributes in array aAttributes
234*cdf0e10cSrcweir //              aAttributes
235*cdf0e10cSrcweir //                  [in] Array of requested attribute strings
236*cdf0e10cSrcweir //              pFlags
237*cdf0e10cSrcweir //                  [out] Pointer to return flags for additional properties
238*cdf0e10cSrcweir //
239*cdf0e10cSrcweir //  Returns:    S_OK
240*cdf0e10cSrcweir //                  Initialization succeeded
241*cdf0e10cSrcweir //              E_FAIL
242*cdf0e10cSrcweir //                  File not previously loaded
243*cdf0e10cSrcweir //              E_INVALIDARG
244*cdf0e10cSrcweir //                  Count and contents of attributes do not agree
245*cdf0e10cSrcweir //              FILTER_E_ACCESS
246*cdf0e10cSrcweir //                  Unable to access file to be filtered
247*cdf0e10cSrcweir //              FILTER_E_PASSWORD
248*cdf0e10cSrcweir //                  (not implemented)
249*cdf0e10cSrcweir //
250*cdf0e10cSrcweir //--------------------------------------------------------------------------
251*cdf0e10cSrcweir const int COUNT_ATTRIBUTES = 5;
252*cdf0e10cSrcweir 
253*cdf0e10cSrcweir SCODE STDMETHODCALLTYPE COooFilter::Init(
254*cdf0e10cSrcweir     ULONG grfFlags,
255*cdf0e10cSrcweir     ULONG cAttributes,
256*cdf0e10cSrcweir     FULLPROPSPEC const * aAttributes,
257*cdf0e10cSrcweir     ULONG * pFlags)
258*cdf0e10cSrcweir {
259*cdf0e10cSrcweir     // Enumerate OLE properties, since any NTFS file can have them
260*cdf0e10cSrcweir     *pFlags = IFILTER_FLAGS_OLE_PROPERTIES;
261*cdf0e10cSrcweir     try
262*cdf0e10cSrcweir     {
263*cdf0e10cSrcweir         m_fContents = FALSE;
264*cdf0e10cSrcweir         m_ulPropertyNum = 0;
265*cdf0e10cSrcweir         m_ulCurrentPropertyNum = 0;
266*cdf0e10cSrcweir         if ( m_cAttributes > 0 )
267*cdf0e10cSrcweir         {
268*cdf0e10cSrcweir             delete[] m_pAttributes;
269*cdf0e10cSrcweir             m_pAttributes = 0;
270*cdf0e10cSrcweir             m_cAttributes = 0;
271*cdf0e10cSrcweir         }
272*cdf0e10cSrcweir         if( 0 < cAttributes )
273*cdf0e10cSrcweir         {
274*cdf0e10cSrcweir             // Filter properties specified in aAttributes
275*cdf0e10cSrcweir             if ( 0 == aAttributes )
276*cdf0e10cSrcweir                 return E_INVALIDARG;
277*cdf0e10cSrcweir             m_pAttributes = new CFullPropSpec[cAttributes];
278*cdf0e10cSrcweir             m_cAttributes = cAttributes;
279*cdf0e10cSrcweir             // Is caller want to filter contents?
280*cdf0e10cSrcweir             CFullPropSpec *pAttrib = (CFullPropSpec *) aAttributes;
281*cdf0e10cSrcweir             ULONG ulNumAttr;
282*cdf0e10cSrcweir             for ( ulNumAttr = 0 ; ulNumAttr < cAttributes; ulNumAttr++ )
283*cdf0e10cSrcweir             {
284*cdf0e10cSrcweir                 if ( pAttrib[ulNumAttr].IsPropertyPropid() &&
285*cdf0e10cSrcweir                      pAttrib[ulNumAttr].GetPropertyPropid() == PID_STG_CONTENTS &&
286*cdf0e10cSrcweir                      pAttrib[ulNumAttr].GetPropSet() == guidStorage )
287*cdf0e10cSrcweir                 {
288*cdf0e10cSrcweir                     m_fContents = TRUE;
289*cdf0e10cSrcweir                 }
290*cdf0e10cSrcweir                 // save the requested properties.
291*cdf0e10cSrcweir                 m_pAttributes[ulNumAttr] = pAttrib[ulNumAttr];
292*cdf0e10cSrcweir             }
293*cdf0e10cSrcweir         }
294*cdf0e10cSrcweir         else if ( grfFlags & IFILTER_INIT_APPLY_INDEX_ATTRIBUTES )
295*cdf0e10cSrcweir         {
296*cdf0e10cSrcweir             // Filter contents and all pseudo-properties
297*cdf0e10cSrcweir             m_fContents = TRUE;
298*cdf0e10cSrcweir 
299*cdf0e10cSrcweir             m_pAttributes = new CFullPropSpec[COUNT_ATTRIBUTES];
300*cdf0e10cSrcweir             m_cAttributes = COUNT_ATTRIBUTES;
301*cdf0e10cSrcweir             m_pAttributes[0].SetPropSet( FMTID_SummaryInformation );
302*cdf0e10cSrcweir             m_pAttributes[0].SetProperty( PIDSI_AUTHOR );
303*cdf0e10cSrcweir             m_pAttributes[1].SetPropSet( FMTID_SummaryInformation );
304*cdf0e10cSrcweir             m_pAttributes[1].SetProperty( PIDSI_TITLE );
305*cdf0e10cSrcweir             m_pAttributes[2].SetPropSet( FMTID_SummaryInformation );
306*cdf0e10cSrcweir             m_pAttributes[2].SetProperty( PIDSI_SUBJECT );
307*cdf0e10cSrcweir             m_pAttributes[3].SetPropSet( FMTID_SummaryInformation );
308*cdf0e10cSrcweir             m_pAttributes[3].SetProperty( PIDSI_KEYWORDS );
309*cdf0e10cSrcweir             m_pAttributes[4].SetPropSet( FMTID_SummaryInformation );
310*cdf0e10cSrcweir             m_pAttributes[4].SetProperty( PIDSI_COMMENTS );
311*cdf0e10cSrcweir         }
312*cdf0e10cSrcweir         else if ( 0 == grfFlags )
313*cdf0e10cSrcweir         {
314*cdf0e10cSrcweir             // Filter only contents
315*cdf0e10cSrcweir             m_fContents = TRUE;
316*cdf0e10cSrcweir         }
317*cdf0e10cSrcweir         else
318*cdf0e10cSrcweir             m_fContents = FALSE;
319*cdf0e10cSrcweir         // Re-initialize
320*cdf0e10cSrcweir         if ( m_fContents )
321*cdf0e10cSrcweir         {
322*cdf0e10cSrcweir             m_fEof = FALSE;
323*cdf0e10cSrcweir             m_eState = FilteringContent;
324*cdf0e10cSrcweir             m_ulUnicodeCharsRead = 0;
325*cdf0e10cSrcweir             m_ChunkPosition = 0;
326*cdf0e10cSrcweir         }
327*cdf0e10cSrcweir         else
328*cdf0e10cSrcweir         {
329*cdf0e10cSrcweir             m_fEof = TRUE;
330*cdf0e10cSrcweir             m_eState = FilteringProperty;
331*cdf0e10cSrcweir         }
332*cdf0e10cSrcweir         m_ulChunkID = 1;
333*cdf0e10cSrcweir     }
334*cdf0e10cSrcweir     catch (const std::exception&)
335*cdf0e10cSrcweir     {
336*cdf0e10cSrcweir         return E_FAIL;
337*cdf0e10cSrcweir     }
338*cdf0e10cSrcweir 
339*cdf0e10cSrcweir     return S_OK;
340*cdf0e10cSrcweir }
341*cdf0e10cSrcweir //M-------------------------------------------------------------------------
342*cdf0e10cSrcweir //
343*cdf0e10cSrcweir //  Method:     COooFilter::GetChunk            (IFilter::GetChunk)
344*cdf0e10cSrcweir //
345*cdf0e10cSrcweir //  Summary:    Gets the next chunk
346*cdf0e10cSrcweir //
347*cdf0e10cSrcweir //  Arguments:  ppStat
348*cdf0e10cSrcweir //                  [out] Pointer to description of current chunk
349*cdf0e10cSrcweir //  Returns:    S_OK
350*cdf0e10cSrcweir //                  Chunk was successfully retrieved
351*cdf0e10cSrcweir //              E_FAIL
352*cdf0e10cSrcweir //                  Character conversion failed
353*cdf0e10cSrcweir //              FILTER_E_ACCESS
354*cdf0e10cSrcweir //                  General access failure occurred
355*cdf0e10cSrcweir //              FILTER_E_END_OF_CHUNKS
356*cdf0e10cSrcweir //                  Previous chunk was the last chunk
357*cdf0e10cSrcweir //              FILTER_E_EMBEDDING_UNAVAILABLE
358*cdf0e10cSrcweir //                  (not implemented)
359*cdf0e10cSrcweir //              FILTER_E_LINK_UNAVAILABLE
360*cdf0e10cSrcweir //                  (not implemented)
361*cdf0e10cSrcweir //              FILTER_E_PASSWORD
362*cdf0e10cSrcweir //                  (not implemented)
363*cdf0e10cSrcweir //
364*cdf0e10cSrcweir //--------------------------------------------------------------------------
365*cdf0e10cSrcweir SCODE STDMETHODCALLTYPE COooFilter::GetChunk(STAT_CHUNK * pStat)
366*cdf0e10cSrcweir {
367*cdf0e10cSrcweir     for(;;)
368*cdf0e10cSrcweir     {
369*cdf0e10cSrcweir         switch ( m_eState )
370*cdf0e10cSrcweir         {
371*cdf0e10cSrcweir         case FilteringContent:
372*cdf0e10cSrcweir         {
373*cdf0e10cSrcweir             // Read Unicodes from buffer.
374*cdf0e10cSrcweir             if( m_ChunkPosition == m_pContentReader ->getChunkBuffer().size() )
375*cdf0e10cSrcweir             {
376*cdf0e10cSrcweir                 m_ulUnicodeBufferLen=0;
377*cdf0e10cSrcweir                 m_fEof = TRUE;
378*cdf0e10cSrcweir             }
379*cdf0e10cSrcweir 
380*cdf0e10cSrcweir             if ( !m_fContents || m_fEof )
381*cdf0e10cSrcweir             {
382*cdf0e10cSrcweir                 m_eState = FilteringProperty;
383*cdf0e10cSrcweir                 continue;
384*cdf0e10cSrcweir             }
385*cdf0e10cSrcweir             m_pwsBuffer = m_pContentReader -> getChunkBuffer()[m_ChunkPosition].second;
386*cdf0e10cSrcweir             m_ulUnicodeBufferLen = m_pwsBuffer.length();
387*cdf0e10cSrcweir             DWORD ChunkLCID = LocaleSetToLCID( m_pContentReader -> getChunkBuffer()[m_ChunkPosition].first );
388*cdf0e10cSrcweir             // Set chunk description
389*cdf0e10cSrcweir             pStat->idChunk   = m_ulChunkID;
390*cdf0e10cSrcweir             pStat->breakType = CHUNK_NO_BREAK;
391*cdf0e10cSrcweir             pStat->flags     = CHUNK_TEXT;
392*cdf0e10cSrcweir             pStat->locale    = ChunkLCID;
393*cdf0e10cSrcweir             pStat->attribute.guidPropSet       = guidStorage;
394*cdf0e10cSrcweir             pStat->attribute.psProperty.ulKind = PRSPEC_PROPID;
395*cdf0e10cSrcweir             pStat->attribute.psProperty.propid = PID_STG_CONTENTS;
396*cdf0e10cSrcweir             pStat->idChunkSource  = m_ulChunkID;
397*cdf0e10cSrcweir             pStat->cwcStartSource = 0;
398*cdf0e10cSrcweir             pStat->cwcLenSource   = 0;
399*cdf0e10cSrcweir             m_ulUnicodeCharsRead = 0;
400*cdf0e10cSrcweir             m_ulChunkID++;
401*cdf0e10cSrcweir             m_ChunkPosition++;
402*cdf0e10cSrcweir             return S_OK;
403*cdf0e10cSrcweir         }
404*cdf0e10cSrcweir         case FilteringProperty:
405*cdf0e10cSrcweir         {
406*cdf0e10cSrcweir             if ( m_cAttributes ==  0 )
407*cdf0e10cSrcweir                 return FILTER_E_END_OF_CHUNKS;
408*cdf0e10cSrcweir             while(  !( ( m_pAttributes[m_ulPropertyNum].IsPropertyPropid() ) &&
409*cdf0e10cSrcweir                        ( m_pAttributes[m_ulPropertyNum].GetPropSet() == FMTID_SummaryInformation ) )||
410*cdf0e10cSrcweir                      ( ( m_pAttributes[m_ulPropertyNum].GetPropertyPropid() != PIDSI_AUTHOR ) &&
411*cdf0e10cSrcweir                        ( m_pAttributes[m_ulPropertyNum].GetPropertyPropid() != PIDSI_TITLE ) &&
412*cdf0e10cSrcweir                        ( m_pAttributes[m_ulPropertyNum].GetPropertyPropid() != PIDSI_SUBJECT ) &&
413*cdf0e10cSrcweir                        ( m_pAttributes[m_ulPropertyNum].GetPropertyPropid() != PIDSI_KEYWORDS ) &&
414*cdf0e10cSrcweir                        ( m_pAttributes[m_ulPropertyNum].GetPropertyPropid() != PIDSI_COMMENTS ) ) )
415*cdf0e10cSrcweir             {
416*cdf0e10cSrcweir                 if ( m_ulPropertyNum <  m_cAttributes )
417*cdf0e10cSrcweir                     m_ulPropertyNum++;
418*cdf0e10cSrcweir                 else
419*cdf0e10cSrcweir                     break;
420*cdf0e10cSrcweir             }
421*cdf0e10cSrcweir             if ( m_ulPropertyNum ==  m_cAttributes)
422*cdf0e10cSrcweir                 return FILTER_E_END_OF_CHUNKS;
423*cdf0e10cSrcweir             else
424*cdf0e10cSrcweir             {
425*cdf0e10cSrcweir                 // Set chunk description
426*cdf0e10cSrcweir                 pStat->idChunk = m_ulChunkID;
427*cdf0e10cSrcweir                 pStat->breakType = CHUNK_EOS;
428*cdf0e10cSrcweir                 pStat->flags = CHUNK_VALUE;
429*cdf0e10cSrcweir                 pStat->locale = GetSystemDefaultLCID();
430*cdf0e10cSrcweir                 pStat->attribute.guidPropSet = FMTID_SummaryInformation;
431*cdf0e10cSrcweir                 pStat->attribute.psProperty.ulKind = PRSPEC_PROPID;
432*cdf0e10cSrcweir                 pStat->attribute.psProperty.propid = m_pAttributes[m_ulPropertyNum].GetPropertyPropid();
433*cdf0e10cSrcweir                 pStat->idChunkSource = m_ulChunkID;
434*cdf0e10cSrcweir                 pStat->cwcStartSource = 0;
435*cdf0e10cSrcweir                 pStat->cwcLenSource = 0;
436*cdf0e10cSrcweir                 m_ulCurrentPropertyNum = m_ulPropertyNum;
437*cdf0e10cSrcweir                 m_ulPropertyNum++;
438*cdf0e10cSrcweir                 m_ulChunkID++;
439*cdf0e10cSrcweir                 return S_OK;
440*cdf0e10cSrcweir             }
441*cdf0e10cSrcweir         }
442*cdf0e10cSrcweir         default:
443*cdf0e10cSrcweir             return E_FAIL;
444*cdf0e10cSrcweir         }//switch(...)
445*cdf0e10cSrcweir     }//for(;;)
446*cdf0e10cSrcweir }
447*cdf0e10cSrcweir //M-------------------------------------------------------------------------
448*cdf0e10cSrcweir //
449*cdf0e10cSrcweir //  Method:     COooFilter::GetText             (IFilter::GetText)
450*cdf0e10cSrcweir //
451*cdf0e10cSrcweir //  Summary:    Retrieves UNICODE text for index
452*cdf0e10cSrcweir //
453*cdf0e10cSrcweir //  Arguments:  pcwcBuffer
454*cdf0e10cSrcweir //                  [in] Pointer to size of UNICODE buffer
455*cdf0e10cSrcweir //                  [out] Pointer to count of UNICODE characters returned
456*cdf0e10cSrcweir //              awcBuffer
457*cdf0e10cSrcweir //                  [out] Pointer to buffer to receive UNICODE text
458*cdf0e10cSrcweir //
459*cdf0e10cSrcweir //  Returns:    S_OK
460*cdf0e10cSrcweir //                  Text successfully retrieved, but text remains in chunk
461*cdf0e10cSrcweir //              FILTER_E_NO_MORE_TEXT
462*cdf0e10cSrcweir //                  All of the text in the current chunk has been returned
463*cdf0e10cSrcweir //              FILTER_S_LAST_TEXT
464*cdf0e10cSrcweir //                  Next call to GetText will return FILTER_E_NO_MORE_TEXT
465*cdf0e10cSrcweir //
466*cdf0e10cSrcweir //--------------------------------------------------------------------------
467*cdf0e10cSrcweir SCODE STDMETHODCALLTYPE COooFilter::GetText(ULONG * pcwcBuffer, WCHAR * awcBuffer)
468*cdf0e10cSrcweir {
469*cdf0e10cSrcweir     switch ( m_eState )
470*cdf0e10cSrcweir     {
471*cdf0e10cSrcweir     case FilteringProperty:
472*cdf0e10cSrcweir         return FILTER_E_NO_TEXT;
473*cdf0e10cSrcweir     case FilteringContent:
474*cdf0e10cSrcweir     {
475*cdf0e10cSrcweir         if ( !m_fContents || 0 == m_ulUnicodeBufferLen )
476*cdf0e10cSrcweir         {
477*cdf0e10cSrcweir             *pcwcBuffer = 0;
478*cdf0e10cSrcweir             return FILTER_E_NO_MORE_TEXT;
479*cdf0e10cSrcweir         }
480*cdf0e10cSrcweir         // Copy UNICODE characters in chunk buffer to output UNICODE buffer
481*cdf0e10cSrcweir         ULONG ulToCopy = min( *pcwcBuffer, m_ulUnicodeBufferLen - m_ulUnicodeCharsRead );
482*cdf0e10cSrcweir         ZeroMemory(awcBuffer, sizeof(awcBuffer));
483*cdf0e10cSrcweir         wmemcpy( awcBuffer, m_pwsBuffer.c_str() + m_ulUnicodeCharsRead, ulToCopy );
484*cdf0e10cSrcweir         m_ulUnicodeCharsRead += ulToCopy;
485*cdf0e10cSrcweir         *pcwcBuffer = ulToCopy;
486*cdf0e10cSrcweir         if ( m_ulUnicodeBufferLen == m_ulUnicodeCharsRead )
487*cdf0e10cSrcweir         {
488*cdf0e10cSrcweir             m_ulUnicodeCharsRead = 0;
489*cdf0e10cSrcweir             m_ulUnicodeBufferLen = 0;
490*cdf0e10cSrcweir             return FILTER_S_LAST_TEXT;
491*cdf0e10cSrcweir         }
492*cdf0e10cSrcweir         return S_OK;
493*cdf0e10cSrcweir     }
494*cdf0e10cSrcweir     default:
495*cdf0e10cSrcweir         return E_FAIL;
496*cdf0e10cSrcweir     }
497*cdf0e10cSrcweir }
498*cdf0e10cSrcweir //M-------------------------------------------------------------------------
499*cdf0e10cSrcweir //
500*cdf0e10cSrcweir //  Method:     GetMetaInfoNameFromPropertyId
501*cdf0e10cSrcweir //
502*cdf0e10cSrcweir //  Summary:    helper function to convert PropertyID into respective
503*cdf0e10cSrcweir //              MetaInfo names.
504*cdf0e10cSrcweir //
505*cdf0e10cSrcweir //  Arguments:  ulPropID
506*cdf0e10cSrcweir //                  [in] property ID
507*cdf0e10cSrcweir //
508*cdf0e10cSrcweir //  Returns:    corresponding metainfo names.
509*cdf0e10cSrcweir //
510*cdf0e10cSrcweir //--------------------------------------------------------------------------
511*cdf0e10cSrcweir 
512*cdf0e10cSrcweir ::std::wstring GetMetaInfoNameFromPropertyId( ULONG ulPropID )
513*cdf0e10cSrcweir {
514*cdf0e10cSrcweir     switch ( ulPropID )
515*cdf0e10cSrcweir     {
516*cdf0e10cSrcweir         case PIDSI_AUTHOR:   return META_INFO_AUTHOR;
517*cdf0e10cSrcweir         case PIDSI_TITLE:    return META_INFO_TITLE;
518*cdf0e10cSrcweir         case PIDSI_SUBJECT:  return META_INFO_SUBJECT;
519*cdf0e10cSrcweir         case PIDSI_KEYWORDS: return META_INFO_KEYWORDS;
520*cdf0e10cSrcweir         case PIDSI_COMMENTS: return META_INFO_DESCRIPTION;
521*cdf0e10cSrcweir         default:             return EMPTY_STRING;
522*cdf0e10cSrcweir     }
523*cdf0e10cSrcweir }
524*cdf0e10cSrcweir //M-------------------------------------------------------------------------
525*cdf0e10cSrcweir //
526*cdf0e10cSrcweir //  Method:     COooFilter::GetValue            (IFilter::GetValue)
527*cdf0e10cSrcweir //
528*cdf0e10cSrcweir //  Summary:    Retrieves properites for index
529*cdf0e10cSrcweir //
530*cdf0e10cSrcweir //  Arguments:  ppPropValue
531*cdf0e10cSrcweir //                  [out] Address that receives pointer to property value
532*cdf0e10cSrcweir //
533*cdf0e10cSrcweir //  Returns:    FILTER_E_NO_VALUES
534*cdf0e10cSrcweir //                  Always
535*cdf0e10cSrcweir //              FILTER_E_NO_MORE_VALUES
536*cdf0e10cSrcweir //                  (not implemented)
537*cdf0e10cSrcweir //
538*cdf0e10cSrcweir //--------------------------------------------------------------------------
539*cdf0e10cSrcweir 
540*cdf0e10cSrcweir SCODE STDMETHODCALLTYPE COooFilter::GetValue(PROPVARIANT ** ppPropValue)
541*cdf0e10cSrcweir {
542*cdf0e10cSrcweir     if (m_eState == FilteringContent)
543*cdf0e10cSrcweir         return FILTER_E_NO_VALUES;
544*cdf0e10cSrcweir     else if (m_eState == FilteringProperty)
545*cdf0e10cSrcweir     {
546*cdf0e10cSrcweir         if ( m_cAttributes == 0 || ( m_ulCurrentPropertyNum == m_ulPropertyNum ) )
547*cdf0e10cSrcweir             return FILTER_E_NO_MORE_VALUES;
548*cdf0e10cSrcweir         PROPVARIANT *pPropVar = (PROPVARIANT *) CoTaskMemAlloc( sizeof (PROPVARIANT) );
549*cdf0e10cSrcweir         if ( pPropVar == 0 )
550*cdf0e10cSrcweir             return E_OUTOFMEMORY;
551*cdf0e10cSrcweir         ::std::wstring wsTagName= GetMetaInfoNameFromPropertyId( m_pAttributes[m_ulCurrentPropertyNum].GetPropertyPropid() );
552*cdf0e10cSrcweir         if ( wsTagName == EMPTY_STRING )
553*cdf0e10cSrcweir             return FILTER_E_NO_VALUES;
554*cdf0e10cSrcweir 		::std::wstring wsTagData = m_pMetaInfoReader->getTagData(wsTagName);
555*cdf0e10cSrcweir 		pPropVar->vt = VT_LPWSTR;
556*cdf0e10cSrcweir 		size_t cw = wsTagData.length() + 1; // reserve one for the '\0'
557*cdf0e10cSrcweir 		pPropVar->pwszVal = static_cast<WCHAR*>( CoTaskMemAlloc(cw*sizeof(WCHAR)) );
558*cdf0e10cSrcweir 		if (pPropVar->pwszVal == 0)
559*cdf0e10cSrcweir 		{
560*cdf0e10cSrcweir 			CoTaskMemFree(pPropVar);
561*cdf0e10cSrcweir 			return E_OUTOFMEMORY;
562*cdf0e10cSrcweir 		}
563*cdf0e10cSrcweir 		wmemcpy(pPropVar->pwszVal, wsTagData.c_str(), cw);
564*cdf0e10cSrcweir         *ppPropValue = pPropVar;
565*cdf0e10cSrcweir         m_ulCurrentPropertyNum = m_ulPropertyNum;
566*cdf0e10cSrcweir         return S_OK;
567*cdf0e10cSrcweir     }
568*cdf0e10cSrcweir     else
569*cdf0e10cSrcweir         return E_FAIL;
570*cdf0e10cSrcweir }
571*cdf0e10cSrcweir //M-------------------------------------------------------------------------
572*cdf0e10cSrcweir //
573*cdf0e10cSrcweir //  Method:     COooFilter::BindRegion          (IFilter::BindRegion)
574*cdf0e10cSrcweir //
575*cdf0e10cSrcweir //  Summary:    Creates moniker or other interface for indicated text
576*cdf0e10cSrcweir //
577*cdf0e10cSrcweir //  Arguments:  origPos
578*cdf0e10cSrcweir //                  [in] Description of text location and extent
579*cdf0e10cSrcweir //              riid
580*cdf0e10cSrcweir //                  [in] Reference IID of specified interface
581*cdf0e10cSrcweir //              ppunk
582*cdf0e10cSrcweir //                  [out] Address that receives requested interface pointer
583*cdf0e10cSrcweir //
584*cdf0e10cSrcweir //  Returns:    E_NOTIMPL
585*cdf0e10cSrcweir //                  Always
586*cdf0e10cSrcweir //              FILTER_W_REGION_CLIPPED
587*cdf0e10cSrcweir //                  (not implemented)
588*cdf0e10cSrcweir //
589*cdf0e10cSrcweir //--------------------------------------------------------------------------
590*cdf0e10cSrcweir 
591*cdf0e10cSrcweir SCODE STDMETHODCALLTYPE COooFilter::BindRegion(
592*cdf0e10cSrcweir     FILTERREGION /*origPos*/,
593*cdf0e10cSrcweir     REFIID /*riid*/,
594*cdf0e10cSrcweir     void ** /*ppunk*/)
595*cdf0e10cSrcweir {
596*cdf0e10cSrcweir     // BindRegion is currently reserved for future use
597*cdf0e10cSrcweir     return E_NOTIMPL;
598*cdf0e10cSrcweir }
599*cdf0e10cSrcweir //M-------------------------------------------------------------------------
600*cdf0e10cSrcweir //
601*cdf0e10cSrcweir //  Method:     COooFilter::GetClassID          (IPersist::GetClassID)
602*cdf0e10cSrcweir //
603*cdf0e10cSrcweir //  Summary:    Retrieves the class id of the filter class
604*cdf0e10cSrcweir //
605*cdf0e10cSrcweir //  Arguments:  pClassID
606*cdf0e10cSrcweir //                  [out] Pointer to the class ID of the filter
607*cdf0e10cSrcweir //
608*cdf0e10cSrcweir //  Returns:    S_OK
609*cdf0e10cSrcweir //                  Always
610*cdf0e10cSrcweir //              E_FAIL
611*cdf0e10cSrcweir //                  (not implemented)
612*cdf0e10cSrcweir //--------------------------------------------------------------------------
613*cdf0e10cSrcweir SCODE STDMETHODCALLTYPE COooFilter::GetClassID(CLSID * pClassID)
614*cdf0e10cSrcweir {
615*cdf0e10cSrcweir     *pClassID = CLSID_COooFilter;
616*cdf0e10cSrcweir     return S_OK;
617*cdf0e10cSrcweir }
618*cdf0e10cSrcweir //M-------------------------------------------------------------------------
619*cdf0e10cSrcweir //
620*cdf0e10cSrcweir //  Method:     COooFilter::IsDirty             (IPersistFile::IsDirty)
621*cdf0e10cSrcweir //
622*cdf0e10cSrcweir //  Summary:    Checks whether file has changed since last save
623*cdf0e10cSrcweir //
624*cdf0e10cSrcweir //  Arguments:  void
625*cdf0e10cSrcweir //
626*cdf0e10cSrcweir //  Returns:    S_FALSE
627*cdf0e10cSrcweir //                  Always
628*cdf0e10cSrcweir //              S_OK
629*cdf0e10cSrcweir //                  (not implemented)
630*cdf0e10cSrcweir //
631*cdf0e10cSrcweir //--------------------------------------------------------------------------
632*cdf0e10cSrcweir SCODE STDMETHODCALLTYPE COooFilter::IsDirty()
633*cdf0e10cSrcweir {
634*cdf0e10cSrcweir     // File is opened read-only and never changes
635*cdf0e10cSrcweir     return S_FALSE;
636*cdf0e10cSrcweir }
637*cdf0e10cSrcweir //M-------------------------------------------------------------------------
638*cdf0e10cSrcweir //
639*cdf0e10cSrcweir //  Method:     COooFilter::Load                (IPersistFile::Load)
640*cdf0e10cSrcweir //
641*cdf0e10cSrcweir //  Summary:    Opens and initializes the specified file
642*cdf0e10cSrcweir //
643*cdf0e10cSrcweir //  Arguments:  pszFileName
644*cdf0e10cSrcweir //                  [in] Pointer to zero-terminated string
645*cdf0e10cSrcweir //                       of absolute path of file to open
646*cdf0e10cSrcweir //              dwMode
647*cdf0e10cSrcweir //                  [in] Access mode to open the file
648*cdf0e10cSrcweir //
649*cdf0e10cSrcweir //  Returns:    S_OK
650*cdf0e10cSrcweir //                  File was successfully loaded
651*cdf0e10cSrcweir //              E_OUTOFMEMORY
652*cdf0e10cSrcweir //                  File could not be loaded due to insufficient memory
653*cdf0e10cSrcweir //              E_FAIL
654*cdf0e10cSrcweir //                  (not implemented)
655*cdf0e10cSrcweir //
656*cdf0e10cSrcweir //--------------------------------------------------------------------------
657*cdf0e10cSrcweir SCODE STDMETHODCALLTYPE COooFilter::Load(LPCWSTR pszFileName, DWORD /*dwMode*/)
658*cdf0e10cSrcweir {
659*cdf0e10cSrcweir     // Load just sets the filename for GetChunk to read and ignores the mode
660*cdf0e10cSrcweir     m_pwszFileName = getShortPathName( pszFileName );
661*cdf0e10cSrcweir 
662*cdf0e10cSrcweir     // Open the file previously specified in call to IPersistFile::Load and get content.
663*cdf0e10cSrcweir 	try
664*cdf0e10cSrcweir     {
665*cdf0e10cSrcweir         if (m_pMetaInfoReader)
666*cdf0e10cSrcweir             delete m_pMetaInfoReader;
667*cdf0e10cSrcweir 		m_pMetaInfoReader = new CMetaInfoReader(WStringToString(m_pwszFileName));
668*cdf0e10cSrcweir 
669*cdf0e10cSrcweir 		if (m_pContentReader)
670*cdf0e10cSrcweir 		    delete m_pContentReader;
671*cdf0e10cSrcweir 		m_pContentReader = new CContentReader(WStringToString(m_pwszFileName), m_pMetaInfoReader->getDefaultLocale());
672*cdf0e10cSrcweir     }
673*cdf0e10cSrcweir     catch (const std::exception&)
674*cdf0e10cSrcweir     {
675*cdf0e10cSrcweir         return E_FAIL;
676*cdf0e10cSrcweir     }
677*cdf0e10cSrcweir     return S_OK;
678*cdf0e10cSrcweir }
679*cdf0e10cSrcweir //M-------------------------------------------------------------------------
680*cdf0e10cSrcweir //
681*cdf0e10cSrcweir //  Method:     COooFilter::Save                (IPersistFile::Save)
682*cdf0e10cSrcweir //
683*cdf0e10cSrcweir //  Summary:    Saves a copy of the current file being filtered
684*cdf0e10cSrcweir //
685*cdf0e10cSrcweir //  Arguments:  pszFileName
686*cdf0e10cSrcweir //                  [in] Pointer to zero-terminated string of
687*cdf0e10cSrcweir //                       absolute path of where to save file
688*cdf0e10cSrcweir //              fRemember
689*cdf0e10cSrcweir //                  [in] Whether the saved copy is made the current file
690*cdf0e10cSrcweir //
691*cdf0e10cSrcweir //  Returns:    E_FAIL
692*cdf0e10cSrcweir //                  Always
693*cdf0e10cSrcweir //              S_OK
694*cdf0e10cSrcweir //                  (not implemented)
695*cdf0e10cSrcweir //
696*cdf0e10cSrcweir //--------------------------------------------------------------------------
697*cdf0e10cSrcweir SCODE STDMETHODCALLTYPE COooFilter::Save(LPCWSTR /*pszFileName*/, BOOL /*fRemember*/)
698*cdf0e10cSrcweir {
699*cdf0e10cSrcweir     // File is opened read-only; saving it is an error
700*cdf0e10cSrcweir     return E_FAIL;
701*cdf0e10cSrcweir }
702*cdf0e10cSrcweir //M-------------------------------------------------------------------------
703*cdf0e10cSrcweir //
704*cdf0e10cSrcweir //  Method:     COooFilter::SaveCompleted      (IPersistFile::SaveCompleted)
705*cdf0e10cSrcweir //
706*cdf0e10cSrcweir //  Summary:    Determines whether a file save is completed
707*cdf0e10cSrcweir //
708*cdf0e10cSrcweir //  Arguments:  pszFileName
709*cdf0e10cSrcweir //                  [in] Pointer to zero-terminated string of
710*cdf0e10cSrcweir //                       absolute path where file was previously saved
711*cdf0e10cSrcweir //
712*cdf0e10cSrcweir //  Returns:    S_OK
713*cdf0e10cSrcweir //                  Always
714*cdf0e10cSrcweir //
715*cdf0e10cSrcweir //--------------------------------------------------------------------------
716*cdf0e10cSrcweir SCODE STDMETHODCALLTYPE COooFilter::SaveCompleted(LPCWSTR /*pszFileName*/)
717*cdf0e10cSrcweir {
718*cdf0e10cSrcweir     // File is opened read-only, so "save" is always finished
719*cdf0e10cSrcweir     return S_OK;
720*cdf0e10cSrcweir }
721*cdf0e10cSrcweir 
722*cdf0e10cSrcweir //M-------------------------------------------------------------------------
723*cdf0e10cSrcweir //
724*cdf0e10cSrcweir //  Method:     COooFilter::Load      (IPersistStream::Load)
725*cdf0e10cSrcweir //
726*cdf0e10cSrcweir //  Summary:    Initializes an object from the stream where it was previously saved
727*cdf0e10cSrcweir //
728*cdf0e10cSrcweir //  Arguments:  pStm
729*cdf0e10cSrcweir //                  [in] Pointer to stream from which object should be loaded
730*cdf0e10cSrcweir //
731*cdf0e10cSrcweir //
732*cdf0e10cSrcweir //  Returns:    S_OK
733*cdf0e10cSrcweir //				E_OUTOFMEMORY
734*cdf0e10cSrcweir //				E_FAIL
735*cdf0e10cSrcweir //
736*cdf0e10cSrcweir //
737*cdf0e10cSrcweir //--------------------------------------------------------------------------
738*cdf0e10cSrcweir SCODE STDMETHODCALLTYPE COooFilter::Load(IStream *pStm)
739*cdf0e10cSrcweir {
740*cdf0e10cSrcweir 	zlib_filefunc_def z_filefunc;
741*cdf0e10cSrcweir 
742*cdf0e10cSrcweir     m_pStream = PrepareIStream( pStm, z_filefunc );
743*cdf0e10cSrcweir 
744*cdf0e10cSrcweir 	try
745*cdf0e10cSrcweir     {
746*cdf0e10cSrcweir         if (m_pMetaInfoReader)
747*cdf0e10cSrcweir             delete m_pMetaInfoReader;
748*cdf0e10cSrcweir 		m_pMetaInfoReader = new CMetaInfoReader((void*)m_pStream, &z_filefunc);
749*cdf0e10cSrcweir 
750*cdf0e10cSrcweir 		if (m_pContentReader)
751*cdf0e10cSrcweir 		    delete m_pContentReader;
752*cdf0e10cSrcweir 		m_pContentReader = new CContentReader((void*)m_pStream, m_pMetaInfoReader->getDefaultLocale(), &z_filefunc);
753*cdf0e10cSrcweir     }
754*cdf0e10cSrcweir     catch (const std::exception&)
755*cdf0e10cSrcweir     {
756*cdf0e10cSrcweir         return E_FAIL;
757*cdf0e10cSrcweir     }
758*cdf0e10cSrcweir     return S_OK;
759*cdf0e10cSrcweir }
760*cdf0e10cSrcweir 
761*cdf0e10cSrcweir //M-------------------------------------------------------------------------
762*cdf0e10cSrcweir //
763*cdf0e10cSrcweir //  Method:     COooFilter::GetSizeMax      (IPersistStream::GetSizeMax)
764*cdf0e10cSrcweir //
765*cdf0e10cSrcweir //  Summary:    Returns the size in bytes of the stream neede to save the object.
766*cdf0e10cSrcweir //
767*cdf0e10cSrcweir //  Arguments:  pcbSize
768*cdf0e10cSrcweir //                  [out] Pointer to a 64 bit unsigned int indicating the size needed
769*cdf0e10cSrcweir //
770*cdf0e10cSrcweir //  Returns:    E_NOTIMPL
771*cdf0e10cSrcweir //
772*cdf0e10cSrcweir //
773*cdf0e10cSrcweir //--------------------------------------------------------------------------
774*cdf0e10cSrcweir SCODE STDMETHODCALLTYPE COooFilter::GetSizeMax(ULARGE_INTEGER * /*pcbSize*/)
775*cdf0e10cSrcweir {
776*cdf0e10cSrcweir     //
777*cdf0e10cSrcweir     return E_NOTIMPL;
778*cdf0e10cSrcweir }
779*cdf0e10cSrcweir 
780*cdf0e10cSrcweir //M-------------------------------------------------------------------------
781*cdf0e10cSrcweir //
782*cdf0e10cSrcweir //  Method:     COooFilter::Save      (IPersistStream::Save)
783*cdf0e10cSrcweir //
784*cdf0e10cSrcweir //  Summary:    Save object to specified stream
785*cdf0e10cSrcweir //
786*cdf0e10cSrcweir //  Arguments:  pStm
787*cdf0e10cSrcweir //                  [in] Pointer to stream
788*cdf0e10cSrcweir //
789*cdf0e10cSrcweir //              fClearDirty
790*cdf0e10cSrcweir //					[in] Indicates whether to clear dirty flag
791*cdf0e10cSrcweir //
792*cdf0e10cSrcweir //  Returns:    E_NOTIMPL
793*cdf0e10cSrcweir //
794*cdf0e10cSrcweir //
795*cdf0e10cSrcweir //--------------------------------------------------------------------------
796*cdf0e10cSrcweir SCODE STDMETHODCALLTYPE COooFilter::Save(IStream * /*pStm*/, BOOL )
797*cdf0e10cSrcweir {
798*cdf0e10cSrcweir     //
799*cdf0e10cSrcweir     return E_NOTIMPL;
800*cdf0e10cSrcweir }
801*cdf0e10cSrcweir 
802*cdf0e10cSrcweir //M-------------------------------------------------------------------------
803*cdf0e10cSrcweir //
804*cdf0e10cSrcweir //  Method:     COooFilter::GetCurFile          (IPersistFile::GetCurFile)
805*cdf0e10cSrcweir //
806*cdf0e10cSrcweir //  Summary:    Returns a copy of the current file name
807*cdf0e10cSrcweir //
808*cdf0e10cSrcweir //  Arguments:  ppszFileName
809*cdf0e10cSrcweir //                  [out] Address to receive pointer to zero-terminated
810*cdf0e10cSrcweir //                        string for absolute path to current file
811*cdf0e10cSrcweir //
812*cdf0e10cSrcweir //  Returns:    S_OK
813*cdf0e10cSrcweir //                  A valid absolute path was successfully returned
814*cdf0e10cSrcweir //              S_FALSE
815*cdf0e10cSrcweir //                  (not implemented)
816*cdf0e10cSrcweir //              E_OUTOFMEMORY
817*cdf0e10cSrcweir //                  Operation failed due to insufficient memory
818*cdf0e10cSrcweir //              E_FAIL
819*cdf0e10cSrcweir //                  Operation failed due to some reason
820*cdf0e10cSrcweir //                  other than insufficient memory
821*cdf0e10cSrcweir //
822*cdf0e10cSrcweir //-------------------------------------------------------------------------
823*cdf0e10cSrcweir SCODE STDMETHODCALLTYPE COooFilter::GetCurFile(LPWSTR * ppszFileName)
824*cdf0e10cSrcweir {
825*cdf0e10cSrcweir     if ( EMPTY_STRING == m_pwszFileName )
826*cdf0e10cSrcweir         return E_FAIL;
827*cdf0e10cSrcweir     else
828*cdf0e10cSrcweir         *ppszFileName = (LPWSTR)m_pwszFileName.c_str();
829*cdf0e10cSrcweir     return S_OK;
830*cdf0e10cSrcweir }
831*cdf0e10cSrcweir 
832*cdf0e10cSrcweir //M-------------------------------------------------------------------------
833*cdf0e10cSrcweir //
834*cdf0e10cSrcweir //  Method:     COooFilterCF::COooFilterCF
835*cdf0e10cSrcweir //
836*cdf0e10cSrcweir //  Summary:    Class factory constructor
837*cdf0e10cSrcweir //
838*cdf0e10cSrcweir //  Arguments:  void
839*cdf0e10cSrcweir //
840*cdf0e10cSrcweir //  Purpose:    Manages global instance count
841*cdf0e10cSrcweir //
842*cdf0e10cSrcweir //--------------------------------------------------------------------------
843*cdf0e10cSrcweir COooFilterCF::COooFilterCF() :
844*cdf0e10cSrcweir     m_lRefs(1)
845*cdf0e10cSrcweir {
846*cdf0e10cSrcweir     InterlockedIncrement( &g_lInstances );
847*cdf0e10cSrcweir }
848*cdf0e10cSrcweir //M-------------------------------------------------------------------------
849*cdf0e10cSrcweir //
850*cdf0e10cSrcweir //  Method:     COooFilterCF::~COooFilterCF
851*cdf0e10cSrcweir //
852*cdf0e10cSrcweir //  Summary:    Class factory destructor
853*cdf0e10cSrcweir //
854*cdf0e10cSrcweir //  Arguments:  void
855*cdf0e10cSrcweir //
856*cdf0e10cSrcweir //  Purpose:    Manages global instance count
857*cdf0e10cSrcweir //
858*cdf0e10cSrcweir //--------------------------------------------------------------------------
859*cdf0e10cSrcweir COooFilterCF::~COooFilterCF()
860*cdf0e10cSrcweir {
861*cdf0e10cSrcweir    InterlockedDecrement( &g_lInstances );
862*cdf0e10cSrcweir }
863*cdf0e10cSrcweir //M-------------------------------------------------------------------------
864*cdf0e10cSrcweir //
865*cdf0e10cSrcweir //  Method:     COooFilterCF::QueryInterface    (IUnknown::QueryInterface)
866*cdf0e10cSrcweir //
867*cdf0e10cSrcweir //  Summary:    Queries for requested interface
868*cdf0e10cSrcweir //
869*cdf0e10cSrcweir //  Arguments:  riid
870*cdf0e10cSrcweir //                  [in] Reference IID of requested interface
871*cdf0e10cSrcweir //              ppvObject
872*cdf0e10cSrcweir //                  [out] Address that receives requested interface pointer
873*cdf0e10cSrcweir //
874*cdf0e10cSrcweir //  Returns:    S_OK
875*cdf0e10cSrcweir //                  Interface is supported
876*cdf0e10cSrcweir //              E_NOINTERFACE
877*cdf0e10cSrcweir //                  Interface is not supported
878*cdf0e10cSrcweir //
879*cdf0e10cSrcweir //--------------------------------------------------------------------------
880*cdf0e10cSrcweir SCODE STDMETHODCALLTYPE COooFilterCF::QueryInterface(REFIID riid, void  ** ppvObject)
881*cdf0e10cSrcweir {
882*cdf0e10cSrcweir     IUnknown *pUnkTemp;
883*cdf0e10cSrcweir 
884*cdf0e10cSrcweir     if ( IID_IClassFactory == riid )
885*cdf0e10cSrcweir         pUnkTemp = (IUnknown *)(IClassFactory *)this;
886*cdf0e10cSrcweir     else if ( IID_IUnknown == riid )
887*cdf0e10cSrcweir         pUnkTemp = (IUnknown *)this;
888*cdf0e10cSrcweir     else
889*cdf0e10cSrcweir     {
890*cdf0e10cSrcweir         *ppvObject = NULL;
891*cdf0e10cSrcweir         return E_NOINTERFACE;
892*cdf0e10cSrcweir     }
893*cdf0e10cSrcweir     *ppvObject = (void  *)pUnkTemp;
894*cdf0e10cSrcweir     pUnkTemp->AddRef();
895*cdf0e10cSrcweir     return S_OK;
896*cdf0e10cSrcweir }
897*cdf0e10cSrcweir //M-------------------------------------------------------------------------
898*cdf0e10cSrcweir //
899*cdf0e10cSrcweir //  Method:     COooFilterCF::AddRef            (IUknown::AddRef)
900*cdf0e10cSrcweir //
901*cdf0e10cSrcweir //  Summary:    Increments interface refcount
902*cdf0e10cSrcweir //
903*cdf0e10cSrcweir //  Arguments:  void
904*cdf0e10cSrcweir //
905*cdf0e10cSrcweir //  Returns:    Value of incremented interface refcount
906*cdf0e10cSrcweir //
907*cdf0e10cSrcweir //-------------------------------------------------------------------------
908*cdf0e10cSrcweir ULONG STDMETHODCALLTYPE COooFilterCF::AddRef()
909*cdf0e10cSrcweir {
910*cdf0e10cSrcweir    return InterlockedIncrement( &m_lRefs );
911*cdf0e10cSrcweir }
912*cdf0e10cSrcweir //M-------------------------------------------------------------------------
913*cdf0e10cSrcweir //
914*cdf0e10cSrcweir //  Method:     COooFilterCF::Release           (IUnknown::Release)
915*cdf0e10cSrcweir //
916*cdf0e10cSrcweir //  Summary:    Decrements interface refcount, deleting if unreferenced
917*cdf0e10cSrcweir //
918*cdf0e10cSrcweir //  Arguments:  void
919*cdf0e10cSrcweir //
920*cdf0e10cSrcweir //  Returns:    Value of decremented refcount
921*cdf0e10cSrcweir //
922*cdf0e10cSrcweir //--------------------------------------------------------------------------
923*cdf0e10cSrcweir ULONG STDMETHODCALLTYPE COooFilterCF::Release()
924*cdf0e10cSrcweir {
925*cdf0e10cSrcweir     ULONG ulTmp = InterlockedDecrement( &m_lRefs );
926*cdf0e10cSrcweir 
927*cdf0e10cSrcweir     if ( 0 == ulTmp )
928*cdf0e10cSrcweir         delete this;
929*cdf0e10cSrcweir     return ulTmp;
930*cdf0e10cSrcweir }
931*cdf0e10cSrcweir //M-------------------------------------------------------------------------
932*cdf0e10cSrcweir //
933*cdf0e10cSrcweir //  Method:     COooFilterCF::CreateInstance (IClassFactory::CreateInstance)
934*cdf0e10cSrcweir //
935*cdf0e10cSrcweir //  Summary:    Creates new OpenOffice.org filter object
936*cdf0e10cSrcweir //
937*cdf0e10cSrcweir //  Arguments:  pUnkOuter
938*cdf0e10cSrcweir //                  [in] Pointer to IUnknown interface of aggregating object
939*cdf0e10cSrcweir //              riid
940*cdf0e10cSrcweir //                  [in] Reference IID of requested interface
941*cdf0e10cSrcweir //              ppvObject
942*cdf0e10cSrcweir //                  [out] Address that receives requested interface pointer
943*cdf0e10cSrcweir //
944*cdf0e10cSrcweir //  Returns:    S_OK
945*cdf0e10cSrcweir //                  OpenOffice.org filter object was successfully created
946*cdf0e10cSrcweir //              CLASS_E_NOAGGREGATION
947*cdf0e10cSrcweir //                  pUnkOuter parameter was non-NULL
948*cdf0e10cSrcweir //              E_NOINTERFACE
949*cdf0e10cSrcweir //                  (not implemented)
950*cdf0e10cSrcweir //              E_OUTOFMEMORY
951*cdf0e10cSrcweir //                  OpenOffice.org filter object could not be created
952*cdf0e10cSrcweir //                  due to insufficient memory
953*cdf0e10cSrcweir //              E_UNEXPECTED
954*cdf0e10cSrcweir //                  Unsuccessful due to an unexpected condition
955*cdf0e10cSrcweir //
956*cdf0e10cSrcweir //--------------------------------------------------------------------------
957*cdf0e10cSrcweir SCODE STDMETHODCALLTYPE COooFilterCF::CreateInstance(
958*cdf0e10cSrcweir     IUnknown * pUnkOuter,
959*cdf0e10cSrcweir     REFIID riid,
960*cdf0e10cSrcweir     void  * * ppvObject)
961*cdf0e10cSrcweir {
962*cdf0e10cSrcweir     COooFilter *pIUnk = 0;
963*cdf0e10cSrcweir     if ( 0 != pUnkOuter )
964*cdf0e10cSrcweir         return CLASS_E_NOAGGREGATION;
965*cdf0e10cSrcweir     pIUnk = new COooFilter();
966*cdf0e10cSrcweir     if ( 0 != pIUnk )
967*cdf0e10cSrcweir     {
968*cdf0e10cSrcweir         if ( SUCCEEDED( pIUnk->QueryInterface( riid , ppvObject ) ) )
969*cdf0e10cSrcweir         {
970*cdf0e10cSrcweir             // Release extra refcount from QueryInterface
971*cdf0e10cSrcweir             pIUnk->Release();
972*cdf0e10cSrcweir         }
973*cdf0e10cSrcweir         else
974*cdf0e10cSrcweir         {
975*cdf0e10cSrcweir             delete pIUnk;
976*cdf0e10cSrcweir             return E_UNEXPECTED;
977*cdf0e10cSrcweir         }
978*cdf0e10cSrcweir     }
979*cdf0e10cSrcweir     else
980*cdf0e10cSrcweir         return E_OUTOFMEMORY;
981*cdf0e10cSrcweir     return S_OK;
982*cdf0e10cSrcweir }
983*cdf0e10cSrcweir 
984*cdf0e10cSrcweir //M-------------------------------------------------------------------------
985*cdf0e10cSrcweir //
986*cdf0e10cSrcweir //  Method:     COooFilterCF::LockServer        (IClassFactory::LockServer)
987*cdf0e10cSrcweir //
988*cdf0e10cSrcweir //  Summary:    Forces/allows filter class to remain loaded/be unloaded
989*cdf0e10cSrcweir //
990*cdf0e10cSrcweir //  Arguments:  fLock
991*cdf0e10cSrcweir //                  [in] TRUE to lock, FALSE to unlock
992*cdf0e10cSrcweir //
993*cdf0e10cSrcweir //  Returns:    S_OK
994*cdf0e10cSrcweir //                  Always
995*cdf0e10cSrcweir //              E_FAIL
996*cdf0e10cSrcweir //                  (not implemented)
997*cdf0e10cSrcweir //              E_OUTOFMEMORY
998*cdf0e10cSrcweir //                  (not implemented)
999*cdf0e10cSrcweir //              E_UNEXPECTED
1000*cdf0e10cSrcweir //                  (not implemented)
1001*cdf0e10cSrcweir //
1002*cdf0e10cSrcweir //--------------------------------------------------------------------------
1003*cdf0e10cSrcweir SCODE STDMETHODCALLTYPE COooFilterCF::LockServer(BOOL fLock)
1004*cdf0e10cSrcweir {
1005*cdf0e10cSrcweir     if( fLock )
1006*cdf0e10cSrcweir         InterlockedIncrement( &g_lInstances );
1007*cdf0e10cSrcweir     else
1008*cdf0e10cSrcweir         InterlockedDecrement( &g_lInstances );
1009*cdf0e10cSrcweir     return S_OK;
1010*cdf0e10cSrcweir }
1011*cdf0e10cSrcweir //+-------------------------------------------------------------------------
1012*cdf0e10cSrcweir //
1013*cdf0e10cSrcweir //  DLL:        ooofilt.dll
1014*cdf0e10cSrcweir //
1015*cdf0e10cSrcweir //  Summary:    Implements Dynamic Link Library functions for OpenOffice.org filter
1016*cdf0e10cSrcweir //
1017*cdf0e10cSrcweir //--------------------------------------------------------------------------
1018*cdf0e10cSrcweir //F-------------------------------------------------------------------------
1019*cdf0e10cSrcweir //
1020*cdf0e10cSrcweir //  Function:   DllMain
1021*cdf0e10cSrcweir //
1022*cdf0e10cSrcweir //  Summary:    Called from C-Runtime on process/thread attach/detach
1023*cdf0e10cSrcweir //
1024*cdf0e10cSrcweir //  Arguments:  hInstance
1025*cdf0e10cSrcweir //                  [in] Handle to the DLL
1026*cdf0e10cSrcweir //              fdwReason
1027*cdf0e10cSrcweir //                  [in] Reason for calling DLL entry point
1028*cdf0e10cSrcweir //              lpReserve
1029*cdf0e10cSrcweir //                  [in] Details of DLL initialization and cleanup
1030*cdf0e10cSrcweir //
1031*cdf0e10cSrcweir //  Returns:    TRUE
1032*cdf0e10cSrcweir //                  Always
1033*cdf0e10cSrcweir //
1034*cdf0e10cSrcweir //--------------------------------------------------------------------------
1035*cdf0e10cSrcweir extern "C" BOOL WINAPI DllMain(
1036*cdf0e10cSrcweir     HINSTANCE hInstance,
1037*cdf0e10cSrcweir     DWORD     fdwReason,
1038*cdf0e10cSrcweir     LPVOID    /*lpvReserved*/
1039*cdf0e10cSrcweir )
1040*cdf0e10cSrcweir {
1041*cdf0e10cSrcweir    if ( DLL_PROCESS_ATTACH == fdwReason )
1042*cdf0e10cSrcweir         DisableThreadLibraryCalls( hInstance );
1043*cdf0e10cSrcweir     return TRUE;
1044*cdf0e10cSrcweir }
1045*cdf0e10cSrcweir //F-------------------------------------------------------------------------
1046*cdf0e10cSrcweir //
1047*cdf0e10cSrcweir //  Function:   DllGetClassObject
1048*cdf0e10cSrcweir //
1049*cdf0e10cSrcweir //  Summary:    Create OpenOffice.org filter class factory object
1050*cdf0e10cSrcweir //
1051*cdf0e10cSrcweir //  Arguments:  cid
1052*cdf0e10cSrcweir //                  [in] Class ID of class that class factory creates
1053*cdf0e10cSrcweir //              iid
1054*cdf0e10cSrcweir //                  [in] Reference IID of requested class factory interface
1055*cdf0e10cSrcweir //              ppvObj
1056*cdf0e10cSrcweir //                  [out] Address that receives requested interface pointer
1057*cdf0e10cSrcweir //
1058*cdf0e10cSrcweir //  Returns:    S_OK
1059*cdf0e10cSrcweir //                  Class factory object was created successfully
1060*cdf0e10cSrcweir //              CLASS_E_CLASSNOTAVAILABLE
1061*cdf0e10cSrcweir //                  DLL does not support the requested class
1062*cdf0e10cSrcweir //              E_INVALIDARG
1063*cdf0e10cSrcweir //                  (not implemented
1064*cdf0e10cSrcweir //              E_OUTOFMEMORY
1065*cdf0e10cSrcweir //                  Insufficient memory to create the class factory object
1066*cdf0e10cSrcweir //              E_UNEXPECTED
1067*cdf0e10cSrcweir //                  Unsuccessful due to an unexpected condition
1068*cdf0e10cSrcweir //
1069*cdf0e10cSrcweir //-------------------------------------------------------------------------
1070*cdf0e10cSrcweir extern "C" SCODE STDMETHODCALLTYPE DllGetClassObject(
1071*cdf0e10cSrcweir     REFCLSID   cid,
1072*cdf0e10cSrcweir     REFIID     iid,
1073*cdf0e10cSrcweir     void **    ppvObj
1074*cdf0e10cSrcweir )
1075*cdf0e10cSrcweir {
1076*cdf0e10cSrcweir     IUnknown *pResult = 0;
1077*cdf0e10cSrcweir 
1078*cdf0e10cSrcweir     if ( CLSID_COooFilter == cid )
1079*cdf0e10cSrcweir         pResult = (IUnknown *) new COooFilterCF;
1080*cdf0e10cSrcweir     else
1081*cdf0e10cSrcweir         return CLASS_E_CLASSNOTAVAILABLE;
1082*cdf0e10cSrcweir     if ( 0 != pResult )
1083*cdf0e10cSrcweir     {
1084*cdf0e10cSrcweir         if( SUCCEEDED( pResult->QueryInterface( iid, ppvObj ) ) )
1085*cdf0e10cSrcweir             // Release extra refcount from QueryInterface
1086*cdf0e10cSrcweir             pResult->Release();
1087*cdf0e10cSrcweir         else
1088*cdf0e10cSrcweir         {
1089*cdf0e10cSrcweir             delete pResult;
1090*cdf0e10cSrcweir             return E_UNEXPECTED;
1091*cdf0e10cSrcweir         }
1092*cdf0e10cSrcweir     }
1093*cdf0e10cSrcweir     else
1094*cdf0e10cSrcweir         return E_OUTOFMEMORY;
1095*cdf0e10cSrcweir     return S_OK;
1096*cdf0e10cSrcweir }
1097*cdf0e10cSrcweir //F-------------------------------------------------------------------------
1098*cdf0e10cSrcweir //
1099*cdf0e10cSrcweir //  Function:   DllCanUnloadNow
1100*cdf0e10cSrcweir //
1101*cdf0e10cSrcweir //  Summary:    Indicates whether it is possible to unload DLL
1102*cdf0e10cSrcweir //
1103*cdf0e10cSrcweir //  Arguments:  void
1104*cdf0e10cSrcweir //
1105*cdf0e10cSrcweir //  Returns:    S_OK
1106*cdf0e10cSrcweir //                  DLL can be unloaded now
1107*cdf0e10cSrcweir //              S_FALSE
1108*cdf0e10cSrcweir //                  DLL must remain loaded
1109*cdf0e10cSrcweir //
1110*cdf0e10cSrcweir //--------------------------------------------------------------------------
1111*cdf0e10cSrcweir extern "C" SCODE STDMETHODCALLTYPE DllCanUnloadNow()
1112*cdf0e10cSrcweir {
1113*cdf0e10cSrcweir     if ( 0 >= g_lInstances )
1114*cdf0e10cSrcweir         return S_OK;
1115*cdf0e10cSrcweir     else
1116*cdf0e10cSrcweir         return S_FALSE;
1117*cdf0e10cSrcweir }
1118*cdf0e10cSrcweir //F-------------------------------------------------------------------------
1119*cdf0e10cSrcweir //
1120*cdf0e10cSrcweir //  Function:   DllRegisterServer
1121*cdf0e10cSrcweir //              DllUnregisterServer
1122*cdf0e10cSrcweir //
1123*cdf0e10cSrcweir //  Summary:    Registers and unregisters DLL server
1124*cdf0e10cSrcweir //
1125*cdf0e10cSrcweir //  Returns:    DllRegisterServer
1126*cdf0e10cSrcweir //                  S_OK
1127*cdf0e10cSrcweir //                      Registration was successful
1128*cdf0e10cSrcweir //                  SELFREG_E_CLASS
1129*cdf0e10cSrcweir //                      Registration was unsuccessful
1130*cdf0e10cSrcweir //                  SELFREG_E_TYPELIB
1131*cdf0e10cSrcweir //                      (not implemented)
1132*cdf0e10cSrcweir //                  E_OUTOFMEMORY
1133*cdf0e10cSrcweir //                      (not implemented)
1134*cdf0e10cSrcweir //                  E_UNEXPECTED
1135*cdf0e10cSrcweir //                      (not implemented)
1136*cdf0e10cSrcweir //              DllUnregisterServer
1137*cdf0e10cSrcweir //                  S_OK
1138*cdf0e10cSrcweir //                      Unregistration was successful
1139*cdf0e10cSrcweir //                  S_FALSE
1140*cdf0e10cSrcweir //                      Unregistration was successful, but other
1141*cdf0e10cSrcweir //                      entries still exist for the DLL's classes
1142*cdf0e10cSrcweir //                  SELFREG_E_CLASS
1143*cdf0e10cSrcweir //                      (not implemented)
1144*cdf0e10cSrcweir //                  SELFREG_E_TYPELIB
1145*cdf0e10cSrcweir //                      (not implemented)
1146*cdf0e10cSrcweir //                  E_OUTOFMEMORY
1147*cdf0e10cSrcweir //                      (not implemented)
1148*cdf0e10cSrcweir //                  E_UNEXPECTED
1149*cdf0e10cSrcweir //                      (not implemented)
1150*cdf0e10cSrcweir //
1151*cdf0e10cSrcweir //--------------------------------------------------------------------------
1152*cdf0e10cSrcweir 
1153*cdf0e10cSrcweir 
1154*cdf0e10cSrcweir //F-------------------------------------------------------------------------
1155*cdf0e10cSrcweir //
1156*cdf0e10cSrcweir //  helper functions to register the Indexing Service.
1157*cdf0e10cSrcweir //
1158*cdf0e10cSrcweir //--------------------------------------------------------------------------
1159*cdf0e10cSrcweir 
1160*cdf0e10cSrcweir namespace /* private */
1161*cdf0e10cSrcweir {
1162*cdf0e10cSrcweir 	const char* GUID_PLACEHOLDER         = "{GUID}";
1163*cdf0e10cSrcweir 	const char* GUID_PERSIST_PLACEHOLDER = "{GUIDPERSIST}";
1164*cdf0e10cSrcweir 	const char* EXTENSION_PLACEHOLDER    = "{EXT}";
1165*cdf0e10cSrcweir 	const char* FORWARDKEY_PLACEHOLDER   = "{FWDKEY}";
1166*cdf0e10cSrcweir 
1167*cdf0e10cSrcweir 	const char* CLSID_GUID_INPROC_ENTRY             = "CLSID\\{GUID}\\InProcServer32";
1168*cdf0e10cSrcweir 	const char* CLSID_GUID_ENTRY                    = "CLSID\\{GUID}";
1169*cdf0e10cSrcweir 	const char* CLSID_GUID_PERSIST_ADDIN_ENTRY      = "CLSID\\{GUID}\\PersistentAddinsRegistered\\{GUIDPERSIST}";
1170*cdf0e10cSrcweir 	const char* CLSID_PERSIST_ENTRY                 = "CLSID\\{GUID}\\PersistentHandler";
1171*cdf0e10cSrcweir 	const char* EXT_PERSIST_ENTRY                   = "{EXT}\\PersistentHandler";
1172*cdf0e10cSrcweir 
1173*cdf0e10cSrcweir 	const char* INDEXING_FILTER_DLLSTOREGISTER      = "SYSTEM\\CurrentControlSet\\Control\\ContentIndex";
1174*cdf0e10cSrcweir 
1175*cdf0e10cSrcweir     //---------------------------
1176*cdf0e10cSrcweir     // "String Placeholder" ->
1177*cdf0e10cSrcweir     // "String Replacement"
1178*cdf0e10cSrcweir     //---------------------------
1179*cdf0e10cSrcweir 
1180*cdf0e10cSrcweir     void SubstitutePlaceholder(std::string& String, const std::string& Placeholder, const std::string& Replacement)
1181*cdf0e10cSrcweir     {
1182*cdf0e10cSrcweir         std::string::size_type idx = String.find(Placeholder);
1183*cdf0e10cSrcweir         std::string::size_type len = Placeholder.length();
1184*cdf0e10cSrcweir 
1185*cdf0e10cSrcweir         while (std::string::npos != idx)
1186*cdf0e10cSrcweir         {
1187*cdf0e10cSrcweir             String.replace(idx, len, Replacement);
1188*cdf0e10cSrcweir             idx = String.find(Placeholder);
1189*cdf0e10cSrcweir         }
1190*cdf0e10cSrcweir     }
1191*cdf0e10cSrcweir 
1192*cdf0e10cSrcweir     //----------------------------------------------
1193*cdf0e10cSrcweir     // Make the registry entry and set Filter Handler
1194*cdf0e10cSrcweir     // HKCR\CLSID\{7BC0E710-5703-45be-A29D-5D46D8B39262} = OpenOffice.org Filter
1195*cdf0e10cSrcweir     //		             InProcServer32	 (Default)       = Path\ooofilt.dll
1196*cdf0e10cSrcweir     //			                         ThreadingModel  = Both
1197*cdf0e10cSrcweir     //----------------------------------------------
1198*cdf0e10cSrcweir 
1199*cdf0e10cSrcweir     HRESULT RegisterFilterHandler(const char* FilePath, const CLSID& FilterGuid)
1200*cdf0e10cSrcweir     {
1201*cdf0e10cSrcweir         std::string ClsidEntry = CLSID_GUID_ENTRY;
1202*cdf0e10cSrcweir         SubstitutePlaceholder(ClsidEntry, GUID_PLACEHOLDER, ClsidToString(FilterGuid));
1203*cdf0e10cSrcweir 
1204*cdf0e10cSrcweir 		if (!SetRegistryKey(HKEY_CLASSES_ROOT, ClsidEntry.c_str(), "", "OpenOffice.org Filter"))
1205*cdf0e10cSrcweir             return E_FAIL;
1206*cdf0e10cSrcweir 
1207*cdf0e10cSrcweir         ClsidEntry = CLSID_GUID_INPROC_ENTRY;
1208*cdf0e10cSrcweir         SubstitutePlaceholder(ClsidEntry, GUID_PLACEHOLDER, ClsidToString(FilterGuid));
1209*cdf0e10cSrcweir 
1210*cdf0e10cSrcweir         if (!SetRegistryKey(HKEY_CLASSES_ROOT, ClsidEntry.c_str(), "", FilePath))
1211*cdf0e10cSrcweir             return E_FAIL;
1212*cdf0e10cSrcweir 
1213*cdf0e10cSrcweir         if (!SetRegistryKey(HKEY_CLASSES_ROOT, ClsidEntry.c_str(), "ThreadingModel", "Both"))
1214*cdf0e10cSrcweir             return E_FAIL;
1215*cdf0e10cSrcweir 
1216*cdf0e10cSrcweir         return S_OK;
1217*cdf0e10cSrcweir     }
1218*cdf0e10cSrcweir 
1219*cdf0e10cSrcweir     //----------------------------------------------
1220*cdf0e10cSrcweir     // Make the registry entry and set Persistent Handler
1221*cdf0e10cSrcweir     // HKCR\CLSID\{7BC0E713-5703-45be-A29D-5D46D8B39262}  = OpenOffice.org Persistent Handler
1222*cdf0e10cSrcweir     //		PersistentAddinsRegistered
1223*cdf0e10cSrcweir     //			{89BCB740-6119-101A-BCB7-00DD010655AF} = {7BC0E710-5703-45be-A29D-5D46D8B39262}
1224*cdf0e10cSrcweir     //----------------------------------------------
1225*cdf0e10cSrcweir 
1226*cdf0e10cSrcweir     HRESULT RegisterPersistentHandler(const CLSID& FilterGuid, const CLSID& PersistentGuid)
1227*cdf0e10cSrcweir     {
1228*cdf0e10cSrcweir         std::string ClsidEntry_Persist = CLSID_GUID_ENTRY;
1229*cdf0e10cSrcweir         SubstitutePlaceholder(ClsidEntry_Persist, GUID_PLACEHOLDER, ClsidToString(PersistentGuid));
1230*cdf0e10cSrcweir 
1231*cdf0e10cSrcweir 
1232*cdf0e10cSrcweir 		if (!SetRegistryKey(HKEY_CLASSES_ROOT, ClsidEntry_Persist.c_str(), "", "OpenOffice.org Persistent Handler"))
1233*cdf0e10cSrcweir             return E_FAIL;
1234*cdf0e10cSrcweir 
1235*cdf0e10cSrcweir 		// Add missing entry
1236*cdf0e10cSrcweir 		std::string ClsidEntry_Persist_Entry = CLSID_PERSIST_ENTRY;
1237*cdf0e10cSrcweir         SubstitutePlaceholder(ClsidEntry_Persist_Entry,
1238*cdf0e10cSrcweir 			                  GUID_PLACEHOLDER,
1239*cdf0e10cSrcweir 							  ClsidToString(PersistentGuid));
1240*cdf0e10cSrcweir 
1241*cdf0e10cSrcweir 		if (!SetRegistryKey(HKEY_CLASSES_ROOT, ClsidEntry_Persist_Entry.c_str(), "", ClsidToString(PersistentGuid).c_str()))
1242*cdf0e10cSrcweir 			return E_FAIL;
1243*cdf0e10cSrcweir 
1244*cdf0e10cSrcweir         std::string ClsidEntry_Persist_Addin = CLSID_GUID_PERSIST_ADDIN_ENTRY;
1245*cdf0e10cSrcweir         SubstitutePlaceholder(ClsidEntry_Persist_Addin,
1246*cdf0e10cSrcweir 			                  GUID_PLACEHOLDER,
1247*cdf0e10cSrcweir 							  ClsidToString(PersistentGuid));
1248*cdf0e10cSrcweir 		SubstitutePlaceholder(ClsidEntry_Persist_Addin,
1249*cdf0e10cSrcweir 			                  GUID_PERSIST_PLACEHOLDER,
1250*cdf0e10cSrcweir 							  ClsidToString(CLSID_PERSISTENT_HANDLER_ADDIN));
1251*cdf0e10cSrcweir 
1252*cdf0e10cSrcweir         if (!SetRegistryKey(HKEY_CLASSES_ROOT, ClsidEntry_Persist_Addin.c_str(), "", ClsidToString(FilterGuid).c_str() ))
1253*cdf0e10cSrcweir             return E_FAIL;
1254*cdf0e10cSrcweir 
1255*cdf0e10cSrcweir         return S_OK;
1256*cdf0e10cSrcweir     }
1257*cdf0e10cSrcweir 
1258*cdf0e10cSrcweir     //---------------------------
1259*cdf0e10cSrcweir     // Unregister Filter Handler or persistent handler
1260*cdf0e10cSrcweir     //---------------------------
1261*cdf0e10cSrcweir 
1262*cdf0e10cSrcweir     HRESULT UnregisterHandler(const CLSID& Guid)
1263*cdf0e10cSrcweir     {
1264*cdf0e10cSrcweir         std::string tmp = "CLSID\\";
1265*cdf0e10cSrcweir         tmp += ClsidToString(Guid);
1266*cdf0e10cSrcweir         return DeleteRegistryKey(HKEY_CLASSES_ROOT, tmp.c_str()) ? S_OK : E_FAIL;
1267*cdf0e10cSrcweir     }
1268*cdf0e10cSrcweir 
1269*cdf0e10cSrcweir     //---------------------------
1270*cdf0e10cSrcweir     // Register Indexing Service ext and class.
1271*cdf0e10cSrcweir 	// HKCR\{EXT}\PersistentHandler = {7BC0E713-5703-45be-A29D-5D46D8B39262}
1272*cdf0e10cSrcweir     // HKCR\{GUID\PersistentHandler = {7BC0E713-5703-45be-A29D-5D46D8B39262}
1273*cdf0e10cSrcweir     //---------------------------
1274*cdf0e10cSrcweir 
1275*cdf0e10cSrcweir     HRESULT RegisterSearchHandler(const char* ModuleFileName)
1276*cdf0e10cSrcweir     {
1277*cdf0e10cSrcweir         if (FAILED(RegisterFilterHandler(ModuleFileName, CLSID_FILTER_HANDLER)))
1278*cdf0e10cSrcweir             return E_FAIL;
1279*cdf0e10cSrcweir 
1280*cdf0e10cSrcweir         if (FAILED(RegisterPersistentHandler(CLSID_FILTER_HANDLER, CLSID_PERSISTENT_HANDLER )))
1281*cdf0e10cSrcweir             return E_FAIL;
1282*cdf0e10cSrcweir 
1283*cdf0e10cSrcweir         std::string sExtPersistEntry;
1284*cdf0e10cSrcweir 
1285*cdf0e10cSrcweir         for(size_t i = 0; i < OOFileExtensionTableSize; i++)
1286*cdf0e10cSrcweir         {
1287*cdf0e10cSrcweir 			// first, register extension.
1288*cdf0e10cSrcweir             sExtPersistEntry = EXT_PERSIST_ENTRY;
1289*cdf0e10cSrcweir             SubstitutePlaceholder(sExtPersistEntry, EXTENSION_PLACEHOLDER, OOFileExtensionTable[i].ExtensionAnsi);
1290*cdf0e10cSrcweir             if (!SetRegistryKey(HKEY_CLASSES_ROOT,
1291*cdf0e10cSrcweir 								sExtPersistEntry.c_str(),
1292*cdf0e10cSrcweir 								"",
1293*cdf0e10cSrcweir 								ClsidToString(CLSID_PERSISTENT_HANDLER).c_str()))
1294*cdf0e10cSrcweir                 return E_FAIL;
1295*cdf0e10cSrcweir 
1296*cdf0e10cSrcweir 			// second, register class.
1297*cdf0e10cSrcweir 			char extClassName[MAX_PATH];
1298*cdf0e10cSrcweir 			if (QueryRegistryKey(HKEY_CLASSES_ROOT, OOFileExtensionTable[i].ExtensionAnsi, "", extClassName,MAX_PATH))
1299*cdf0e10cSrcweir 			{
1300*cdf0e10cSrcweir 				::std::string extCLSIDName( extClassName );
1301*cdf0e10cSrcweir 				extCLSIDName += "\\CLSID";
1302*cdf0e10cSrcweir 				char extCLSID[MAX_PATH];
1303*cdf0e10cSrcweir 
1304*cdf0e10cSrcweir 				if (QueryRegistryKey( HKEY_CLASSES_ROOT, extCLSIDName.c_str(), "", extCLSID, MAX_PATH))
1305*cdf0e10cSrcweir 				{
1306*cdf0e10cSrcweir 					std::string ClsidEntry_CLSID_Persist = CLSID_PERSIST_ENTRY;
1307*cdf0e10cSrcweir 					SubstitutePlaceholder(ClsidEntry_CLSID_Persist,
1308*cdf0e10cSrcweir 										GUID_PLACEHOLDER,
1309*cdf0e10cSrcweir 										extCLSID);
1310*cdf0e10cSrcweir 
1311*cdf0e10cSrcweir 					if (!SetRegistryKey(HKEY_CLASSES_ROOT,
1312*cdf0e10cSrcweir 										ClsidEntry_CLSID_Persist.c_str(),
1313*cdf0e10cSrcweir 										"",
1314*cdf0e10cSrcweir 										ClsidToString(CLSID_PERSISTENT_HANDLER).c_str() ))
1315*cdf0e10cSrcweir 						return E_FAIL;
1316*cdf0e10cSrcweir 				}
1317*cdf0e10cSrcweir 			}
1318*cdf0e10cSrcweir         }
1319*cdf0e10cSrcweir 
1320*cdf0e10cSrcweir         return S_OK;
1321*cdf0e10cSrcweir     }
1322*cdf0e10cSrcweir 
1323*cdf0e10cSrcweir     // Register Indexing Service ext and class.
1324*cdf0e10cSrcweir     HRESULT UnregisterSearchHandler()
1325*cdf0e10cSrcweir     {
1326*cdf0e10cSrcweir         std::string sExtPersistEntry;
1327*cdf0e10cSrcweir 
1328*cdf0e10cSrcweir         for (size_t i = 0; i < OOFileExtensionTableSize; i++)
1329*cdf0e10cSrcweir         {
1330*cdf0e10cSrcweir 			// first, unregister extension
1331*cdf0e10cSrcweir             sExtPersistEntry = EXT_PERSIST_ENTRY;
1332*cdf0e10cSrcweir             SubstitutePlaceholder(sExtPersistEntry, EXTENSION_PLACEHOLDER, OOFileExtensionTable[i].ExtensionAnsi);
1333*cdf0e10cSrcweir             DeleteRegistryKey(HKEY_CLASSES_ROOT, sExtPersistEntry.c_str());
1334*cdf0e10cSrcweir 
1335*cdf0e10cSrcweir 			// second, unregister class
1336*cdf0e10cSrcweir 			char extClassName[MAX_PATH];
1337*cdf0e10cSrcweir 			if (QueryRegistryKey(HKEY_CLASSES_ROOT, OOFileExtensionTable[i].ExtensionAnsi, "", extClassName,MAX_PATH))
1338*cdf0e10cSrcweir 			{
1339*cdf0e10cSrcweir 				::std::string extCLSIDName( extClassName );
1340*cdf0e10cSrcweir 				extCLSIDName += "\\CLSID";
1341*cdf0e10cSrcweir 				char extCLSID[MAX_PATH];
1342*cdf0e10cSrcweir 
1343*cdf0e10cSrcweir 				if (QueryRegistryKey( HKEY_CLASSES_ROOT, extCLSIDName.c_str(), "", extCLSID, MAX_PATH))
1344*cdf0e10cSrcweir 				{
1345*cdf0e10cSrcweir 					std::string ClsidEntry_CLSID_Persist = CLSID_PERSIST_ENTRY;
1346*cdf0e10cSrcweir 					SubstitutePlaceholder(ClsidEntry_CLSID_Persist,
1347*cdf0e10cSrcweir 										GUID_PLACEHOLDER,
1348*cdf0e10cSrcweir 										extCLSID);
1349*cdf0e10cSrcweir 
1350*cdf0e10cSrcweir 					DeleteRegistryKey(HKEY_CLASSES_ROOT, ClsidEntry_CLSID_Persist.c_str());
1351*cdf0e10cSrcweir 				}
1352*cdf0e10cSrcweir 			}
1353*cdf0e10cSrcweir 		}
1354*cdf0e10cSrcweir 
1355*cdf0e10cSrcweir 		return ((UnregisterHandler(CLSID_FILTER_HANDLER)==S_OK) && (UnregisterHandler(CLSID_PERSISTENT_HANDLER)==S_OK))?S_OK:E_FAIL;
1356*cdf0e10cSrcweir     }
1357*cdf0e10cSrcweir 
1358*cdf0e10cSrcweir     //---------------------------
1359*cdf0e10cSrcweir     //    add or remove an entry to DllsToRegister entry of Indexing
1360*cdf0e10cSrcweir 	//    Filter to let Indexing Service register our filter automatically
1361*cdf0e10cSrcweir 	//	  each time.
1362*cdf0e10cSrcweir     //---------------------------
1363*cdf0e10cSrcweir 	HRESULT AddOrRemoveDllsToRegisterList( const ::std::string & DllPath, bool isAdd )
1364*cdf0e10cSrcweir 	{
1365*cdf0e10cSrcweir 		char DllsToRegisterList[4096];
1366*cdf0e10cSrcweir 		if (QueryRegistryKey(HKEY_LOCAL_MACHINE,
1367*cdf0e10cSrcweir 			                 INDEXING_FILTER_DLLSTOREGISTER,
1368*cdf0e10cSrcweir 							 "DLLsToRegister",
1369*cdf0e10cSrcweir 							 DllsToRegisterList,
1370*cdf0e10cSrcweir 							 4096))
1371*cdf0e10cSrcweir 		{
1372*cdf0e10cSrcweir 			char * pChar = DllsToRegisterList;
1373*cdf0e10cSrcweir 			for ( ; *pChar != '\0' || *(pChar +1) != '\0'; pChar++)
1374*cdf0e10cSrcweir 				if ( *pChar == '\0')
1375*cdf0e10cSrcweir 					*pChar = ';';
1376*cdf0e10cSrcweir 			*pChar = ';';
1377*cdf0e10cSrcweir 			*(pChar+1) = '\0';
1378*cdf0e10cSrcweir 
1379*cdf0e10cSrcweir 			::std::string DllList(DllsToRegisterList);
1380*cdf0e10cSrcweir 			if ( ( isAdd )&&( DllList.find( DllPath ) == ::std::string::npos ) )
1381*cdf0e10cSrcweir 				DllList.append( DllPath );
1382*cdf0e10cSrcweir 			else if ( ( !isAdd )&&( DllList.find( DllPath ) != ::std::string::npos ) )
1383*cdf0e10cSrcweir 				DllList.erase( DllList.find( DllPath )-1, DllPath.length()+1 );
1384*cdf0e10cSrcweir 			else
1385*cdf0e10cSrcweir 				return S_OK;
1386*cdf0e10cSrcweir 
1387*cdf0e10cSrcweir 			pChar = DllsToRegisterList;
1388*cdf0e10cSrcweir 			for ( size_t nChar = 0; nChar < DllList.length(); pChar++,nChar++)
1389*cdf0e10cSrcweir 			{
1390*cdf0e10cSrcweir 				if ( DllList[nChar] == ';')
1391*cdf0e10cSrcweir 					*pChar = '\0';
1392*cdf0e10cSrcweir 				else
1393*cdf0e10cSrcweir 					*pChar = DllList[nChar];
1394*cdf0e10cSrcweir 			}
1395*cdf0e10cSrcweir 			*pChar = *( pChar+1 ) ='\0';
1396*cdf0e10cSrcweir 
1397*cdf0e10cSrcweir 			HKEY hSubKey;
1398*cdf0e10cSrcweir 			int rc = RegCreateKeyExA(HKEY_LOCAL_MACHINE,
1399*cdf0e10cSrcweir 									INDEXING_FILTER_DLLSTOREGISTER,
1400*cdf0e10cSrcweir 									0,
1401*cdf0e10cSrcweir 									"",
1402*cdf0e10cSrcweir 									REG_OPTION_NON_VOLATILE,
1403*cdf0e10cSrcweir 									KEY_WRITE,
1404*cdf0e10cSrcweir 									0,
1405*cdf0e10cSrcweir 									&hSubKey,
1406*cdf0e10cSrcweir 									0);
1407*cdf0e10cSrcweir 
1408*cdf0e10cSrcweir 			if (ERROR_SUCCESS == rc)
1409*cdf0e10cSrcweir 			{
1410*cdf0e10cSrcweir 				rc = RegSetValueExA( hSubKey,
1411*cdf0e10cSrcweir 									"DLLsToRegister",
1412*cdf0e10cSrcweir 									0,
1413*cdf0e10cSrcweir 									REG_MULTI_SZ,
1414*cdf0e10cSrcweir 									reinterpret_cast<const BYTE*>(DllsToRegisterList),
1415*cdf0e10cSrcweir 									DllList.length() + 2);
1416*cdf0e10cSrcweir 
1417*cdf0e10cSrcweir 				RegCloseKey(hSubKey);
1418*cdf0e10cSrcweir 			}
1419*cdf0e10cSrcweir 
1420*cdf0e10cSrcweir 			return (ERROR_SUCCESS == rc)?S_OK:E_FAIL;
1421*cdf0e10cSrcweir 		}
1422*cdf0e10cSrcweir 
1423*cdf0e10cSrcweir 		return S_OK;
1424*cdf0e10cSrcweir 	}
1425*cdf0e10cSrcweir 
1426*cdf0e10cSrcweir } // namespace /* private */
1427*cdf0e10cSrcweir 
1428*cdf0e10cSrcweir STDAPI DllRegisterServer()
1429*cdf0e10cSrcweir {
1430*cdf0e10cSrcweir     /*
1431*cdf0e10cSrcweir 	TCHAR ModuleFileName[MAX_PATH];
1432*cdf0e10cSrcweir 
1433*cdf0e10cSrcweir 	GetModuleFileName(
1434*cdf0e10cSrcweir 		GetModuleHandle(MODULE_NAME_FILTER),
1435*cdf0e10cSrcweir 		ModuleFileName,
1436*cdf0e10cSrcweir 		sizeof(ModuleFileName));
1437*cdf0e10cSrcweir 
1438*cdf0e10cSrcweir 	HRESULT hr = S_OK;
1439*cdf0e10cSrcweir 
1440*cdf0e10cSrcweir 
1441*cdf0e10cSrcweir // register search handler
1442*cdf0e10cSrcweir #ifdef UNICODE
1443*cdf0e10cSrcweir 	if (FAILED(RegisterSearchHandler(WStringToString(ModuleFileName).c_str())))
1444*cdf0e10cSrcweir 		hr = E_FAIL;
1445*cdf0e10cSrcweir 	if (FAILED(AddOrRemoveDllsToRegisterList(WStringToString(ModuleFileName).c_str(), true)))
1446*cdf0e10cSrcweir 		hr = E_FAIL;
1447*cdf0e10cSrcweir #else
1448*cdf0e10cSrcweir     if (FAILED(RegisterSearchHandler(ModuleFileName)))
1449*cdf0e10cSrcweir 		hr = E_FAIL;
1450*cdf0e10cSrcweir 	if (FAILED(AddOrRemoveDllsToRegisterList(ModuleFileName, true)))
1451*cdf0e10cSrcweir 		hr = E_FAIL;
1452*cdf0e10cSrcweir #endif
1453*cdf0e10cSrcweir 
1454*cdf0e10cSrcweir 
1455*cdf0e10cSrcweir 	return hr;
1456*cdf0e10cSrcweir 	*/
1457*cdf0e10cSrcweir 	return S_OK;
1458*cdf0e10cSrcweir }
1459*cdf0e10cSrcweir 
1460*cdf0e10cSrcweir //---------------------------
1461*cdf0e10cSrcweir //
1462*cdf0e10cSrcweir //---------------------------
1463*cdf0e10cSrcweir 
1464*cdf0e10cSrcweir STDAPI DllUnregisterServer()
1465*cdf0e10cSrcweir {
1466*cdf0e10cSrcweir     /*
1467*cdf0e10cSrcweir 	TCHAR ModuleFileName[MAX_PATH];
1468*cdf0e10cSrcweir 
1469*cdf0e10cSrcweir 	GetModuleFileName(
1470*cdf0e10cSrcweir 		GetModuleHandle(MODULE_NAME_FILTER),
1471*cdf0e10cSrcweir 		ModuleFileName,
1472*cdf0e10cSrcweir 		sizeof(ModuleFileName));
1473*cdf0e10cSrcweir 
1474*cdf0e10cSrcweir 	HRESULT hr = S_OK;
1475*cdf0e10cSrcweir 
1476*cdf0e10cSrcweir 	// unregister search handler
1477*cdf0e10cSrcweir 	if (FAILED(UnregisterSearchHandler()))
1478*cdf0e10cSrcweir 		hr = E_FAIL;
1479*cdf0e10cSrcweir 
1480*cdf0e10cSrcweir #ifdef UNICODE
1481*cdf0e10cSrcweir 	if (FAILED(AddOrRemoveDllsToRegisterList(WStringToString(ModuleFileName).c_str(),false)))
1482*cdf0e10cSrcweir 		hr = E_FAIL;
1483*cdf0e10cSrcweir #else
1484*cdf0e10cSrcweir 	if (FAILED(AddOrRemoveDllsToRegisterList(ModuleFileName, false)))
1485*cdf0e10cSrcweir 		hr = E_FAIL;
1486*cdf0e10cSrcweir #endif
1487*cdf0e10cSrcweir 
1488*cdf0e10cSrcweir 	return hr;
1489*cdf0e10cSrcweir 	*/
1490*cdf0e10cSrcweir 	return S_OK;
1491*cdf0e10cSrcweir }
1492