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