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