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