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