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