diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:06:44 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:06:44 +0000 |
commit | ed5640d8b587fbcfed7dd7967f3de04b37a76f26 (patch) | |
tree | 7a5f7c6c9d02226d7471cb3cc8fbbf631b415303 /shell/source/win32/shlxthandler/ooofilt | |
parent | Initial commit. (diff) | |
download | libreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.tar.xz libreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.zip |
Adding upstream version 4:7.4.7.upstream/4%7.4.7upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'shell/source/win32/shlxthandler/ooofilt')
-rw-r--r-- | shell/source/win32/shlxthandler/ooofilt/ooofilt.cxx | 956 | ||||
-rw-r--r-- | shell/source/win32/shlxthandler/ooofilt/ooofilt.def | 5 | ||||
-rw-r--r-- | shell/source/win32/shlxthandler/ooofilt/ooofilt.hxx | 195 | ||||
-rw-r--r-- | shell/source/win32/shlxthandler/ooofilt/propspec.cxx | 192 | ||||
-rw-r--r-- | shell/source/win32/shlxthandler/ooofilt/propspec.hxx | 127 | ||||
-rw-r--r-- | shell/source/win32/shlxthandler/ooofilt/stream_helper.cxx | 137 |
6 files changed, 1612 insertions, 0 deletions
diff --git a/shell/source/win32/shlxthandler/ooofilt/ooofilt.cxx b/shell/source/win32/shlxthandler/ooofilt/ooofilt.cxx new file mode 100644 index 000000000..c45c69930 --- /dev/null +++ b/shell/source/win32/shlxthandler/ooofilt/ooofilt.cxx @@ -0,0 +1,956 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + + +// File: ooofilt.cxx +// Contents: Filter Implementation for OpenOffice.Org Document using +// Indexing Service +// Summary: The LibreOffice filter reads OpenOffice.org XML files (with +// the extension .sxw .sxi, etc) and ODF files and extract +// their content, author, keywords,subject,comments and title +// to be filtered. + +// Platform: Windows 2000, Windows XP + +#include <contentreader.hxx> +#include <metainforeader.hxx> +#include <registry.hxx> +#include <fileextensions.hxx> + + +// Include file Purpose +// windows.h Win32 declarations +// string.h string wstring declarations +// filter.h IFilter interface declarations +// filterr.h FACILITY_ITF error definitions for IFilter +// ntquery.h Indexing Service declarations +// assert.h assertion function. +// ooofilt.hxx LibreOffice filter declarations +// propspec.hxx PROPSPEC + + +#if !defined WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +#endif +#include <windows.h> + +#include <string.h> +#include <filter.h> +#include <filterr.h> +#include <ntquery.h> +#include <assert.h> +#include "ooofilt.hxx" +#include <objidl.h> +#include <stdio.h> +#include "propspec.hxx" + +#include <stream_helper.hxx> + +#include <olectl.h> // declarations of DllRegisterServer/DllUnregisterServer + +//C------------------------------------------------------------------------- +// Class: COooFilter +// Summary: Implements LibreOffice filter class + +//M------------------------------------------------------------------------- +// Method: COooFilter::COooFilter +// Summary: Class constructor +// Arguments: void +// Purpose: Manages global instance count + +COooFilter::COooFilter() : + m_lRefs(1), + m_pContentReader(nullptr), + m_pMetaInfoReader(nullptr), + m_eState(FilterState::FilteringContent), + m_ulUnicodeBufferLen(0), + m_ulUnicodeCharsRead(0), + m_ulPropertyNum(0), + m_ulCurrentPropertyNum(0), + m_ulChunkID(1), + m_fContents(false), + m_fEof(false), + m_ChunkPosition(0), + m_cAttributes(0), + m_pAttributes(nullptr), + m_pStream(nullptr) + +{ + InterlockedIncrement( &g_lInstances ); +} +//M------------------------------------------------------------------------- +// Method: COooFilter::~COooFilter +// Summary: Class destructor +// Arguments: void +// Purpose: Manages global instance count and file handle + +COooFilter::~COooFilter() +{ + delete [] m_pAttributes; + delete m_pContentReader; + delete m_pMetaInfoReader; + delete m_pStream; + + InterlockedDecrement( &g_lInstances ); +} + +//M------------------------------------------------------------------------- +// Method: COooFilter::QueryInterface (IUnknown::QueryInterface) +// Summary: Queries for requested interface // Arguments: riid +// [in] Reference IID of requested interface +// ppvObject +// [out] Address that receives requested interface pointer +// Returns: S_OK +// Interface is supported +// E_NOINTERFACE +// Interface is not supported + +HRESULT STDMETHODCALLTYPE COooFilter::QueryInterface( + REFIID riid, + void ** ppvObject) +{ + IUnknown *pUnkTemp = nullptr; + if ( IID_IFilter == riid ) + pUnkTemp = static_cast<IFilter *>(this); + else if ( IID_IPersistFile == riid ) + pUnkTemp = static_cast<IPersistFile *>(this); + else if ( IID_IPersist == riid ) + pUnkTemp = static_cast<IPersistFile *>(this); + else if (IID_IPersistStream == riid) + pUnkTemp = static_cast<IPersistStream *>(this); + else if ( IID_IUnknown == riid ) + pUnkTemp = static_cast<IPersistFile *>(this); + else + { + *ppvObject = nullptr; + return E_NOINTERFACE; + } + *ppvObject = pUnkTemp; + pUnkTemp->AddRef(); + return S_OK; +} +//M------------------------------------------------------------------------- +// Method: COooFilter::AddRef (IUnknown::AddRef) +// Summary: Increments interface refcount +// Arguments: void +// Returns: Value of incremented interface refcount + +ULONG STDMETHODCALLTYPE COooFilter::AddRef() +{ + return InterlockedIncrement( &m_lRefs ); +} +//M------------------------------------------------------------------------- +// Method: COooFilter::Release (IUnknown::Release) +// Summary: Decrements interface refcount, deleting if unreferenced +// Arguments: void +// Returns: Value of decremented interface refcount + +ULONG STDMETHODCALLTYPE COooFilter::Release() +{ + ULONG ulTmp = InterlockedDecrement( &m_lRefs ); + + if ( 0 == ulTmp ) + delete this; + return ulTmp; +} +//M------------------------------------------------------------------------- +// Method: COooFilter::Init (IFilter::Init) +// Summary: Initializes LibreOffice filter instance +// Arguments: grfFlags +// [in] Flags for filter behavior +// cAttributes +// [in] Number attributes in array aAttributes +// aAttributes +// [in] Array of requested attribute strings +// pFlags +// [out] Pointer to return flags for additional properties +// Returns: S_OK +// Initialization succeeded +// E_FAIL +// File not previously loaded +// E_INVALIDARG +// Count and contents of attributes do not agree +// FILTER_E_ACCESS +// Unable to access file to be filtered +// FILTER_E_PASSWORD +// (not implemented) + +const int COUNT_ATTRIBUTES = 5; + +SCODE STDMETHODCALLTYPE COooFilter::Init( + ULONG grfFlags, + ULONG cAttributes, + FULLPROPSPEC const * aAttributes, + ULONG * pFlags) +{ + // Enumerate OLE properties, since any NTFS file can have them + *pFlags = IFILTER_FLAGS_OLE_PROPERTIES; + try + { + m_fContents = false; + m_ulPropertyNum = 0; + m_ulCurrentPropertyNum = 0; + if ( m_cAttributes > 0 ) + { + delete[] m_pAttributes; + m_pAttributes = nullptr; + m_cAttributes = 0; + } + if( 0 < cAttributes ) + { + // Filter properties specified in aAttributes + if ( nullptr == aAttributes ) + return E_INVALIDARG; + m_pAttributes = new CFullPropSpec[cAttributes]; + m_cAttributes = cAttributes; + // Is caller want to filter contents? + CFullPropSpec const *pAttrib = reinterpret_cast<CFullPropSpec const *>(aAttributes); + ULONG ulNumAttr; + for ( ulNumAttr = 0 ; ulNumAttr < cAttributes; ulNumAttr++ ) + { + if ( pAttrib[ulNumAttr].IsPropertyPropid() && + pAttrib[ulNumAttr].GetPropertyPropid() == PID_STG_CONTENTS && + pAttrib[ulNumAttr].GetPropSet() == guidStorage ) + { + m_fContents = true; + } + // save the requested properties. + m_pAttributes[ulNumAttr] = pAttrib[ulNumAttr]; + } + } + else if ( grfFlags & IFILTER_INIT_APPLY_INDEX_ATTRIBUTES ) + { + // Filter contents and all pseudo-properties + m_fContents = true; + + m_pAttributes = new CFullPropSpec[COUNT_ATTRIBUTES]; + m_cAttributes = COUNT_ATTRIBUTES; + m_pAttributes[0].SetPropSet( FMTID_SummaryInformation ); + m_pAttributes[0].SetProperty( PIDSI_AUTHOR ); + m_pAttributes[1].SetPropSet( FMTID_SummaryInformation ); + m_pAttributes[1].SetProperty( PIDSI_TITLE ); + m_pAttributes[2].SetPropSet( FMTID_SummaryInformation ); + m_pAttributes[2].SetProperty( PIDSI_SUBJECT ); + m_pAttributes[3].SetPropSet( FMTID_SummaryInformation ); + m_pAttributes[3].SetProperty( PIDSI_KEYWORDS ); + m_pAttributes[4].SetPropSet( FMTID_SummaryInformation ); + m_pAttributes[4].SetProperty( PIDSI_COMMENTS ); + } + else if ( 0 == grfFlags ) + { + // Filter only contents + m_fContents = true; + } + else + m_fContents = false; + // Re-initialize + if ( m_fContents ) + { + m_fEof = false; + m_eState = FilterState::FilteringContent; + m_ulUnicodeCharsRead = 0; + m_ChunkPosition = 0; + } + else + { + m_fEof = true; + m_eState = FilterState::FilteringProperty; + } + m_ulChunkID = 1; + } + catch (const std::exception&) + { + return E_FAIL; + } + + return S_OK; +} +//M------------------------------------------------------------------------- +// Method: COooFilter::GetChunk (IFilter::GetChunk) +// Summary: Gets the next chunk +// Arguments: ppStat +// [out] Pointer to description of current chunk +// Returns: S_OK +// Chunk was successfully retrieved +// E_FAIL +// Character conversion failed +// FILTER_E_ACCESS +// General access failure occurred +// FILTER_E_END_OF_CHUNKS +// Previous chunk was the last chunk +// FILTER_E_EMBEDDING_UNAVAILABLE +// (not implemented) +// FILTER_E_LINK_UNAVAILABLE +// (not implemented) +// FILTER_E_PASSWORD +// (not implemented) + +SCODE STDMETHODCALLTYPE COooFilter::GetChunk(STAT_CHUNK * pStat) +{ + for(;;) + { + switch ( m_eState ) + { + case FilterState::FilteringContent: + { + if( m_ChunkPosition == m_pContentReader ->getChunkBuffer().size() ) + { + m_ulUnicodeBufferLen=0; + m_fEof = true; + } + + if ( !m_fContents || m_fEof ) + { + m_eState = FilterState::FilteringProperty; + continue; + } + m_pwsBuffer = m_pContentReader -> getChunkBuffer()[m_ChunkPosition].second; + m_ulUnicodeBufferLen = static_cast<ULONG>(m_pwsBuffer.length()); + DWORD ChunkLCID = LocaleSetToLCID( m_pContentReader -> getChunkBuffer()[m_ChunkPosition].first ); + // Set chunk description + pStat->idChunk = m_ulChunkID; + pStat->breakType = CHUNK_NO_BREAK; + pStat->flags = CHUNK_TEXT; + pStat->locale = ChunkLCID; + pStat->attribute.guidPropSet = guidStorage; + pStat->attribute.psProperty.ulKind = PRSPEC_PROPID; + pStat->attribute.psProperty.propid = PID_STG_CONTENTS; + pStat->idChunkSource = m_ulChunkID; + pStat->cwcStartSource = 0; + pStat->cwcLenSource = 0; + m_ulUnicodeCharsRead = 0; + m_ulChunkID++; + m_ChunkPosition++; + return S_OK; + } + case FilterState::FilteringProperty: + { + if ( m_cAttributes == 0 ) + return FILTER_E_END_OF_CHUNKS; + while( !( ( m_pAttributes[m_ulPropertyNum].IsPropertyPropid() ) && + ( m_pAttributes[m_ulPropertyNum].GetPropSet() == FMTID_SummaryInformation ) )|| + ( ( m_pAttributes[m_ulPropertyNum].GetPropertyPropid() != PIDSI_AUTHOR ) && + ( m_pAttributes[m_ulPropertyNum].GetPropertyPropid() != PIDSI_TITLE ) && + ( m_pAttributes[m_ulPropertyNum].GetPropertyPropid() != PIDSI_SUBJECT ) && + ( m_pAttributes[m_ulPropertyNum].GetPropertyPropid() != PIDSI_KEYWORDS ) && + ( m_pAttributes[m_ulPropertyNum].GetPropertyPropid() != PIDSI_COMMENTS ) ) ) + { + if ( m_ulPropertyNum < m_cAttributes ) + m_ulPropertyNum++; + else + break; + } + if ( m_ulPropertyNum == m_cAttributes) + return FILTER_E_END_OF_CHUNKS; + else + { + // Set chunk description + pStat->idChunk = m_ulChunkID; + pStat->breakType = CHUNK_EOS; + pStat->flags = CHUNK_VALUE; + pStat->locale = GetSystemDefaultLCID(); + pStat->attribute.guidPropSet = FMTID_SummaryInformation; + pStat->attribute.psProperty.ulKind = PRSPEC_PROPID; + pStat->attribute.psProperty.propid = m_pAttributes[m_ulPropertyNum].GetPropertyPropid(); + pStat->idChunkSource = m_ulChunkID; + pStat->cwcStartSource = 0; + pStat->cwcLenSource = 0; + m_ulCurrentPropertyNum = m_ulPropertyNum; + m_ulPropertyNum++; + m_ulChunkID++; + return S_OK; + } + } + }//switch(...) + }//for(;;) +} +//M------------------------------------------------------------------------- +// Method: COooFilter::GetText (IFilter::GetText) +// Summary: Retrieves UNICODE text for index +// Arguments: pcwcBuffer +// [in] Pointer to size of UNICODE buffer +// [out] Pointer to count of UNICODE characters returned +// awcBuffer +// [out] Pointer to buffer to receive UNICODE text +// Returns: S_OK +// Text successfully retrieved, but text remains in chunk +// FILTER_E_NO_MORE_TEXT +// All of the text in the current chunk has been returned +// FILTER_S_LAST_TEXT +// Next call to GetText will return FILTER_E_NO_MORE_TEXT + +SCODE STDMETHODCALLTYPE COooFilter::GetText(ULONG * pcwcBuffer, WCHAR * awcBuffer) +{ + switch ( m_eState ) + { + case FilterState::FilteringProperty: + return FILTER_E_NO_TEXT; + case FilterState::FilteringContent: + { + if ( !m_fContents || 0 == m_ulUnicodeBufferLen ) + { + *pcwcBuffer = 0; + return FILTER_E_NO_MORE_TEXT; + } + // Copy UNICODE characters in chunk buffer to output UNICODE buffer + ULONG ulToCopy = min( *pcwcBuffer, m_ulUnicodeBufferLen - m_ulUnicodeCharsRead ); + wmemcpy( awcBuffer, m_pwsBuffer.c_str() + m_ulUnicodeCharsRead, ulToCopy ); + ZeroMemory( + awcBuffer + ulToCopy, (*pcwcBuffer - ulToCopy) * sizeof (WCHAR)); + m_ulUnicodeCharsRead += ulToCopy; + *pcwcBuffer = ulToCopy; + if ( m_ulUnicodeBufferLen == m_ulUnicodeCharsRead ) + { + m_ulUnicodeCharsRead = 0; + m_ulUnicodeBufferLen = 0; + return FILTER_S_LAST_TEXT; + } + return S_OK; + } + } + return E_FAIL; // Should not happen! +} +//M------------------------------------------------------------------------- +// Method: GetMetaInfoNameFromPropertyId +// Summary: helper function to convert PropertyID into respective +// MetaInfo names. +// Arguments: ulPropID +// [in] property ID +// Returns: corresponding metainfo names. + + +static ::std::wstring GetMetaInfoNameFromPropertyId( ULONG ulPropID ) +{ + switch ( ulPropID ) + { + case PIDSI_AUTHOR: return META_INFO_AUTHOR; + case PIDSI_TITLE: return META_INFO_TITLE; + case PIDSI_SUBJECT: return META_INFO_SUBJECT; + case PIDSI_KEYWORDS: return META_INFO_KEYWORDS; + case PIDSI_COMMENTS: return META_INFO_DESCRIPTION; + default: return EMPTY_STRING; + } +} +//M------------------------------------------------------------------------- +// Method: COooFilter::GetValue (IFilter::GetValue) +// Summary: Retrieves properties for index +// Arguments: ppPropValue +// [out] Address that receives pointer to property value +// Returns: FILTER_E_NO_VALUES +// Always +// FILTER_E_NO_MORE_VALUES +// (not implemented) + + +SCODE STDMETHODCALLTYPE COooFilter::GetValue(PROPVARIANT ** ppPropValue) +{ + if (m_eState == FilterState::FilteringContent) + return FILTER_E_NO_VALUES; + else // m_eState == FilteringProperty + { + if ( m_cAttributes == 0 || ( m_ulCurrentPropertyNum == m_ulPropertyNum ) ) + return FILTER_E_NO_MORE_VALUES; + PROPVARIANT *pPropVar = static_cast<PROPVARIANT *>(CoTaskMemAlloc( sizeof (PROPVARIANT) )); + if ( pPropVar == nullptr ) + return E_OUTOFMEMORY; + ::std::wstring wsTagName= GetMetaInfoNameFromPropertyId( m_pAttributes[m_ulCurrentPropertyNum].GetPropertyPropid() ); + if ( wsTagName == EMPTY_STRING ) + return FILTER_E_NO_VALUES; + ::std::wstring wsTagData = m_pMetaInfoReader->getTagData(wsTagName); + pPropVar->vt = VT_LPWSTR; + size_t cw = wsTagData.length() + 1; // reserve one for the '\0' + pPropVar->pwszVal = static_cast<WCHAR*>( CoTaskMemAlloc(cw*sizeof(WCHAR)) ); + if (pPropVar->pwszVal == nullptr) + { + CoTaskMemFree(pPropVar); + return E_OUTOFMEMORY; + } + wmemcpy(pPropVar->pwszVal, wsTagData.c_str(), cw); + *ppPropValue = pPropVar; + m_ulCurrentPropertyNum = m_ulPropertyNum; + return S_OK; + } +} +//M------------------------------------------------------------------------- +// Method: COooFilter::BindRegion (IFilter::BindRegion) +// Summary: Creates moniker or other interface for indicated text +// Arguments: origPos +// [in] Description of text location and extent +// riid +// [in] Reference IID of specified interface +// ppunk +// [out] Address that receives requested interface pointer +// Returns: E_NOTIMPL +// Always +// FILTER_W_REGION_CLIPPED +// (not implemented) + + +SCODE STDMETHODCALLTYPE COooFilter::BindRegion( + FILTERREGION /*origPos*/, + REFIID /*riid*/, + void ** /*ppunk*/) +{ + // BindRegion is currently reserved for future use + return E_NOTIMPL; +} +//M------------------------------------------------------------------------- +// Method: COooFilter::GetClassID (IPersist::GetClassID) +// Summary: Retrieves the class id of the filter class +// Arguments: pClassID +// [out] Pointer to the class ID of the filter +// Returns: S_OK +// Always +// E_FAIL +// (not implemented) + +HRESULT STDMETHODCALLTYPE COooFilter::GetClassID(CLSID * pClassID) +{ + *pClassID = CLSID_COooFilter; + return S_OK; +} +//M------------------------------------------------------------------------- +// Method: COooFilter::IsDirty (IPersistFile::IsDirty) +// Summary: Checks whether file has changed since last save +// Arguments: void +// Returns: S_FALSE +// Always +// S_OK +// (not implemented) + +HRESULT STDMETHODCALLTYPE COooFilter::IsDirty() +{ + // File is opened read-only and never changes + return S_FALSE; +} +//M------------------------------------------------------------------------- +// Method: COooFilter::Load (IPersistFile::Load) +// Summary: Opens and initializes the specified file +// Arguments: pszFileName +// [in] Pointer to zero-terminated string +// of absolute path of file to open +// dwMode +// [in] Access mode to open the file +// Returns: S_OK +// File was successfully loaded +// E_OUTOFMEMORY +// File could not be loaded due to insufficient memory +// E_FAIL +// (not implemented) + +HRESULT STDMETHODCALLTYPE COooFilter::Load(LPCOLESTR pszFileName, DWORD /*dwMode*/) +{ + // Load just sets the filename for GetChunk to read and ignores the mode + m_pwszFileName = getShortPathName( pszFileName ); + + // Open the file previously specified in call to IPersistFile::Load and get content. + try + { + delete m_pMetaInfoReader; + m_pMetaInfoReader = new CMetaInfoReader(m_pwszFileName); + + delete m_pContentReader; + m_pContentReader = new CContentReader(m_pwszFileName, m_pMetaInfoReader->getDefaultLocale()); + } + catch (const std::exception&) + { + return E_FAIL; + } + return S_OK; +} +//M------------------------------------------------------------------------- +// Method: COooFilter::Save (IPersistFile::Save) +// Summary: Saves a copy of the current file being filtered +// Arguments: pszFileName +// [in] Pointer to zero-terminated string of +// absolute path of where to save file +// fRemember +// [in] Whether the saved copy is made the current file +// Returns: E_FAIL +// Always +// S_OK +// (not implemented) + +HRESULT STDMETHODCALLTYPE COooFilter::Save(LPCOLESTR /*pszFileName*/, BOOL /*fRemember*/) +{ + // File is opened read-only; saving it is an error + return E_FAIL; +} +//M------------------------------------------------------------------------- +// Method: COooFilter::SaveCompleted (IPersistFile::SaveCompleted) +// Summary: Determines whether a file save is completed +// Arguments: pszFileName +// [in] Pointer to zero-terminated string of +// absolute path where file was previously saved +// Returns: S_OK +// Always + +HRESULT STDMETHODCALLTYPE COooFilter::SaveCompleted(LPCOLESTR /*pszFileName*/) +{ + // File is opened read-only, so "save" is always finished + return S_OK; +} + +//M------------------------------------------------------------------------- +// Method: COooFilter::Load (IPersistStream::Load) +// Summary: Initializes an object from the stream where it was previously saved +// Arguments: pStm +// [in] Pointer to stream from which object should be loaded +// Returns: S_OK +// E_OUTOFMEMORY +// E_FAIL + +HRESULT STDMETHODCALLTYPE COooFilter::Load(IStream *pStm) +{ + m_pStream = new BufferStream(pStm); + try + { + delete m_pMetaInfoReader; + m_pMetaInfoReader = new CMetaInfoReader(m_pStream); + + delete m_pContentReader; + m_pContentReader = new CContentReader(m_pStream, m_pMetaInfoReader->getDefaultLocale()); + } + catch (const std::exception&) + { + return E_FAIL; + } + return S_OK; +} + +//M------------------------------------------------------------------------- +// Method: COooFilter::GetSizeMax (IPersistStream::GetSizeMax) +// Summary: Returns the size in bytes of the stream needed to save the object. +// Arguments: pcbSize +// [out] Pointer to a 64 bit unsigned int indicating the size needed +// Returns: E_NOTIMPL + +HRESULT STDMETHODCALLTYPE COooFilter::GetSizeMax(ULARGE_INTEGER * /*pcbSize*/) +{ + return E_NOTIMPL; +} + +//M------------------------------------------------------------------------- +// Method: COooFilter::Save (IPersistStream::Save) +// Summary: Save object to specified stream +// Arguments: pStm +// [in] Pointer to stream +// fClearDirty +// [in] Indicates whether to clear dirty flag +// Returns: E_NOTIMPL + +HRESULT STDMETHODCALLTYPE COooFilter::Save(IStream * /*pStm*/, BOOL ) +{ + return E_NOTIMPL; +} + +//M------------------------------------------------------------------------- +// Method: COooFilter::GetCurFile (IPersistFile::GetCurFile) +// Summary: Returns a copy of the current file name +// Arguments: ppszFileName +// [out] Address to receive pointer to zero-terminated +// string for absolute path to current file +// Returns: S_OK +// A valid absolute path was successfully returned +// S_FALSE +// (not implemented) +// E_OUTOFMEMORY +// Operation failed due to insufficient memory +// E_FAIL +// Operation failed due to some reason +// other than insufficient memory + +HRESULT STDMETHODCALLTYPE COooFilter::GetCurFile(LPOLESTR * ppszFileName) +{ + if ( EMPTY_STRING == m_pwszFileName ) + return E_FAIL; + else + *ppszFileName = const_cast<LPWSTR>(m_pwszFileName.c_str()); + return S_OK; +} + +//M------------------------------------------------------------------------- +// Method: COooFilterCF::COooFilterCF +// Summary: Class factory constructor +// Arguments: void +// Purpose: Manages global instance count + +COooFilterCF::COooFilterCF() : + m_lRefs(1) +{ + InterlockedIncrement( &g_lInstances ); +} +//M------------------------------------------------------------------------- +// Method: COooFilterCF::~COooFilterCF +// Summary: Class factory destructor +// Arguments: void +// Purpose: Manages global instance count + +COooFilterCF::~COooFilterCF() +{ + InterlockedDecrement( &g_lInstances ); +} +//M------------------------------------------------------------------------- +// Method: COooFilterCF::QueryInterface (IUnknown::QueryInterface) +// Summary: Queries for requested interface +// Arguments: riid +// [in] Reference IID of requested interface +// ppvObject +// [out] Address that receives requested interface pointer +// Returns: S_OK +// Interface is supported +// E_NOINTERFACE +// Interface is not supported + +HRESULT STDMETHODCALLTYPE COooFilterCF::QueryInterface(REFIID riid, void ** ppvObject) +{ + IUnknown *pUnkTemp; + + if ( IID_IClassFactory == riid ) + pUnkTemp = this; + else if ( IID_IUnknown == riid ) + pUnkTemp = this; + else + { + *ppvObject = nullptr; + return E_NOINTERFACE; + } + *ppvObject = pUnkTemp; + pUnkTemp->AddRef(); + return S_OK; +} +//M------------------------------------------------------------------------- +// Method: COooFilterCF::AddRef (IUnknown::AddRef) +// Summary: Increments interface refcount +// Arguments: void +// Returns: Value of incremented interface refcount + +ULONG STDMETHODCALLTYPE COooFilterCF::AddRef() +{ + return InterlockedIncrement( &m_lRefs ); +} +//M------------------------------------------------------------------------- +// Method: COooFilterCF::Release (IUnknown::Release) +// Summary: Decrements interface refcount, deleting if unreferenced +// Arguments: void +// Returns: Value of decremented refcount + +ULONG STDMETHODCALLTYPE COooFilterCF::Release() +{ + ULONG ulTmp = InterlockedDecrement( &m_lRefs ); + + if ( 0 == ulTmp ) + delete this; + return ulTmp; +} +//M------------------------------------------------------------------------- +// Method: COooFilterCF::CreateInstance (IClassFactory::CreateInstance) +// Summary: Creates new LibreOffice filter object +// Arguments: pUnkOuter +// [in] Pointer to IUnknown interface of aggregating object +// riid +// [in] Reference IID of requested interface +// ppvObject +// [out] Address that receives requested interface pointer +// Returns: S_OK +// LibreOffice filter object was successfully created +// CLASS_E_NOAGGREGATION +// pUnkOuter parameter was non-NULL +// E_NOINTERFACE +// (not implemented) +// E_OUTOFMEMORY +// LibreOffice filter object could not be created +// due to insufficient memory +// E_UNEXPECTED +// Unsuccessful due to an unexpected condition + +HRESULT STDMETHODCALLTYPE COooFilterCF::CreateInstance( + IUnknown * pUnkOuter, + REFIID riid, + void * * ppvObject) +{ + COooFilter *pIUnk = nullptr; + if ( nullptr != pUnkOuter ) + return CLASS_E_NOAGGREGATION; + pIUnk = new COooFilter(); + if ( SUCCEEDED( pIUnk->QueryInterface( riid , ppvObject ) ) ) + { + // Release extra refcount from QueryInterface + pIUnk->Release(); + } + else + { + delete pIUnk; + return E_UNEXPECTED; + } + return S_OK; +} + +//M------------------------------------------------------------------------- +// Method: COooFilterCF::LockServer (IClassFactory::LockServer) +// Summary: Forces/allows filter class to remain loaded/be unloaded +// Arguments: fLock +// [in] TRUE to lock, FALSE to unlock +// Returns: S_OK +// Always +// E_FAIL +// (not implemented) +// E_OUTOFMEMORY +// (not implemented) +// E_UNEXPECTED +// (not implemented) + +HRESULT STDMETHODCALLTYPE COooFilterCF::LockServer(BOOL fLock) +{ + if( fLock ) + InterlockedIncrement( &g_lInstances ); + else + InterlockedDecrement( &g_lInstances ); + return S_OK; +} +//+------------------------------------------------------------------------- +// DLL: ooofilt.dll +// Summary: Implements Dynamic Link Library functions for LibreOffice filter + +//F------------------------------------------------------------------------- +// Function: DllMain +// Summary: Called from C-Runtime on process/thread attach/detach +// Arguments: hInstance +// [in] Handle to the DLL +// fdwReason +// [in] Reason for calling DLL entry point +// lpReserve +// [in] Details of DLL initialization and cleanup +// Returns: TRUE +// Always + +extern "C" BOOL WINAPI DllMain( + HINSTANCE hInstance, + DWORD fdwReason, + LPVOID /*lpvReserved*/ +) +{ + if ( DLL_PROCESS_ATTACH == fdwReason ) + DisableThreadLibraryCalls( hInstance ); + return TRUE; +} +//F------------------------------------------------------------------------- +// Function: DllGetClassObject +// Summary: Create LibreOffice filter class factory object +// Arguments: cid +// [in] Class ID of class that class factory creates +// iid +// [in] Reference IID of requested class factory interface +// ppvObj +// [out] Address that receives requested interface pointer +// Returns: S_OK +// Class factory object was created successfully +// CLASS_E_CLASSNOTAVAILABLE +// DLL does not support the requested class +// E_INVALIDARG +// (not implemented +// E_OUTOFMEMORY +// Insufficient memory to create the class factory object +// E_UNEXPECTED +// Unsuccessful due to an unexpected condition + +extern "C" HRESULT STDMETHODCALLTYPE DllGetClassObject( + REFCLSID cid, + REFIID iid, + LPVOID * ppvObj +) +{ + COooFilterCF* pImpl = nullptr; + IUnknown *pResult = nullptr; + + if ( CLSID_COooFilter == cid ) + { + pImpl = new COooFilterCF; + pResult = pImpl; + } + else + return CLASS_E_CLASSNOTAVAILABLE; + if( SUCCEEDED( pResult->QueryInterface( iid, ppvObj ) ) ) + // Release extra refcount from QueryInterface + pResult->Release(); + else + { + delete pImpl; + return E_UNEXPECTED; + } + return S_OK; +} +//F------------------------------------------------------------------------- +// Function: DllCanUnloadNow +// Summary: Indicates whether it is possible to unload DLL +// Arguments: void +// Returns: S_OK +// DLL can be unloaded now +// S_FALSE +// DLL must remain loaded + +extern "C" HRESULT STDMETHODCALLTYPE DllCanUnloadNow() +{ + if ( 0 >= g_lInstances ) + return S_OK; + else + return S_FALSE; +} +//F------------------------------------------------------------------------- +// Function: DllRegisterServer +// DllUnregisterServer +// Summary: Registers and unregisters DLL server +// Returns: DllRegisterServer +// S_OK +// Registration was successful +// SELFREG_E_CLASS +// Registration was unsuccessful +// SELFREG_E_TYPELIB +// (not implemented) +// E_OUTOFMEMORY +// (not implemented) +// E_UNEXPECTED +// (not implemented) +// DllUnregisterServer +// S_OK +// Unregistration was successful +// S_FALSE +// Unregistration was successful, but other +// entries still exist for the DLL's classes +// SELFREG_E_CLASS +// (not implemented) +// SELFREG_E_TYPELIB +// (not implemented) +// E_OUTOFMEMORY +// (not implemented) +// E_UNEXPECTED +// (not implemented) + +STDAPI DllRegisterServer() +{ + return S_OK; +} + + +STDAPI DllUnregisterServer() +{ + return S_OK; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/shell/source/win32/shlxthandler/ooofilt/ooofilt.def b/shell/source/win32/shlxthandler/ooofilt/ooofilt.def new file mode 100644 index 000000000..d731a151f --- /dev/null +++ b/shell/source/win32/shlxthandler/ooofilt/ooofilt.def @@ -0,0 +1,5 @@ +EXPORTS
+ DllCanUnloadNow PRIVATE
+ DllGetClassObject PRIVATE
+ DllRegisterServer PRIVATE
+ DllUnregisterServer PRIVATE
diff --git a/shell/source/win32/shlxthandler/ooofilt/ooofilt.hxx b/shell/source/win32/shlxthandler/ooofilt/ooofilt.hxx new file mode 100644 index 000000000..c178452ff --- /dev/null +++ b/shell/source/win32/shlxthandler/ooofilt/ooofilt.hxx @@ -0,0 +1,195 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SHELL_SOURCE_WIN32_SHLXTHANDLER_OOOFILT_OOOFILT_HXX +#define INCLUDED_SHELL_SOURCE_WIN32_SHLXTHANDLER_OOOFILT_OOOFILT_HXX + +#include <types.hxx> + +//+------------------------------------------------------------------------- +// Contents: LibreOffice filter declarations +// Platform: Windows 2000, Windows XP + +//+------------------------------------------------------------------------- + +class CContentReader; +class CMetaInfoReader; +class CFullPropSpec; + +LONG g_lInstances = 0; // Global count of COooFilter and COooFilterCF instances +GUID const guidStorage = PSGUID_STORAGE; // GUID for storage property set + +//C------------------------------------------------------------------------- +// Class: COooFilter +// Purpose: Implements interfaces of LibreOffice filter + +// OooFilter Class ID +// {7BC0E710-5703-45be-A29D-5D46D8B39262} +GUID const CLSID_COooFilter = +{ + 0x7bc0e710, + 0x5703, + 0x45be, + { 0xa2, 0x9d, 0x5d, 0x46, 0xd8, 0xb3, 0x92, 0x62 } +}; + +// LibreOffice Persistent Handler Class ID +// {7BC0E713-5703-45be-A29D-5D46D8B39262} +const CLSID CLSID_PERSISTENT_HANDLER = +{0x7bc0e713, 0x5703, 0x45be, {0xa2, 0x9d, 0x5d, 0x46, 0xd8, 0xb3, 0x92, 0x62}}; + +// LibreOffice Persistent Handler Addin Registered Class ID +// {89BCB740-6119-101A-BCB7-00DD010655AF} +const CLSID CLSID_PERSISTENT_HANDLER_ADDIN = +{0x89bcb740, 0x6119, 0x101a, {0xbc, 0xb7, 0x00, 0xdd, 0x01, 0x06, 0x55, 0xaf}}; + +// LibreOffice Filter Handler Class ID +// {7BC0E710-5703-45be-A29D-5D46D8B39262} +const CLSID CLSID_FILTER_HANDLER = +{0x7bc0e710, 0x5703, 0x45be, {0xa2, 0x9d, 0x5d, 0x46, 0xd8, 0xb3, 0x92, 0x62}}; + +enum class FilterState +{ + FilteringContent, // Filtering the content property + FilteringProperty // Filtering the pseudo property +}; +class COooFilter : public IFilter, public IPersistFile, public IPersistStream +{ +public: + // From IUnknown + virtual HRESULT STDMETHODCALLTYPE QueryInterface( + REFIID riid, + void ** ppvObject) override; + virtual ULONG STDMETHODCALLTYPE AddRef() override; + virtual ULONG STDMETHODCALLTYPE Release() override; + + // From IFilter + virtual SCODE STDMETHODCALLTYPE Init( + ULONG grfFlags, + ULONG cAttributes, + FULLPROPSPEC const * aAttributes, + ULONG * pFlags) override; + virtual SCODE STDMETHODCALLTYPE GetChunk( + STAT_CHUNK * pStat) override; + virtual SCODE STDMETHODCALLTYPE GetText( + ULONG * pcwcBuffer, + WCHAR * awcBuffer) override; + + virtual SCODE STDMETHODCALLTYPE GetValue( + PROPVARIANT ** ppPropValue) override; + + virtual SCODE STDMETHODCALLTYPE BindRegion( + FILTERREGION origPos, + REFIID riid, + void ** ppunk) override; + + // From IPersistFile + virtual HRESULT STDMETHODCALLTYPE GetClassID( + CLSID * pClassID) override; + virtual HRESULT STDMETHODCALLTYPE IsDirty() override; + virtual HRESULT STDMETHODCALLTYPE Load( + LPCOLESTR pszFileName, + DWORD dwMode) override; + virtual HRESULT STDMETHODCALLTYPE Save( + LPCOLESTR pszFileName, + BOOL fRemember) override; + + virtual HRESULT STDMETHODCALLTYPE SaveCompleted( + LPCOLESTR pszFileName) override; + + virtual HRESULT STDMETHODCALLTYPE GetCurFile( + LPOLESTR * ppszFileName) override; + + // From IPersistStream + virtual HRESULT STDMETHODCALLTYPE Load( + IStream *pStm) override; + + virtual HRESULT STDMETHODCALLTYPE Save( + IStream *pStm, + BOOL fClearDirty) override; + + virtual HRESULT STDMETHODCALLTYPE GetSizeMax( + ULARGE_INTEGER *pcbSize) override; + + +private: + friend class COooFilterCF; + + COooFilter(); + virtual ~COooFilter(); + + LONG m_lRefs; // Reference count + CContentReader * m_pContentReader; // A content reader that retrieves document content. + CMetaInfoReader * m_pMetaInfoReader; // A metainfo reader that retrieves document metainfo. + FilterState m_eState; // State of filtering + ::std::wstring m_pwszFileName; // Name of input file to filter + ULONG m_ulUnicodeBufferLen; // UNICODE Characters read from file to chunk buffer + ULONG m_ulUnicodeCharsRead; // UNICODE Characters read from chunk buffer + ULONG m_ulPropertyNum; // Number of properties that has been processed + ULONG m_ulCurrentPropertyNum; // Current Property that is processing; + ULONG m_ulChunkID; // Current chunk id + bool m_fContents; // TRUE if contents requested + bool m_fEof; // TRUE if end of file reached + ::std::wstring m_pwsBuffer; // Buffer to save UNICODE content from ChunkBuffer. + ULONG m_ChunkPosition; // Chunk pointer to specify the current Chunk; + ULONG m_cAttributes; // Count of attributes + CFullPropSpec * m_pAttributes; // Attributes to filter + StreamInterface * m_pStream; + +}; + +//C------------------------------------------------------------------------- +// Class: COooFilterCF +// Purpose: Implements class factory for LibreOffice filter + + +class COooFilterCF : public IClassFactory +{ +public: + // From IUnknown + virtual HRESULT STDMETHODCALLTYPE QueryInterface( + REFIID riid, + void ** ppvObject) override; + + virtual ULONG STDMETHODCALLTYPE AddRef() override; + virtual ULONG STDMETHODCALLTYPE Release() override; + + // From IClassFactory + virtual HRESULT STDMETHODCALLTYPE CreateInstance( + IUnknown * pUnkOuter, + REFIID riid, void ** ppvObject) override; + + virtual HRESULT STDMETHODCALLTYPE LockServer( + BOOL fLock) override; + +private: + friend HRESULT STDMETHODCALLTYPE DllGetClassObject( + REFCLSID cid, + REFIID iid, + LPVOID * ppvObj); + + COooFilterCF(); + virtual ~COooFilterCF(); + + LONG m_lRefs; // Reference count +}; + +#endif // INCLUDED_SHELL_SOURCE_WIN32_SHLXTHANDLER_OOOFILT_OOOFILT_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/shell/source/win32/shlxthandler/ooofilt/propspec.cxx b/shell/source/win32/shlxthandler/ooofilt/propspec.cxx new file mode 100644 index 000000000..f03cef033 --- /dev/null +++ b/shell/source/win32/shlxthandler/ooofilt/propspec.cxx @@ -0,0 +1,192 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + + +//+------------------------------------------------------------------------- +// File: propspec.cxx +// Contents: C++ wrappers for FULLPROPSPEC + +#include <sal/config.h> + +#include <new> + +#if !defined WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +#endif +#include <windows.h> +#include <filter.h> + +#include "propspec.hxx" + +//refer to ms-help://MS.VSCC/MS.MSDNVS.2052/com/stgasstg_7agk.htm +//FMTID_SummaryInformation +//GUID CLSID_SummaryInformation = { +// 0xF29F85E0, +// 0x4FF9, +// 0x1068, +// { 0xAB, 0x91, 0x08, 0x00, 0x2B, 0x27, 0xB3, 0xD9 } +//}; +//+------------------------------------------------------------------------- +// Member: CFullPropSpec::CFullPropSpec, public +// Synopsis: Default constructor +// Effects: Defines property with null guid and propid 0 + + +CFullPropSpec::CFullPropSpec() +{ + _psProperty.ulKind = PRSPEC_PROPID; + _psProperty.propid = 0; +} +//+------------------------------------------------------------------------- +// Member: CFullPropSpec::CFullPropSpec, public +// Synopsis: Construct propid based propspec +// Arguments: [guidPropSet] -- Property set +// [pidProperty] -- Property + +CFullPropSpec::CFullPropSpec( GUID const & guidPropSet, PROPID pidProperty ) : + _guidPropSet( guidPropSet ) +{ + _psProperty.ulKind = PRSPEC_PROPID; + _psProperty.propid = pidProperty; +} +//+------------------------------------------------------------------------- +// Member: CFullPropSpec::CFullPropSpec, public +// Synopsis: Construct name based propspec +// Arguments: [guidPropSet] -- Property set +// [wcsProperty] -- Property + +CFullPropSpec::CFullPropSpec( GUID const & guidPropSet, + WCHAR const * wcsProperty ) : + _guidPropSet( guidPropSet ) +{ + _psProperty.ulKind = PRSPEC_PROPID; + SetProperty( wcsProperty ); +} +//+------------------------------------------------------------------------- +// Member: CFullPropSpec::CFullPropSpec, public +// Synopsis: Copy constructor +// Arguments: [src] -- Source property spec + +CFullPropSpec::CFullPropSpec( CFullPropSpec const & src ) : + _guidPropSet( src._guidPropSet ) +{ + _psProperty.ulKind = src._psProperty.ulKind; + if ( _psProperty.ulKind == PRSPEC_LPWSTR ) + { + if ( src._psProperty.lpwstr ) + { + _psProperty.ulKind = PRSPEC_PROPID; + SetProperty( src._psProperty.lpwstr ); + } + else + _psProperty.lpwstr = nullptr; + } + else + { + _psProperty.propid = src._psProperty.propid; + } +} + +//+------------------------------------------------------------------------- +// Member: CFullPropSpec::operator=, public +// Synopsis: Assignment operator +// Arguments: [Property] -- Source property + +CFullPropSpec & CFullPropSpec::operator=( CFullPropSpec const & Property ) +{ + if (this != &Property) + { + // Clean up. + this->CFullPropSpec::~CFullPropSpec(); + + ::new (this) CFullPropSpec( Property ); + } + return *this; +} + +CFullPropSpec::~CFullPropSpec() +{ + if ( _psProperty.ulKind == PRSPEC_LPWSTR && + _psProperty.lpwstr ) + { + CoTaskMemFree( _psProperty.lpwstr ); + } +} + +void CFullPropSpec::SetProperty( PROPID pidProperty ) +{ + if ( _psProperty.ulKind == PRSPEC_LPWSTR && + nullptr != _psProperty.lpwstr ) + { + CoTaskMemFree( _psProperty.lpwstr ); + } + _psProperty.ulKind = PRSPEC_PROPID; + _psProperty.propid = pidProperty; +} +BOOL CFullPropSpec::SetProperty( WCHAR const * wcsProperty ) +{ + if ( _psProperty.ulKind == PRSPEC_LPWSTR && + nullptr != _psProperty.lpwstr ) + { + CoTaskMemFree( _psProperty.lpwstr ); + } + _psProperty.ulKind = PRSPEC_LPWSTR; + int len = static_cast<int>( (wcslen( wcsProperty ) + 1) * sizeof( WCHAR ) ); + _psProperty.lpwstr = static_cast<WCHAR *>(CoTaskMemAlloc( len )); + if ( nullptr != _psProperty.lpwstr ) + { + memcpy( _psProperty.lpwstr, + wcsProperty, + len ); + return TRUE; + } + else + { + _psProperty.lpwstr = nullptr; + return FALSE; + } +} +bool CFullPropSpec::operator==( CFullPropSpec const & prop ) const +{ + if ( memcmp( &prop._guidPropSet, + &_guidPropSet, + sizeof( _guidPropSet ) ) != 0 || + prop._psProperty.ulKind != _psProperty.ulKind ) + { + return false; + } + switch( _psProperty.ulKind ) + { + case PRSPEC_LPWSTR: + return( _wcsicmp( GetPropertyName(), prop.GetPropertyName() ) == 0 ); + case PRSPEC_PROPID: + return( GetPropertyPropid() == prop.GetPropertyPropid() ); + default: + return false; + } +} +bool CFullPropSpec::operator!=( CFullPropSpec const & prop ) const +{ + if (*this == prop) + return false; + else + return true; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/shell/source/win32/shlxthandler/ooofilt/propspec.hxx b/shell/source/win32/shlxthandler/ooofilt/propspec.hxx new file mode 100644 index 000000000..f9e1fc289 --- /dev/null +++ b/shell/source/win32/shlxthandler/ooofilt/propspec.hxx @@ -0,0 +1,127 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SHELL_SOURCE_WIN32_SHLXTHANDLER_OOOFILT_PROPSPEC_HXX +#define INCLUDED_SHELL_SOURCE_WIN32_SHLXTHANDLER_OOOFILT_PROPSPEC_HXX + +//+------------------------------------------------------------------------- +// File: propspec.hxx +// Contents: C++ wrapper(s) for FULLPROPSPEC + +#if !defined WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +#endif +#include <windows.h> +#include <ole2.h> +#include <ntquery.h> +//+------------------------------------------------------------------------- +// Declare: CLSID_SummaryInformation, GUID +// CLSID_Storage, GUID +// Contents: Definitions of OpenOffice.org Document properties + + +//+------------------------------------------------------------------------- +// Class: CFullPropertySpec +// Purpose: Describes full (PropertySet\Property) name of a property. + + +class CFullPropSpec +{ +public: + CFullPropSpec(); + CFullPropSpec( GUID const & guidPropSet, PROPID pidProperty ); + CFullPropSpec( GUID const & guidPropSet, WCHAR const * wcsProperty ); + // Validity check + inline BOOL IsValid() const; + + // Copy constructors/assignment/clone + CFullPropSpec( CFullPropSpec const & Property ); + CFullPropSpec & operator=( CFullPropSpec const & Property ); + ~CFullPropSpec(); + // Memory allocation + void * operator new( size_t size ); + void operator delete( void * p ); + inline FULLPROPSPEC * CastToStruct(); + inline FULLPROPSPEC const * CastToStruct() const; + // Comparators + bool operator==( CFullPropSpec const & prop ) const; + bool operator!=( CFullPropSpec const & prop ) const; + // Member variable access + inline void SetPropSet( GUID const & guidPropSet ); + inline GUID const & GetPropSet() const; + + void SetProperty( PROPID pidProperty ); + BOOL SetProperty( WCHAR const * wcsProperty ); + inline WCHAR const * GetPropertyName() const; + inline PROPID GetPropertyPropid() const; + inline PROPSPEC GetPropSpec() const; + inline BOOL IsPropertyName() const; + inline BOOL IsPropertyPropid() const; +private: + GUID _guidPropSet = {}; + PROPSPEC _psProperty; +}; +// Inline methods for CFullPropSpec +inline void * CFullPropSpec::operator new( size_t size ) +{ + void * p = CoTaskMemAlloc( size ); + return p; +} +inline void CFullPropSpec::operator delete( void * p ) +{ + if ( p ) + CoTaskMemFree( p ); +} +inline BOOL CFullPropSpec::IsValid() const +{ + return ( _psProperty.ulKind == PRSPEC_PROPID || + nullptr != _psProperty.lpwstr ); +} +inline void CFullPropSpec::SetPropSet( GUID const & guidPropSet ) +{ + _guidPropSet = guidPropSet; +} +inline GUID const & CFullPropSpec::GetPropSet() const +{ + return _guidPropSet; +} +inline PROPSPEC CFullPropSpec::GetPropSpec() const +{ + return _psProperty; +} +inline WCHAR const * CFullPropSpec::GetPropertyName() const +{ + return _psProperty.lpwstr; +} +inline PROPID CFullPropSpec::GetPropertyPropid() const +{ + return _psProperty.propid; +} +inline BOOL CFullPropSpec::IsPropertyName() const +{ + return _psProperty.ulKind == PRSPEC_LPWSTR; +} +inline BOOL CFullPropSpec::IsPropertyPropid() const +{ + return _psProperty.ulKind == PRSPEC_PROPID; +} + +#endif // INCLUDED_SHELL_SOURCE_WIN32_SHLXTHANDLER_OOOFILT_PROPSPEC_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/shell/source/win32/shlxthandler/ooofilt/stream_helper.cxx b/shell/source/win32/shlxthandler/ooofilt/stream_helper.cxx new file mode 100644 index 000000000..76578ba70 --- /dev/null +++ b/shell/source/win32/shlxthandler/ooofilt/stream_helper.cxx @@ -0,0 +1,137 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + + +#if !defined WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +#endif +#include <windows.h> + +#include <stdio.h> +#include <objidl.h> +#include <stream_helper.hxx> + +BufferStream::BufferStream(IStream *str) : + stream(str) +{ + // These next few lines work around the "Seek pointer" bug found on Vista. + char cBuf[20]; + unsigned long nCount; + ULARGE_INTEGER nNewPosition; + LARGE_INTEGER nMove; + nMove.QuadPart = 0; + stream->Seek( nMove, STREAM_SEEK_SET, &nNewPosition ); + stream->Read( cBuf, 20, &nCount ); +} + +BufferStream::~BufferStream() +{ +} + +unsigned long BufferStream::sread (unsigned char *buf, unsigned long size) +{ + unsigned long newsize; + HRESULT hr; + + hr = stream->Read (buf, size, &newsize); + if (hr == S_OK) + return newsize; + else + return static_cast<unsigned long>(0); +} + +long BufferStream::stell () +{ + HRESULT hr; + LARGE_INTEGER Move; + ULARGE_INTEGER NewPosition; + Move.QuadPart = 0; + NewPosition.QuadPart = 0; + + hr = stream->Seek (Move, STREAM_SEEK_CUR, &NewPosition); + if (hr == S_OK) + return static_cast<long>(NewPosition.QuadPart); + else + return -1; +} + +long BufferStream::sseek (long offset, int origin) +{ + HRESULT hr; + LARGE_INTEGER Move; + DWORD dwOrigin; + Move.QuadPart = static_cast<__int64>(offset); + + switch (origin) + { + case SEEK_CUR: + dwOrigin = STREAM_SEEK_CUR; + break; + case SEEK_END: + dwOrigin = STREAM_SEEK_END; + break; + case SEEK_SET: + dwOrigin = STREAM_SEEK_SET; + break; + default: + return -1; + } + + hr = stream->Seek (Move, dwOrigin, nullptr); + if (hr == S_OK) + return 0; + else + return -1; +} + +FileStream::FileStream(const Filepath_char_t *filename) : + file(nullptr) +{ + // fdo#67534: avoid locking to not interfere with soffice opening the file + file = _wfsopen(filename, L"rb", _SH_DENYNO); +} + +FileStream::~FileStream() +{ + if (file) + fclose(file); +} + +unsigned long FileStream::sread (unsigned char *buf, unsigned long size) +{ + if (file) + return static_cast<unsigned long>(fread(buf, 1, size, file)); + return 0; +} + +long FileStream::stell () +{ + if (file) + return ftell(file); + return -1; +} + +long FileStream::sseek (long offset, int origin) +{ + if (file) + return fseek(file, offset, origin); + return -1; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |