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