diff options
Diffstat (limited to 'shell/source/win32/shlxthandler')
42 files changed, 7972 insertions, 0 deletions
diff --git a/shell/source/win32/shlxthandler/classfactory.cxx b/shell/source/win32/shlxthandler/classfactory.cxx new file mode 100755 index 000000000000..e19dd68383b4 --- /dev/null +++ b/shell/source/win32/shlxthandler/classfactory.cxx @@ -0,0 +1,171 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_shell.hxx" +#include "internal/global.hxx" +#include "classfactory.hxx" +#include "internal/infotips.hxx" +#include "internal/propsheets.hxx" +#include "internal/columninfo.hxx" +#ifdef __MINGW32__ +#include <algorithm> +using ::std::max; +using ::std::min; +#endif +#include "internal/thumbviewer.hxx" +#include "internal/shlxthdl.hxx" + +//----------------------------- +// +//----------------------------- + +long CClassFactory::s_ServerLocks = 0; + +//----------------------------- +// +//----------------------------- + +CClassFactory::CClassFactory(const CLSID& clsid) : + m_RefCnt(1), + m_Clsid(clsid) +{ + InterlockedIncrement(&g_DllRefCnt); +} + +//----------------------------- +// +//----------------------------- + +CClassFactory::~CClassFactory() +{ + InterlockedDecrement(&g_DllRefCnt); +} + +//----------------------------- +// IUnknown methods +//----------------------------- + +HRESULT STDMETHODCALLTYPE CClassFactory::QueryInterface(REFIID riid, void __RPC_FAR *__RPC_FAR *ppvObject) +{ + *ppvObject = 0; + + if (IID_IUnknown == riid || IID_IClassFactory == riid) + { + IUnknown* pUnk = this; + pUnk->AddRef(); + *ppvObject = pUnk; + return S_OK; + } + + return E_NOINTERFACE; +} + +//----------------------------- +// +//----------------------------- + +ULONG STDMETHODCALLTYPE CClassFactory::AddRef(void) +{ + return InterlockedIncrement(&m_RefCnt); +} + +//----------------------------- +// +//----------------------------- + +ULONG STDMETHODCALLTYPE CClassFactory::Release(void) +{ + long refcnt = InterlockedDecrement(&m_RefCnt); + + if (0 == refcnt) + delete this; + + return refcnt; +} + +//----------------------------- +// IClassFactory methods +//----------------------------- + +HRESULT STDMETHODCALLTYPE CClassFactory::CreateInstance( + IUnknown __RPC_FAR *pUnkOuter, + REFIID riid, + void __RPC_FAR *__RPC_FAR *ppvObject) +{ + if ((pUnkOuter != NULL)) + return CLASS_E_NOAGGREGATION; + + IUnknown* pUnk = 0; + + if (CLSID_PROPERTYSHEET_HANDLER == m_Clsid) + pUnk = static_cast<IShellExtInit*>(new CPropertySheet()); + + else if (CLSID_INFOTIP_HANDLER == m_Clsid) + pUnk = static_cast<IQueryInfo*>(new CInfoTip()); + + else if (CLSID_COLUMN_HANDLER == m_Clsid) + pUnk = static_cast<IColumnProvider*>(new CColumnInfo()); + + else if (CLSID_THUMBVIEWER_HANDLER == m_Clsid) + pUnk = static_cast<IExtractImage*>(new CThumbviewer()); + + POST_CONDITION(pUnk != 0, "Could not create COM object"); + + if (0 == pUnk) + return E_OUTOFMEMORY; + + HRESULT hr = pUnk->QueryInterface(riid, ppvObject); + + // if QueryInterface failed the component will destroy itself + pUnk->Release(); + + return hr; +} + +//----------------------------- +// +//----------------------------- + +HRESULT STDMETHODCALLTYPE CClassFactory::LockServer(BOOL fLock) +{ + if (fLock) + InterlockedIncrement(&s_ServerLocks); + else + InterlockedDecrement(&s_ServerLocks); + + return S_OK; +} + +//----------------------------- +// +//----------------------------- + +bool CClassFactory::IsLocked() +{ + return (s_ServerLocks > 0); +} diff --git a/shell/source/win32/shlxthandler/classfactory.hxx b/shell/source/win32/shlxthandler/classfactory.hxx new file mode 100644 index 000000000000..f0a8b84ae6ee --- /dev/null +++ b/shell/source/win32/shlxthandler/classfactory.hxx @@ -0,0 +1,77 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef CLASSFACTORY_HXX_INCLUDED +#define CLASSFACTORY_HXX_INCLUDED + +#if defined _MSC_VER +#pragma warning(push, 1) +#endif +#include <objidl.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif + +class CClassFactory : public IClassFactory +{ +public: + CClassFactory(const CLSID& clsid); + virtual ~CClassFactory(); + + //----------------------------- + // IUnknown methods + //----------------------------- + + virtual HRESULT STDMETHODCALLTYPE QueryInterface( + REFIID riid, + void __RPC_FAR *__RPC_FAR *ppvObject); + + virtual ULONG STDMETHODCALLTYPE AddRef(void); + + virtual ULONG STDMETHODCALLTYPE Release(void); + + //----------------------------- + // IClassFactory methods + //----------------------------- + + virtual HRESULT STDMETHODCALLTYPE CreateInstance( + IUnknown __RPC_FAR *pUnkOuter, + REFIID riid, + void __RPC_FAR *__RPC_FAR *ppvObject); + + virtual HRESULT STDMETHODCALLTYPE LockServer(BOOL fLock); + + static bool IsLocked(); + +private: + long m_RefCnt; + CLSID m_Clsid; + + static long s_ServerLocks; +}; + +#endif diff --git a/shell/source/win32/shlxthandler/columninfo/columninfo.cxx b/shell/source/win32/shlxthandler/columninfo/columninfo.cxx new file mode 100755 index 000000000000..ab6c8bae2922 --- /dev/null +++ b/shell/source/win32/shlxthandler/columninfo/columninfo.cxx @@ -0,0 +1,232 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_shell.hxx" +#include "internal/global.hxx" +#include "internal/columninfo.hxx" +#include "internal/fileextensions.hxx" +#include "internal/metainforeader.hxx" +#include "internal/utilities.hxx" +#include "internal/config.hxx" + +#include <malloc.h> + +//---------------------------- +// +//---------------------------- + +namespace /* private */ +{ + SHCOLUMNINFO ColumnInfoTable[] = + { + {{PSGUID_SUMMARYINFORMATION, PIDSI_TITLE}, VT_BSTR, LVCFMT_LEFT, 30, SHCOLSTATE_TYPE_STR, L"Title", L"Title"}, + {{PSGUID_SUMMARYINFORMATION, PIDSI_AUTHOR}, VT_BSTR, LVCFMT_LEFT, 30, SHCOLSTATE_TYPE_STR, L"Author", L"Author"}, + {{PSGUID_SUMMARYINFORMATION, PIDSI_SUBJECT}, VT_BSTR, LVCFMT_LEFT, 30, SHCOLSTATE_TYPE_STR, L"Subject", L"Subject"}, + {{PSGUID_SUMMARYINFORMATION, PIDSI_KEYWORDS}, VT_BSTR, LVCFMT_LEFT, 30, SHCOLSTATE_TYPE_STR, L"Keywords", L"Keywords"}, + {{PSGUID_SUMMARYINFORMATION, PIDSI_COMMENTS}, VT_BSTR, LVCFMT_LEFT, 30, SHCOLSTATE_TYPE_STR, L"Comments", L"Comments"}, + {{PSGUID_SUMMARYINFORMATION, PIDSI_PAGECOUNT},VT_BSTR, LVCFMT_LEFT, 30, SHCOLSTATE_TYPE_STR, L"Pagecount", L"Pagecount"} + }; + + size_t ColumnInfoTableSize = sizeof(ColumnInfoTable)/sizeof(ColumnInfoTable[0]); +} + +//---------------------------- +// +//---------------------------- + +CColumnInfo::CColumnInfo(long RefCnt) : + m_RefCnt(RefCnt) +{ + InterlockedIncrement(&g_DllRefCnt); +} + +//---------------------------- +// +//---------------------------- + +CColumnInfo::~CColumnInfo() +{ + InterlockedDecrement(&g_DllRefCnt); +} + +//----------------------------- +// IUnknown methods +//----------------------------- + +HRESULT STDMETHODCALLTYPE CColumnInfo::QueryInterface(REFIID riid, void __RPC_FAR *__RPC_FAR *ppvObject) +{ + *ppvObject = 0; + + if (IID_IUnknown == riid || IID_IColumnProvider == riid) + { + IUnknown* pUnk = static_cast<IColumnProvider*>(this); + pUnk->AddRef(); + *ppvObject = pUnk; + return S_OK; + } + + return E_NOINTERFACE; +} + +//---------------------------- +// +//---------------------------- + +ULONG STDMETHODCALLTYPE CColumnInfo::AddRef(void) +{ + return InterlockedIncrement(&m_RefCnt); +} + +//---------------------------- +// +//---------------------------- + +ULONG STDMETHODCALLTYPE CColumnInfo::Release( void) +{ + long refcnt = InterlockedDecrement(&m_RefCnt); + + if (0 == m_RefCnt) + delete this; + + return refcnt; +} + +//----------------------------- +// IColumnProvider +//----------------------------- + +HRESULT STDMETHODCALLTYPE CColumnInfo::Initialize(LPCSHCOLUMNINIT /*psci*/) +{ + return S_OK; +} + +//----------------------------- +// Register all columns we support +//----------------------------- + +HRESULT STDMETHODCALLTYPE CColumnInfo::GetColumnInfo(DWORD dwIndex, SHCOLUMNINFO *psci) +{ + if (dwIndex >= ColumnInfoTableSize) + return S_FALSE; + + // Return information on each column we support. Return S_FALSE + // to indicate that we have returned information on all our + // columns. GetColumnInfo will be called repeatedly until S_FALSE + // or an error is returned + psci->scid.fmtid = ColumnInfoTable[dwIndex].scid.fmtid; + psci->scid.pid = ColumnInfoTable[dwIndex].scid.pid; + ZeroMemory(psci->wszTitle, sizeof(psci->wszTitle)); + wcsncpy(psci->wszTitle, ColumnInfoTable[dwIndex].wszTitle, (sizeof(psci->wszTitle) - 1)); + + //wcscpy(psci->wszTitle, ColumnInfoTable[dwIndex].wszTitle); + + return S_OK; +} + +//----------------------------- +// +//----------------------------- + +HRESULT STDMETHODCALLTYPE CColumnInfo::GetItemData(LPCSHCOLUMNID pscid, LPCSHCOLUMNDATA pscd, VARIANT *pvarData) +{ + if (IsOOFileExtension(pscd->pwszExt)) + { + try + { + std::wstring fname = getShortPathName( std::wstring( pscd->wszFile ) ); + + CMetaInfoReader meta_info_accessor(WStringToString(fname)); + + VariantClear(pvarData); + + if (IsEqualGUID (pscid->fmtid, FMTID_SummaryInformation) && pscid->pid == PIDSI_TITLE) + { + pvarData->vt = VT_BSTR; + pvarData->bstrVal = SysAllocString(meta_info_accessor.getTagData( META_INFO_TITLE ).c_str()); + + return S_OK; + } + else if (IsEqualGUID (pscid->fmtid, FMTID_SummaryInformation) && pscid->pid == PIDSI_AUTHOR) + { + pvarData->vt = VT_BSTR; + pvarData->bstrVal = SysAllocString(meta_info_accessor.getTagData( META_INFO_AUTHOR).c_str()); + + return S_OK; + } + else if (IsEqualGUID (pscid->fmtid, FMTID_SummaryInformation) && pscid->pid == PIDSI_SUBJECT) + { + pvarData->vt = VT_BSTR; + pvarData->bstrVal = SysAllocString(meta_info_accessor.getTagData( META_INFO_SUBJECT).c_str()); + + return S_OK; + } + else if (IsEqualGUID (pscid->fmtid, FMTID_SummaryInformation) && pscid->pid == PIDSI_KEYWORDS) + { + pvarData->vt = VT_BSTR; + pvarData->bstrVal = SysAllocString(meta_info_accessor.getTagData( META_INFO_KEYWORDS).c_str()); + + return S_OK; + } + else if (IsEqualGUID (pscid->fmtid, FMTID_SummaryInformation) && pscid->pid == PIDSI_COMMENTS) + { + pvarData->vt = VT_BSTR; + pvarData->bstrVal = SysAllocString(meta_info_accessor.getTagData( META_INFO_DESCRIPTION).c_str()); + + return S_OK; + } + else if (IsEqualGUID (pscid->fmtid, FMTID_SummaryInformation) && pscid->pid == PIDSI_PAGECOUNT) + { + pvarData->vt = VT_BSTR; + pvarData->bstrVal = SysAllocString(meta_info_accessor.getTagAttribute( META_INFO_DOCUMENT_STATISTIC, META_INFO_PAGES).c_str()); + + return S_OK; + } + } + catch (const std::exception&) + { + return S_FALSE; + } + } + + return S_FALSE; +} + +//----------------------------- +// +//----------------------------- + +bool CColumnInfo::IsOOFileExtension(wchar_t* Extension) const +{ + for (size_t i = 0; i < OOFileExtensionTableSize; i++) + { + if (0 == _wcsicmp(Extension, OOFileExtensionTable[i].ExtensionUnicode)) + return true; + } + + return false; +} diff --git a/shell/source/win32/shlxthandler/columninfo/makefile.mk b/shell/source/win32/shlxthandler/columninfo/makefile.mk new file mode 100644 index 000000000000..868a711e005c --- /dev/null +++ b/shell/source/win32/shlxthandler/columninfo/makefile.mk @@ -0,0 +1,59 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/..$/..$/.. +PRJNAME=shell +TARGET=columninfo +LIBTARGET=NO +ENABLE_EXCEPTIONS=TRUE + + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +CFLAGS+=-DISOLATION_AWARE_ENABLED -DWIN32_LEAN_AND_MEAN -DXML_UNICODE -D_NTSDK -DUNICODE -D_UNICODE -D_WIN32_WINNT=0x0501 +CFLAGS+=-wd4710 -wd4711 -wd4514 -wd4619 -wd4217 -wd4820 +CDEFS+=-D_WIN32_IE=0x501 + +# --- Files -------------------------------------------------------- + +SLOFILES=$(SLO)$/columninfo.obj + +.IF "$(BUILD_X64)"!="" +CFLAGS_X64+=-DISOLATION_AWARE_ENABLED -DWIN32_LEAN_AND_MEAN -DXML_UNICODE -D_NTSDK -DUNICODE -D_UNICODE -D_WIN32_WINNT=0x0501 +CFLAGS_X64+=-wd4710 -wd4711 -wd4514 -wd4619 -wd4217 -wd4820 +CDEFS_X64+=-D_WIN32_IE=0x501 +SLOFILES_X64=$(SLO_X64)$/$(TARGET).obj +.ENDIF # "$(BUILD_X64)"!="" + +# --- Targets ------------------------------------------------------ +.INCLUDE : set_wntx64.mk +.INCLUDE : target.mk +INCLUDE!:=$(subst,/stl, $(INCLUDE)) +.EXPORT : INCLUDE +.INCLUDE : tg_wntx64.mk
\ No newline at end of file diff --git a/shell/source/win32/shlxthandler/exports.dxp b/shell/source/win32/shlxthandler/exports.dxp new file mode 100644 index 000000000000..953039ccc957 --- /dev/null +++ b/shell/source/win32/shlxthandler/exports.dxp @@ -0,0 +1,4 @@ +DllRegisterServer PRIVATE +DllUnregisterServer PRIVATE +DllGetClassObject PRIVATE +DllCanUnloadNow PRIVATE
\ No newline at end of file diff --git a/shell/source/win32/shlxthandler/infotips/infotips.cxx b/shell/source/win32/shlxthandler/infotips/infotips.cxx new file mode 100755 index 000000000000..c6bf925ac6a9 --- /dev/null +++ b/shell/source/win32/shlxthandler/infotips/infotips.cxx @@ -0,0 +1,404 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_shell.hxx" +#include "internal/global.hxx" +#include "internal/infotips.hxx" +#include "internal/shlxthdl.hxx" +#include "internal/metainforeader.hxx" +#include "internal/contentreader.hxx" +#include "internal/utilities.hxx" +#include "internal/registry.hxx" +#include "internal/fileextensions.hxx" +#include "internal/iso8601_converter.hxx" +#include "internal/config.hxx" + +#include "internal/resource.h" +#include <stdio.h> +#include <utility> +#include <stdlib.h> + + +#define MAX_STRING 80 +#define KB 1024.0 +const std::wstring WSPACE = std::wstring(SPACE); + +//----------------------------- +// +//----------------------------- + +CInfoTip::CInfoTip(long RefCnt) : + m_RefCnt(RefCnt) +{ + ZeroMemory(m_szFileName, sizeof(m_szFileName)); + InterlockedIncrement(&g_DllRefCnt); +} + +//----------------------------- +// +//----------------------------- + +CInfoTip::~CInfoTip() +{ + InterlockedDecrement(&g_DllRefCnt); +} + +//----------------------------- +// IUnknown methods +//----------------------------- + +HRESULT STDMETHODCALLTYPE CInfoTip::QueryInterface(REFIID riid, void __RPC_FAR *__RPC_FAR *ppvObject) +{ + *ppvObject = 0; + + IUnknown* pUnk = 0; + + if (IID_IUnknown == riid || IID_IQueryInfo == riid) + { + pUnk = static_cast<IQueryInfo*>(this); + pUnk->AddRef(); + *ppvObject = pUnk; + return S_OK; + } + else if (IID_IPersistFile == riid) + { + pUnk = static_cast<IPersistFile*>(this); + pUnk->AddRef(); + *ppvObject = pUnk; + return S_OK; + } + + return E_NOINTERFACE; +} + +//---------------------------- +// +//---------------------------- + +ULONG STDMETHODCALLTYPE CInfoTip::AddRef(void) +{ + return InterlockedIncrement(&m_RefCnt); +} + +//---------------------------- +// +//---------------------------- + +ULONG STDMETHODCALLTYPE CInfoTip::Release( void) +{ + long refcnt = InterlockedDecrement(&m_RefCnt); + + if (0 == m_RefCnt) + delete this; + + return refcnt; +} + +//********************helper functions for GetInfoTip functions********************** + +/** get file type infomation from registry. +*/ +std::wstring getFileTypeInfo(const std::string& file_extension) +{ + char extKeyValue[MAX_STRING]; + char typeKeyValue[MAX_STRING]; + ::std::string sDot("."); + if (QueryRegistryKey(HKEY_CLASSES_ROOT, (sDot.append(file_extension)).c_str(), "", extKeyValue, MAX_STRING)) + if (QueryRegistryKey( HKEY_CLASSES_ROOT, extKeyValue, "",typeKeyValue, MAX_STRING)) + return StringToWString(typeKeyValue); + + return EMPTY_STRING; +} + +/** get file size. +*/ +DWORD getSizeOfFile( char* FileName ) +{ + HANDLE hFile = CreateFile(StringToWString(FileName).c_str(), // open file + GENERIC_READ, // open for reading + FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, // share for all operations + NULL, // no security + OPEN_EXISTING, // existing file only + FILE_ATTRIBUTE_NORMAL, // normal file + NULL); // no attr. template + + if (hFile != INVALID_HANDLE_VALUE) + { + DWORD dwSize = GetFileSize( HANDLE(hFile), NULL ); + CloseHandle( HANDLE(hFile) ); + return dwSize; + } + + return INVALID_FILE_SIZE; +} + +/** format file size in to be more readable. +*/ +std::wstring formatSizeOfFile( DWORD dwSize ) +{ + if ( dwSize < 1000 ) + { + char buffer[3]; + int dFileSize = dwSize; + + _itoa( dFileSize, buffer, 10 ); + return StringToWString( buffer ).append(StringToWString("B")); + } + + char *buffer=NULL; + int decimal, sign; + double dFileSize = (double)dwSize/(double)KB; + + buffer = _fcvt( dFileSize, 1, &decimal, &sign ); + + ::std::wstring wsTemp = StringToWString( buffer ); + int pos=decimal % 3; + ::std::wstring wsBuffer = wsTemp.substr( 0,pos); + + if ( decimal ) + for (;decimal - pos > 2;pos += 3) + { + if (pos) + wsBuffer.append(StringToWString(",")); + wsBuffer.append( wsTemp.substr( pos, 3) ); + } + else + wsBuffer.append(StringToWString("0")); + + wsBuffer.append(StringToWString(".")); + wsBuffer.append(wsTemp.substr( decimal, wsTemp.size()-decimal )); + wsBuffer.append(StringToWString("KB")); + + return wsBuffer; +} + + +/** get file size infomation. +*/ +std::wstring getFileSizeInfo(char* FileName) +{ + DWORD dwSize=getSizeOfFile(FileName); + if (dwSize != INVALID_FILE_SIZE) + return formatSizeOfFile( dwSize ); + + return EMPTY_STRING; +} + +//---------------------------- +// IQueryInfo methods +//---------------------------- + +HRESULT STDMETHODCALLTYPE CInfoTip::GetInfoTip(DWORD /*dwFlags*/, wchar_t** ppwszTip) +{ + std::wstring msg; + const std::wstring CONST_SPACE(SPACE); + + //display File Type, no matter other info is loaded successfully or not. + std::wstring tmpTypeStr = getFileTypeInfo( get_file_name_extension(m_szFileName) ); + if ( tmpTypeStr != EMPTY_STRING ) + { + msg += GetResString(IDS_TYPE_COLON) + CONST_SPACE; + msg += tmpTypeStr; + } + + try + { + CMetaInfoReader meta_info_accessor(m_szFileName); + + //display document title; + if ( meta_info_accessor.getTagData( META_INFO_TITLE ).length() > 0) + { + if ( msg != EMPTY_STRING ) + msg += L"\n"; + msg += GetResString(IDS_TITLE_COLON) + CONST_SPACE; + msg += meta_info_accessor.getTagData( META_INFO_TITLE ); + } + else + { + if ( msg != EMPTY_STRING ) + msg += L"\n"; + msg += GetResString(IDS_TITLE_COLON) + CONST_SPACE; + msg += m_FileNameOnly; + } + + //display document author; + if ( meta_info_accessor.getTagData( META_INFO_AUTHOR ).length() > 0) + { + if ( msg != EMPTY_STRING ) + msg += L"\n"; + msg += GetResString( IDS_AUTHOR_COLON ) + CONST_SPACE; + msg += meta_info_accessor.getTagData( META_INFO_AUTHOR ); + } + + //display document subject; + if ( meta_info_accessor.getTagData( META_INFO_SUBJECT ).length() > 0) + { + if ( msg != EMPTY_STRING ) + msg += L"\n"; + msg += GetResString(IDS_SUBJECT_COLON) + CONST_SPACE; + msg += meta_info_accessor.getTagData( META_INFO_SUBJECT ); + } + + //display document description; + if ( meta_info_accessor.getTagData( META_INFO_DESCRIPTION ).length() > 0) + { + if ( msg != EMPTY_STRING ) + msg += L"\n"; + msg += GetResString( IDS_COMMENTS_COLON ) + CONST_SPACE; + msg += meta_info_accessor.getTagData( META_INFO_DESCRIPTION ); + } + + //display midified time formated into locale representation. + if ( iso8601_date_to_local_date(meta_info_accessor.getTagData(META_INFO_MODIFIED )).length() > 0) + { + if ( msg != EMPTY_STRING ) + msg += L"\n"; + msg += GetResString( IDS_MODIFIED_COLON ) + CONST_SPACE; + msg += iso8601_date_to_local_date(meta_info_accessor.getTagData(META_INFO_MODIFIED )); + } + } + catch (const std::exception&) + { + //return E_FAIL; + } + + //display file size, no matter other infomation is loaded successfully or not. + std::wstring tmpSizeStr = getFileSizeInfo( m_szFileName ); + if ( tmpSizeStr != EMPTY_STRING ) + { + msg += L"\n"; + msg += GetResString( IDS_SIZE_COLON ) + CONST_SPACE; + msg += tmpSizeStr; + } + + + //finalize and assignthe string. + LPMALLOC lpMalloc; + HRESULT hr = SHGetMalloc(&lpMalloc); + + if (SUCCEEDED(hr)) + { + size_t len = sizeof(wchar_t) * msg.length() + sizeof(wchar_t); + wchar_t* pMem = reinterpret_cast<wchar_t*>(lpMalloc->Alloc(len)); + + ZeroMemory(pMem, len); + + msg.copy(pMem,msg.length()); + + *ppwszTip = pMem; + lpMalloc->Release(); + + return S_OK; + } + + return E_FAIL; +} + +//---------------------------- +// +//---------------------------- + +HRESULT STDMETHODCALLTYPE CInfoTip::GetInfoFlags(DWORD * /*pdwFlags*/ ) +{ + return E_NOTIMPL; +} + +//---------------------------- +// IPersist methods +//---------------------------- + +HRESULT STDMETHODCALLTYPE CInfoTip::GetClassID(CLSID* pClassID) +{ + pClassID = const_cast<CLSID*>(&CLSID_INFOTIP_HANDLER); + return S_OK; +} + +//---------------------------- +// IPersistFile methods +//---------------------------- + +HRESULT STDMETHODCALLTYPE CInfoTip::Load(LPCOLESTR pszFileName, DWORD /*dwMode*/) +{ + std::wstring fname = pszFileName; + + // there must be a '\' and there must even be an + // extension, else we would not have been called + std::wstring::iterator begin = fname.begin() + fname.find_last_of(L"\\") + 1; + std::wstring::iterator end = fname.end(); + + m_FileNameOnly = std::wstring(begin, end); + + fname = getShortPathName( fname ); + + std::string fnameA = WStringToString(fname); + + // #115531# + // ZeroMemory because strncpy doesn't '\0'-terminates the destination + // string; reserve the last place in the buffer for the final '\0' + // that's why '(sizeof(m_szFileName) - 1)' + ZeroMemory(m_szFileName, sizeof(m_szFileName)); + strncpy(m_szFileName, fnameA.c_str(), (sizeof(m_szFileName) - 1)); + + return S_OK; +} + +//---------------------------- +// +//---------------------------- + +HRESULT STDMETHODCALLTYPE CInfoTip::IsDirty(void) +{ + return E_NOTIMPL; +} + +//---------------------------- +// +//---------------------------- + +HRESULT STDMETHODCALLTYPE CInfoTip::Save(LPCOLESTR /*pszFileName*/, BOOL /*fRemember*/) +{ + return E_NOTIMPL; +} + +//---------------------------- +// +//---------------------------- + +HRESULT STDMETHODCALLTYPE CInfoTip::SaveCompleted(LPCOLESTR /*pszFileName*/) +{ + return E_NOTIMPL; +} + +//---------------------------- +// +//---------------------------- + +HRESULT STDMETHODCALLTYPE CInfoTip::GetCurFile(LPOLESTR __RPC_FAR * /*ppszFileName*/) +{ + return E_NOTIMPL; +} diff --git a/shell/source/win32/shlxthandler/infotips/makefile.mk b/shell/source/win32/shlxthandler/infotips/makefile.mk new file mode 100644 index 000000000000..f69f2cf2fd78 --- /dev/null +++ b/shell/source/win32/shlxthandler/infotips/makefile.mk @@ -0,0 +1,60 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/..$/..$/.. +PRJNAME=shell +TARGET=infotips +LIBTARGET=NO +ENABLE_EXCEPTIONS=TRUE +EXTERNAL_WARNINGS_NOT_ERRORS := TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +CFLAGS+=-DISOLATION_AWARE_ENABLED -DWIN32_LEAN_AND_MEAN -DXML_UNICODE -D_NTSDK -DUNICODE -D_UNICODE -D_WIN32_WINNT=0x0501 +CFLAGS+=-wd4710 -wd4711 -wd4514 -wd4619 -wd4217 -wd4820 +CDEFS+=-D_WIN32_IE=0x501 + +# --- Files -------------------------------------------------------- + +SLOFILES=$(SLO)$/$(TARGET).obj + +.IF "$(BUILD_X64)"!="" +CFLAGS_X64+=-DISOLATION_AWARE_ENABLED -DWIN32_LEAN_AND_MEAN -DXML_UNICODE -D_NTSDK -DUNICODE -D_UNICODE -D_WIN32_WINNT=0x0501 +CFLAGS_X64+=-wd4710 -wd4711 -wd4514 -wd4619 -wd4217 -wd4820 +CDEFS_X64+=-D_WIN32_IE=0x501 +SLOFILES_X64=$(SLO_X64)$/$(TARGET).obj +.ENDIF # "$(BUILD_X64)"!="" + +# --- Targets ------------------------------------------------------ + +.INCLUDE : set_wntx64.mk +.INCLUDE : target.mk +INCLUDE!:=$(subst,/stl, $(INCLUDE)) +.EXPORT : INCLUDE +.INCLUDE : tg_wntx64.mk
\ No newline at end of file diff --git a/shell/source/win32/shlxthandler/makefile.mk b/shell/source/win32/shlxthandler/makefile.mk new file mode 100644 index 000000000000..b6c9a45a9515 --- /dev/null +++ b/shell/source/win32/shlxthandler/makefile.mk @@ -0,0 +1,157 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/..$/.. +PRJNAME=shell +TARGET=shlxthdl +LIBTARGET=NO +ENABLE_EXCEPTIONS=TRUE +USE_DEFFILE=TRUE +.IF "$(BUILD_X64)"!="" +USE_DEFFILE_X64=TRUE +.ENDIF +NO_DEFAULT_STL=TRUE +USE_STLP_DEBUG= + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +UWINAPILIB = +UWINAPILIB_X64 = + +CFLAGS+=-DISOLATION_AWARE_ENABLED -DWIN32_LEAN_AND_MEAN -DXML_UNICODE -D_NTSDK -DUNICODE -D_UNICODE -D_WIN32_WINNT=0x0501 +CFLAGS+=-wd4710 -wd4711 -wd4514 -wd4619 -wd4217 -wd4820 +CDEFS+=-D_WIN32_IE=0x501 + +# --- Files -------------------------------------------------------- + +SLOFILES=$(SLO)$/classfactory.obj\ + $(SLO)$/columninfo.obj\ + $(SLO)$/infotips.obj\ + $(SLO)$/propsheets.obj\ + $(SLO)$/shlxthdl.obj\ + $(SLO)$/listviewbuilder.obj\ + $(SLO)$/document_statistic.obj\ + $(SLO)$/thumbviewer.obj\ + +SHL1TARGET=$(TARGET) + +.IF "$(COM)"=="GCC" +SHL1STDLIBS=$(ZLIB3RDLIB) $(EXPAT3RDLIB) $(COMCTL32LIB) +SHL1LIBS= +.ELSE +SHL1STDLIBS= +SHL1LIBS=$(SOLARLIBDIR)$/zlib.lib\ + $(SOLARLIBDIR)$/expat_xmlparse.lib\ + $(SOLARLIBDIR)$/expat_xmltok.lib +.ENDIF +SHL1STDLIBS+=\ + $(OLEAUT32LIB)\ + $(ADVAPI32LIB)\ + $(OLE32LIB)\ + $(UUIDLIB)\ + $(SHELL32LIB)\ + $(KERNEL32LIB)\ + $(GDI32LIB)\ + $(GDIPLUSLIB) + +.IF "$(COM)"!="GCC" +SHL1STDLIBS+=\ + msvcprt.lib +.ENDIF + +SHL1STDLIBS+=\ + $(SHLWAPILIB) + +SHL1LIBS+=$(SLB)$/util.lib\ + $(SLB)$/ooofilereader.lib + +SHL1DEPN= + +SHL1OBJS=$(SLOFILES) +SHL1DEF=$(MISC)$/$(SHL1TARGET).def + +SHL1RES=$(RES)$/$(TARGET).res + +DEF1NAME=$(SHL1TARGET) +DEF1EXPORTFILE=exports.dxp + +.IF "$(BUILD_X64)"!="" +# -------------------- x64 ----------------------- +CFLAGS_X64+=-DISOLATION_AWARE_ENABLED -DWIN32_LEAN_AND_MEAN -DXML_UNICODE -D_NTSDK -DUNICODE -D_UNICODE -D_WIN32_WINNT=0x0501 +CFLAGS_X64+=-wd4710 -wd4711 -wd4514 -wd4619 -wd4217 -wd4820 +CDEFS_X64+=-D_WIN32_IE=0x501 + +SLOFILES_X64= \ + $(SLO_X64)$/classfactory.obj\ + $(SLO_X64)$/columninfo.obj\ + $(SLO_X64)$/infotips.obj\ + $(SLO_X64)$/propsheets.obj\ + $(SLO_X64)$/shlxthdl.obj\ + $(SLO_X64)$/listviewbuilder.obj\ + $(SLO_X64)$/document_statistic.obj\ + $(SLO_X64)$/thumbviewer.obj\ + +SHL1TARGET_X64=$(TARGET) +SHL1LIBS_X64=$(SOLARLIBDIR_X64)$/zlib.lib\ + $(SOLARLIBDIR_X64)$/expat_xmlparse.lib\ + $(SOLARLIBDIR_X64)$/expat_xmltok.lib + +SHL1STDLIBS_X64+=\ + $(OLEAUT32LIB_X64)\ + $(ADVAPI32LIB_X64)\ + $(OLE32LIB_X64)\ + $(UUIDLIB_X64)\ + $(SHELL32LIB_X64)\ + $(KERNEL32LIB_X64)\ + $(GDI32LIB_X64)\ + $(USER32LIB_X64) \ + $(GDIPLUSLIB_X64) \ + $(MSVCRT_X64) \ + $(MSVCPRT_X64) \ + $(OLDNAMESLIB_X64) \ + msvcprt.lib + +SHL1LIBS_X64+=$(SLB_X64)$/util.lib\ + $(SLB_X64)$/ooofilereader.lib +SHL1OBJS_X64=$(SLOFILES_X64) +SHL1DEF_X64=$(MISC_X64)$/$(SHL1TARGET).def +SHL1RES_X64=$(RES_X64)$/$(TARGET).res + +DEF1NAME_X64=$(SHL1TARGET_X64) +DEF1EXPORTFILE_X64=exports.dxp +.ENDIF # "$(BUILD_X64)"!="" + +# --- Targets ------------------------------------------------------ + +.INCLUDE : set_wntx64.mk +.INCLUDE : target.mk +INCLUDE!:=$(subst,/stl, $(INCLUDE)) +.EXPORT : INCLUDE +.INCLUDE : tg_wntx64.mk + diff --git a/shell/source/win32/shlxthandler/ooofilt/exports.dxp b/shell/source/win32/shlxthandler/ooofilt/exports.dxp new file mode 100644 index 000000000000..953039ccc957 --- /dev/null +++ b/shell/source/win32/shlxthandler/ooofilt/exports.dxp @@ -0,0 +1,4 @@ +DllRegisterServer PRIVATE +DllUnregisterServer PRIVATE +DllGetClassObject PRIVATE +DllCanUnloadNow PRIVATE
\ No newline at end of file diff --git a/shell/source/win32/shlxthandler/ooofilt/makefile.mk b/shell/source/win32/shlxthandler/ooofilt/makefile.mk new file mode 100644 index 000000000000..9111069ab889 --- /dev/null +++ b/shell/source/win32/shlxthandler/ooofilt/makefile.mk @@ -0,0 +1,141 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/..$/..$/.. +PRJNAME=shell +TARGET=ooofilt +LIBTARGET=NO +ENABLE_EXCEPTIONS=TRUE +USE_DEFFILE=TRUE + +# Do not use the dynamic STLport library. +NO_DEFAULT_STL=YES + +# Do not use the uwinapi library +UWINAPILIB= + + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +CFLAGS+=-DISOLATION_AWARE_ENABLED -DWIN32_LEAN_AND_MEAN -DXML_UNICODE -D_NTSDK -DUNICODE -D_UNICODE -D_WIN32_WINNT=0x0501 +CFLAGS+=-wd4710 -wd4711 -wd4514 -wd4619 -wd4217 -wd4820 +CDEFS+=-D_WIN32_IE=0x501 +# SCPCDEFS+=-D_STLP_USE_STATIC_LIB + +# --- Files -------------------------------------------------------- + +SLOFILES=$(SLO)$/ooofilt.obj\ + $(SLO)$/propspec.obj\ + $(SLO)$/stream_helper.obj + +# $(SLO)$/utilities.obj +# $(SLO)$/dbgmacros.obj + +SHL1TARGET=$(TARGET) +.IF "$(COM)"=="GCC" +SHL1STDLIBS=$(ZLIB3RDLIB) $(EXPAT3RDLIB) +SHL1LIBS= +.ELSE +SHL1STDLIBS= +SHL1LIBS=$(SOLARLIBDIR)$/zlib.lib\ + $(SOLARLIBDIR)$/expat_xmlparse.lib\ + $(SOLARLIBDIR)$/expat_xmltok.lib +.ENDIF +SHL1STDLIBS+=$(OLE32LIB)\ + $(ADVAPI32LIB)\ + $(COMCTL32LIB)\ + $(UUIDLIB)\ + $(SHELL32LIB)\ + $(KERNEL32LIB)\ + $(OLDNAMESLIB) + +.IF "$(COM)"!="GCC" +SHL1STDLIBS+=msvcprt.lib + +.IF "$(PRODUCT)"!="full" +SHL1STDLIBS+=msvcrt.lib +.ENDIF +.ENDIF + + +# $(LIBSTLPORTST) + +SHL1LIBS+=$(SLB)$/util.lib\ + $(SLB)$/ooofilereader.lib + +SHL1DEPN= +SHL1OBJS=$(SLOFILES) +SHL1DEF=$(MISC)$/$(SHL1TARGET).def +DEF1NAME=$(SHL1TARGET) +DEF1EXPORTFILE=exports.dxp + + +.IF "$(BUILD_X64)"!="" +#---------------------------- x64 ------------------------- +CFLAGS_X64+=-DISOLATION_AWARE_ENABLED -DWIN32_LEAN_AND_MEAN -DXML_UNICODE -D_NTSDK -DUNICODE -D_UNICODE -D_WIN32_WINNT=0x0501 +CFLAGS_X64+=-wd4710 -wd4711 -wd4514 -wd4619 -wd4217 -wd4820 +CDEFS_X64+=-D_WIN32_IE=0x501 +USE_DEFFILE_X64=TRUE + +SLOFILES_X64=$(SLO_X64)$/ooofilt.obj\ + $(SLO_X64)$/propspec.obj\ + $(SLO_X64)$/stream_helper.obj + +SHL1TARGET_X64=$(TARGET) + +SHL1LIBS_X64=$(SOLARLIBDIR_X64)$/zlib.lib\ + $(SOLARLIBDIR_X64)$/expat_xmlparse.lib\ + $(SOLARLIBDIR_X64)$/expat_xmltok.lib + +SHL1STDLIBS_X64+=$(OLE32LIB_X64)\ + $(ADVAPI32LIB_X64)\ + $(COMCTL32LIB_X64)\ + $(UUIDLIB_X64)\ + $(USER32LIB_X64) \ + $(SHELL32LIB_X64)\ + $(KERNEL32LIB_X64)\ + $(MSVCPRT_X64) \ + $(MSVCRT_X64) \ + $(OLDNAMESLIB_X64) + +SHL1LIBS_X64+=$(SLB_X64)$/util.lib\ + $(SLB_X64)$/ooofilereader.lib +SHL1OBJS_X64=$(SLOFILES_X64) +SHL1DEF_X64=$(MISC_X64)$/$(SHL1TARGET_X64).def +DEF1NAME_X64=$(SHL1TARGET_X64) +DEF1EXPORTFILE_X64=exports.dxp +.ENDIF # "$(BUILD_X64)"!="" + +# --- Targets ------------------------------------------------------ + +.INCLUDE : set_wntx64.mk +.INCLUDE : target.mk +INCLUDE!:=$(subst,/stl, $(INCLUDE)) +.EXPORT : INCLUDE +.INCLUDE : tg_wntx64.mk diff --git a/shell/source/win32/shlxthandler/ooofilt/ooofilt.cxx b/shell/source/win32/shlxthandler/ooofilt/ooofilt.cxx new file mode 100755 index 000000000000..30151fc5dd75 --- /dev/null +++ b/shell/source/win32/shlxthandler/ooofilt/ooofilt.cxx @@ -0,0 +1,1491 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_shell.hxx" + +//-------------------------------------------------------------------------- +// File: ooofilt.cxx +// +// Contents: Filter Implementation for OpenOffice.Org Document using +// Indexing Service +// +// Summary: The OpenOffice.org filter reads OpenOffice.org files (with the +// extension .sxw .sxi, etc) and extract their content, author, +// keywords,subject,comments and title to be filtered. +// +// Platform: Windows 2000, Windows XP +// +//-------------------------------------------------------------------------- +#include "internal/contentreader.hxx" +#include "internal/metainforeader.hxx" +//#include "internal/utilities.hxx" +#include "internal/registry.hxx" +#include "internal/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 OpenOffice.org filter declarations +// propspec.hxx PROPSPEC +// +//-------------------------------------------------------------------------- + +#if defined _MSC_VER +#pragma warning(push, 1) +#endif +#include <windows.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif +#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" +#ifdef __MINGW32__ +#include <algorithm> +using ::std::min; +#endif + +#include "internal/stream_helper.hxx" + +//C------------------------------------------------------------------------- +// +// Class: COooFilter +// +// Summary: Implements OpenOffice.org filter class +// +//-------------------------------------------------------------------------- +//M------------------------------------------------------------------------- +// +// Method: COooFilter::COooFilter +// +// Summary: Class constructor +// +// Arguments: void +// +// Purpose: Manages global instance count +// +//-------------------------------------------------------------------------- +COooFilter::COooFilter() : + m_lRefs(1), + m_pContentReader(NULL), + m_pMetaInfoReader(NULL), + m_eState(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(0), + m_pStream(NULL) + +{ + 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; + + if (m_pContentReader) + delete m_pContentReader; + if (m_pMetaInfoReader) + delete m_pMetaInfoReader; + + 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 +// +//-------------------------------------------------------------------------- +SCODE STDMETHODCALLTYPE COooFilter::QueryInterface( + REFIID riid, + void ** ppvObject) +{ + IUnknown *pUnkTemp = 0; + if ( IID_IFilter == riid ) + pUnkTemp = (IUnknown *)(IFilter *)this; + else if ( IID_IPersistFile == riid ) + pUnkTemp = (IUnknown *)(IPersistFile *)this; + else if ( IID_IPersist == riid ) + pUnkTemp = (IUnknown *)(IPersist *)(IPersistFile *)this; + else if (IID_IPersistStream == riid) + pUnkTemp = (IUnknown *)(IPersistStream *)this; + else if ( IID_IUnknown == riid ) + pUnkTemp = (IUnknown *)(IPersist *)(IPersistFile *)this; + else + { + *ppvObject = NULL; + return E_NOINTERFACE; + } + *ppvObject = (void *)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 OpenOffice.org 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 = 0; + m_cAttributes = 0; + } + if( 0 < cAttributes ) + { + // Filter properties specified in aAttributes + if ( 0 == aAttributes ) + return E_INVALIDARG; + m_pAttributes = new CFullPropSpec[cAttributes]; + m_cAttributes = cAttributes; + // Is caller want to filter contents? + CFullPropSpec *pAttrib = (CFullPropSpec *) 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 = FilteringContent; + m_ulUnicodeCharsRead = 0; + m_ChunkPosition = 0; + } + else + { + m_fEof = TRUE; + m_eState = 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 FilteringContent: + { + // Read Unicodes from buffer. + if( m_ChunkPosition == m_pContentReader ->getChunkBuffer().size() ) + { + m_ulUnicodeBufferLen=0; + m_fEof = TRUE; + } + + if ( !m_fContents || m_fEof ) + { + m_eState = FilteringProperty; + continue; + } + m_pwsBuffer = m_pContentReader -> getChunkBuffer()[m_ChunkPosition].second; + m_ulUnicodeBufferLen = 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 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; + } + } + default: + return E_FAIL; + }//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 FilteringProperty: + return FILTER_E_NO_TEXT; + case 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 ); + ZeroMemory(awcBuffer, sizeof(awcBuffer)); + wmemcpy( awcBuffer, m_pwsBuffer.c_str() + m_ulUnicodeCharsRead, ulToCopy ); + m_ulUnicodeCharsRead += ulToCopy; + *pcwcBuffer = ulToCopy; + if ( m_ulUnicodeBufferLen == m_ulUnicodeCharsRead ) + { + m_ulUnicodeCharsRead = 0; + m_ulUnicodeBufferLen = 0; + return FILTER_S_LAST_TEXT; + } + return S_OK; + } + default: + return E_FAIL; + } +} +//M------------------------------------------------------------------------- +// +// Method: GetMetaInfoNameFromPropertyId +// +// Summary: helper function to convert PropertyID into respective +// MetaInfo names. +// +// Arguments: ulPropID +// [in] property ID +// +// Returns: corresponding metainfo names. +// +//-------------------------------------------------------------------------- + +::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 properites 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 == FilteringContent) + return FILTER_E_NO_VALUES; + else if (m_eState == FilteringProperty) + { + if ( m_cAttributes == 0 || ( m_ulCurrentPropertyNum == m_ulPropertyNum ) ) + return FILTER_E_NO_MORE_VALUES; + PROPVARIANT *pPropVar = (PROPVARIANT *) CoTaskMemAlloc( sizeof (PROPVARIANT) ); + if ( pPropVar == 0 ) + 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 == 0) + { + CoTaskMemFree(pPropVar); + return E_OUTOFMEMORY; + } + wmemcpy(pPropVar->pwszVal, wsTagData.c_str(), cw); + *ppPropValue = pPropVar; + m_ulCurrentPropertyNum = m_ulPropertyNum; + return S_OK; + } + else + return E_FAIL; +} +//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) +//-------------------------------------------------------------------------- +SCODE 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) +// +//-------------------------------------------------------------------------- +SCODE 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) +// +//-------------------------------------------------------------------------- +SCODE STDMETHODCALLTYPE COooFilter::Load(LPCWSTR 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 + { + if (m_pMetaInfoReader) + delete m_pMetaInfoReader; + m_pMetaInfoReader = new CMetaInfoReader(WStringToString(m_pwszFileName)); + + if (m_pContentReader) + delete m_pContentReader; + m_pContentReader = new CContentReader(WStringToString(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) +// +//-------------------------------------------------------------------------- +SCODE STDMETHODCALLTYPE COooFilter::Save(LPCWSTR /*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 +// +//-------------------------------------------------------------------------- +SCODE STDMETHODCALLTYPE COooFilter::SaveCompleted(LPCWSTR /*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 +// +// +//-------------------------------------------------------------------------- +SCODE STDMETHODCALLTYPE COooFilter::Load(IStream *pStm) +{ + zlib_filefunc_def z_filefunc; + + m_pStream = PrepareIStream( pStm, z_filefunc ); + + try + { + if (m_pMetaInfoReader) + delete m_pMetaInfoReader; + m_pMetaInfoReader = new CMetaInfoReader((void*)m_pStream, &z_filefunc); + + if (m_pContentReader) + delete m_pContentReader; + m_pContentReader = new CContentReader((void*)m_pStream, m_pMetaInfoReader->getDefaultLocale(), &z_filefunc); + } + 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 neede to save the object. +// +// Arguments: pcbSize +// [out] Pointer to a 64 bit unsigned int indicating the size needed +// +// Returns: E_NOTIMPL +// +// +//-------------------------------------------------------------------------- +SCODE 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 +// +// +//-------------------------------------------------------------------------- +SCODE 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 +// +//------------------------------------------------------------------------- +SCODE STDMETHODCALLTYPE COooFilter::GetCurFile(LPWSTR * ppszFileName) +{ + if ( EMPTY_STRING == m_pwszFileName ) + return E_FAIL; + else + *ppszFileName = (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 +// +//-------------------------------------------------------------------------- +SCODE STDMETHODCALLTYPE COooFilterCF::QueryInterface(REFIID riid, void ** ppvObject) +{ + IUnknown *pUnkTemp; + + if ( IID_IClassFactory == riid ) + pUnkTemp = (IUnknown *)(IClassFactory *)this; + else if ( IID_IUnknown == riid ) + pUnkTemp = (IUnknown *)this; + else + { + *ppvObject = NULL; + return E_NOINTERFACE; + } + *ppvObject = (void *)pUnkTemp; + pUnkTemp->AddRef(); + return S_OK; +} +//M------------------------------------------------------------------------- +// +// Method: COooFilterCF::AddRef (IUknown::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 OpenOffice.org 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 +// OpenOffice.org filter object was successfully created +// CLASS_E_NOAGGREGATION +// pUnkOuter parameter was non-NULL +// E_NOINTERFACE +// (not implemented) +// E_OUTOFMEMORY +// OpenOffice.org filter object could not be created +// due to insufficient memory +// E_UNEXPECTED +// Unsuccessful due to an unexpected condition +// +//-------------------------------------------------------------------------- +SCODE STDMETHODCALLTYPE COooFilterCF::CreateInstance( + IUnknown * pUnkOuter, + REFIID riid, + void * * ppvObject) +{ + COooFilter *pIUnk = 0; + if ( 0 != pUnkOuter ) + return CLASS_E_NOAGGREGATION; + pIUnk = new COooFilter(); + if ( 0 != pIUnk ) + { + if ( SUCCEEDED( pIUnk->QueryInterface( riid , ppvObject ) ) ) + { + // Release extra refcount from QueryInterface + pIUnk->Release(); + } + else + { + delete pIUnk; + return E_UNEXPECTED; + } + } + else + return E_OUTOFMEMORY; + 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) +// +//-------------------------------------------------------------------------- +SCODE 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 OpenOffice.org 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 OpenOffice.org 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" SCODE STDMETHODCALLTYPE DllGetClassObject( + REFCLSID cid, + REFIID iid, + void ** ppvObj +) +{ + IUnknown *pResult = 0; + + if ( CLSID_COooFilter == cid ) + pResult = (IUnknown *) new COooFilterCF; + else + return CLASS_E_CLASSNOTAVAILABLE; + if ( 0 != pResult ) + { + if( SUCCEEDED( pResult->QueryInterface( iid, ppvObj ) ) ) + // Release extra refcount from QueryInterface + pResult->Release(); + else + { + delete pResult; + return E_UNEXPECTED; + } + } + else + return E_OUTOFMEMORY; + 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" SCODE 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) +// +//-------------------------------------------------------------------------- + + +//F------------------------------------------------------------------------- +// +// helper functions to register the Indexing Service. +// +//-------------------------------------------------------------------------- + +namespace /* private */ +{ + const char* GUID_PLACEHOLDER = "{GUID}"; + const char* GUID_PERSIST_PLACEHOLDER = "{GUIDPERSIST}"; + const char* EXTENSION_PLACEHOLDER = "{EXT}"; + const char* FORWARDKEY_PLACEHOLDER = "{FWDKEY}"; + + const char* CLSID_GUID_INPROC_ENTRY = "CLSID\\{GUID}\\InProcServer32"; + const char* CLSID_GUID_ENTRY = "CLSID\\{GUID}"; + const char* CLSID_GUID_PERSIST_ADDIN_ENTRY = "CLSID\\{GUID}\\PersistentAddinsRegistered\\{GUIDPERSIST}"; + const char* CLSID_PERSIST_ENTRY = "CLSID\\{GUID}\\PersistentHandler"; + const char* EXT_PERSIST_ENTRY = "{EXT}\\PersistentHandler"; + + const char* INDEXING_FILTER_DLLSTOREGISTER = "SYSTEM\\CurrentControlSet\\Control\\ContentIndex"; + + //--------------------------- + // "String Placeholder" -> + // "String Replacement" + //--------------------------- + + void SubstitutePlaceholder(std::string& String, const std::string& Placeholder, const std::string& Replacement) + { + std::string::size_type idx = String.find(Placeholder); + std::string::size_type len = Placeholder.length(); + + while (std::string::npos != idx) + { + String.replace(idx, len, Replacement); + idx = String.find(Placeholder); + } + } + + //---------------------------------------------- + // Make the registry entry and set Filter Handler + // HKCR\CLSID\{7BC0E710-5703-45be-A29D-5D46D8B39262} = OpenOffice.org Filter + // InProcServer32 (Default) = Path\ooofilt.dll + // ThreadingModel = Both + //---------------------------------------------- + + HRESULT RegisterFilterHandler(const char* FilePath, const CLSID& FilterGuid) + { + std::string ClsidEntry = CLSID_GUID_ENTRY; + SubstitutePlaceholder(ClsidEntry, GUID_PLACEHOLDER, ClsidToString(FilterGuid)); + + if (!SetRegistryKey(HKEY_CLASSES_ROOT, ClsidEntry.c_str(), "", "OpenOffice.org Filter")) + return E_FAIL; + + ClsidEntry = CLSID_GUID_INPROC_ENTRY; + SubstitutePlaceholder(ClsidEntry, GUID_PLACEHOLDER, ClsidToString(FilterGuid)); + + if (!SetRegistryKey(HKEY_CLASSES_ROOT, ClsidEntry.c_str(), "", FilePath)) + return E_FAIL; + + if (!SetRegistryKey(HKEY_CLASSES_ROOT, ClsidEntry.c_str(), "ThreadingModel", "Both")) + return E_FAIL; + + return S_OK; + } + + //---------------------------------------------- + // Make the registry entry and set Persistent Handler + // HKCR\CLSID\{7BC0E713-5703-45be-A29D-5D46D8B39262} = OpenOffice.org Persistent Handler + // PersistentAddinsRegistered + // {89BCB740-6119-101A-BCB7-00DD010655AF} = {7BC0E710-5703-45be-A29D-5D46D8B39262} + //---------------------------------------------- + + HRESULT RegisterPersistentHandler(const CLSID& FilterGuid, const CLSID& PersistentGuid) + { + std::string ClsidEntry_Persist = CLSID_GUID_ENTRY; + SubstitutePlaceholder(ClsidEntry_Persist, GUID_PLACEHOLDER, ClsidToString(PersistentGuid)); + + + if (!SetRegistryKey(HKEY_CLASSES_ROOT, ClsidEntry_Persist.c_str(), "", "OpenOffice.org Persistent Handler")) + return E_FAIL; + + // Add missing entry + std::string ClsidEntry_Persist_Entry = CLSID_PERSIST_ENTRY; + SubstitutePlaceholder(ClsidEntry_Persist_Entry, + GUID_PLACEHOLDER, + ClsidToString(PersistentGuid)); + + if (!SetRegistryKey(HKEY_CLASSES_ROOT, ClsidEntry_Persist_Entry.c_str(), "", ClsidToString(PersistentGuid).c_str())) + return E_FAIL; + + std::string ClsidEntry_Persist_Addin = CLSID_GUID_PERSIST_ADDIN_ENTRY; + SubstitutePlaceholder(ClsidEntry_Persist_Addin, + GUID_PLACEHOLDER, + ClsidToString(PersistentGuid)); + SubstitutePlaceholder(ClsidEntry_Persist_Addin, + GUID_PERSIST_PLACEHOLDER, + ClsidToString(CLSID_PERSISTENT_HANDLER_ADDIN)); + + if (!SetRegistryKey(HKEY_CLASSES_ROOT, ClsidEntry_Persist_Addin.c_str(), "", ClsidToString(FilterGuid).c_str() )) + return E_FAIL; + + return S_OK; + } + + //--------------------------- + // Unregister Filter Handler or persistent handler + //--------------------------- + + HRESULT UnregisterHandler(const CLSID& Guid) + { + std::string tmp = "CLSID\\"; + tmp += ClsidToString(Guid); + return DeleteRegistryKey(HKEY_CLASSES_ROOT, tmp.c_str()) ? S_OK : E_FAIL; + } + + //--------------------------- + // Register Indexing Service ext and class. + // HKCR\{EXT}\PersistentHandler = {7BC0E713-5703-45be-A29D-5D46D8B39262} + // HKCR\{GUID\PersistentHandler = {7BC0E713-5703-45be-A29D-5D46D8B39262} + //--------------------------- + + HRESULT RegisterSearchHandler(const char* ModuleFileName) + { + if (FAILED(RegisterFilterHandler(ModuleFileName, CLSID_FILTER_HANDLER))) + return E_FAIL; + + if (FAILED(RegisterPersistentHandler(CLSID_FILTER_HANDLER, CLSID_PERSISTENT_HANDLER ))) + return E_FAIL; + + std::string sExtPersistEntry; + + for(size_t i = 0; i < OOFileExtensionTableSize; i++) + { + // first, register extension. + sExtPersistEntry = EXT_PERSIST_ENTRY; + SubstitutePlaceholder(sExtPersistEntry, EXTENSION_PLACEHOLDER, OOFileExtensionTable[i].ExtensionAnsi); + if (!SetRegistryKey(HKEY_CLASSES_ROOT, + sExtPersistEntry.c_str(), + "", + ClsidToString(CLSID_PERSISTENT_HANDLER).c_str())) + return E_FAIL; + + // second, register class. + char extClassName[MAX_PATH]; + if (QueryRegistryKey(HKEY_CLASSES_ROOT, OOFileExtensionTable[i].ExtensionAnsi, "", extClassName,MAX_PATH)) + { + ::std::string extCLSIDName( extClassName ); + extCLSIDName += "\\CLSID"; + char extCLSID[MAX_PATH]; + + if (QueryRegistryKey( HKEY_CLASSES_ROOT, extCLSIDName.c_str(), "", extCLSID, MAX_PATH)) + { + std::string ClsidEntry_CLSID_Persist = CLSID_PERSIST_ENTRY; + SubstitutePlaceholder(ClsidEntry_CLSID_Persist, + GUID_PLACEHOLDER, + extCLSID); + + if (!SetRegistryKey(HKEY_CLASSES_ROOT, + ClsidEntry_CLSID_Persist.c_str(), + "", + ClsidToString(CLSID_PERSISTENT_HANDLER).c_str() )) + return E_FAIL; + } + } + } + + return S_OK; + } + + // Register Indexing Service ext and class. + HRESULT UnregisterSearchHandler() + { + std::string sExtPersistEntry; + + for (size_t i = 0; i < OOFileExtensionTableSize; i++) + { + // first, unregister extension + sExtPersistEntry = EXT_PERSIST_ENTRY; + SubstitutePlaceholder(sExtPersistEntry, EXTENSION_PLACEHOLDER, OOFileExtensionTable[i].ExtensionAnsi); + DeleteRegistryKey(HKEY_CLASSES_ROOT, sExtPersistEntry.c_str()); + + // second, unregister class + char extClassName[MAX_PATH]; + if (QueryRegistryKey(HKEY_CLASSES_ROOT, OOFileExtensionTable[i].ExtensionAnsi, "", extClassName,MAX_PATH)) + { + ::std::string extCLSIDName( extClassName ); + extCLSIDName += "\\CLSID"; + char extCLSID[MAX_PATH]; + + if (QueryRegistryKey( HKEY_CLASSES_ROOT, extCLSIDName.c_str(), "", extCLSID, MAX_PATH)) + { + std::string ClsidEntry_CLSID_Persist = CLSID_PERSIST_ENTRY; + SubstitutePlaceholder(ClsidEntry_CLSID_Persist, + GUID_PLACEHOLDER, + extCLSID); + + DeleteRegistryKey(HKEY_CLASSES_ROOT, ClsidEntry_CLSID_Persist.c_str()); + } + } + } + + return ((UnregisterHandler(CLSID_FILTER_HANDLER)==S_OK) && (UnregisterHandler(CLSID_PERSISTENT_HANDLER)==S_OK))?S_OK:E_FAIL; + } + + //--------------------------- + // add or remove an entry to DllsToRegister entry of Indexing + // Filter to let Indexing Service register our filter automatically + // each time. + //--------------------------- + HRESULT AddOrRemoveDllsToRegisterList( const ::std::string & DllPath, bool isAdd ) + { + char DllsToRegisterList[4096]; + if (QueryRegistryKey(HKEY_LOCAL_MACHINE, + INDEXING_FILTER_DLLSTOREGISTER, + "DLLsToRegister", + DllsToRegisterList, + 4096)) + { + char * pChar = DllsToRegisterList; + for ( ; *pChar != '\0' || *(pChar +1) != '\0'; pChar++) + if ( *pChar == '\0') + *pChar = ';'; + *pChar = ';'; + *(pChar+1) = '\0'; + + ::std::string DllList(DllsToRegisterList); + if ( ( isAdd )&&( DllList.find( DllPath ) == ::std::string::npos ) ) + DllList.append( DllPath ); + else if ( ( !isAdd )&&( DllList.find( DllPath ) != ::std::string::npos ) ) + DllList.erase( DllList.find( DllPath )-1, DllPath.length()+1 ); + else + return S_OK; + + pChar = DllsToRegisterList; + for ( size_t nChar = 0; nChar < DllList.length(); pChar++,nChar++) + { + if ( DllList[nChar] == ';') + *pChar = '\0'; + else + *pChar = DllList[nChar]; + } + *pChar = *( pChar+1 ) ='\0'; + + HKEY hSubKey; + int rc = RegCreateKeyExA(HKEY_LOCAL_MACHINE, + INDEXING_FILTER_DLLSTOREGISTER, + 0, + "", + REG_OPTION_NON_VOLATILE, + KEY_WRITE, + 0, + &hSubKey, + 0); + + if (ERROR_SUCCESS == rc) + { + rc = RegSetValueExA( hSubKey, + "DLLsToRegister", + 0, + REG_MULTI_SZ, + reinterpret_cast<const BYTE*>(DllsToRegisterList), + DllList.length() + 2); + + RegCloseKey(hSubKey); + } + + return (ERROR_SUCCESS == rc)?S_OK:E_FAIL; + } + + return S_OK; + } + +} // namespace /* private */ + +STDAPI DllRegisterServer() +{ + /* + TCHAR ModuleFileName[MAX_PATH]; + + GetModuleFileName( + GetModuleHandle(MODULE_NAME_FILTER), + ModuleFileName, + sizeof(ModuleFileName)); + + HRESULT hr = S_OK; + + +// register search handler +#ifdef UNICODE + if (FAILED(RegisterSearchHandler(WStringToString(ModuleFileName).c_str()))) + hr = E_FAIL; + if (FAILED(AddOrRemoveDllsToRegisterList(WStringToString(ModuleFileName).c_str(), true))) + hr = E_FAIL; +#else + if (FAILED(RegisterSearchHandler(ModuleFileName))) + hr = E_FAIL; + if (FAILED(AddOrRemoveDllsToRegisterList(ModuleFileName, true))) + hr = E_FAIL; +#endif + + + return hr; + */ + return S_OK; +} + +//--------------------------- +// +//--------------------------- + +STDAPI DllUnregisterServer() +{ + /* + TCHAR ModuleFileName[MAX_PATH]; + + GetModuleFileName( + GetModuleHandle(MODULE_NAME_FILTER), + ModuleFileName, + sizeof(ModuleFileName)); + + HRESULT hr = S_OK; + + // unregister search handler + if (FAILED(UnregisterSearchHandler())) + hr = E_FAIL; + +#ifdef UNICODE + if (FAILED(AddOrRemoveDllsToRegisterList(WStringToString(ModuleFileName).c_str(),false))) + hr = E_FAIL; +#else + if (FAILED(AddOrRemoveDllsToRegisterList(ModuleFileName, false))) + hr = E_FAIL; +#endif + + return hr; + */ + return S_OK; +} diff --git a/shell/source/win32/shlxthandler/ooofilt/ooofilt.hxx b/shell/source/win32/shlxthandler/ooofilt/ooofilt.hxx new file mode 100755 index 000000000000..b68863523b28 --- /dev/null +++ b/shell/source/win32/shlxthandler/ooofilt/ooofilt.hxx @@ -0,0 +1,218 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "internal/types.hxx" + +//+------------------------------------------------------------------------- +// +// Contents: OpenOffice.org filter declarations +// +// Platform: Windows 2000, Windows XP +// +//-------------------------------------------------------------------------- + +#pragma once + +//+------------------------------------------------------------------------- +// +// forward declaration +// +//-------------------------------------------------------------------------- +class CContentReader; +class CMetaInfoReader; +class CFullPropSpec; + +//+------------------------------------------------------------------------- +// +// Global definitions +// +//-------------------------------------------------------------------------- + +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 OpenOffice.org filter +// +//-------------------------------------------------------------------------- + +// OooFilter Class ID +// {7BC0E710-5703-45be-A29D-5D46D8B39262} +GUID const CLSID_COooFilter = +{ + 0x7bc0e710, + 0x5703, + 0x45be, + { 0xa2, 0x9d, 0x5d, 0x46, 0xd8, 0xb3, 0x92, 0x62 } +}; + +// OpenOffice.org 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}}; + +// OpenOffice.org 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}}; + +// OpenOffice.org 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 FilterState +{ + FilteringContent, // Filtering the content property + FilteringProperty // Filtering the pseudo property +}; +class COooFilter : public IFilter, public IPersistFile, public IPersistStream +{ +public: + // From IUnknown + virtual SCODE STDMETHODCALLTYPE QueryInterface( + REFIID riid, + void ** ppvObject); + virtual ULONG STDMETHODCALLTYPE AddRef(); + virtual ULONG STDMETHODCALLTYPE Release(); + + // From IFilter + virtual SCODE STDMETHODCALLTYPE Init( + ULONG grfFlags, + ULONG cAttributes, + FULLPROPSPEC const * aAttributes, + ULONG * pFlags); + virtual SCODE STDMETHODCALLTYPE GetChunk( + STAT_CHUNK * pStat); + virtual SCODE STDMETHODCALLTYPE GetText( + ULONG * pcwcBuffer, + WCHAR * awcBuffer); + + virtual SCODE STDMETHODCALLTYPE GetValue( + PROPVARIANT ** ppPropValue); + + virtual SCODE STDMETHODCALLTYPE BindRegion( + FILTERREGION origPos, + REFIID riid, + void ** ppunk); + + // From IPersistFile + virtual SCODE STDMETHODCALLTYPE GetClassID( + CLSID * pClassID); + virtual SCODE STDMETHODCALLTYPE IsDirty(); + virtual SCODE STDMETHODCALLTYPE Load( + LPCWSTR pszFileName, + DWORD dwMode); + virtual SCODE STDMETHODCALLTYPE Save( + LPCWSTR pszFileName, + BOOL fRemember); + + virtual SCODE STDMETHODCALLTYPE SaveCompleted( + LPCWSTR pszFileName); + + virtual SCODE STDMETHODCALLTYPE GetCurFile( + LPWSTR * ppszFileName); + + // From IPersistStream + virtual SCODE STDMETHODCALLTYPE Load( + IStream *pStm); + + virtual SCODE STDMETHODCALLTYPE Save( + IStream *pStm, + BOOL fClearDirty); + + virtual SCODE STDMETHODCALLTYPE GetSizeMax( + ULARGE_INTEGER *pcbSize); + + +private: + friend class COooFilterCF; + + COooFilter(); + virtual ~COooFilter(); + + long m_lRefs; // Reference count + CContentReader * m_pContentReader; // A content reader that retrive document content. + CMetaInfoReader * m_pMetaInfoReader; // A metainfo reader that retrive 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 + IStream * m_pStream; + +}; + +//C------------------------------------------------------------------------- +// +// Class: COooFilterCF +// +// Purpose: Implements class factory for OpenOffice.org filter +// +//-------------------------------------------------------------------------- + +class COooFilterCF : public IClassFactory +{ +public: + // From IUnknown + virtual SCODE STDMETHODCALLTYPE QueryInterface( + REFIID riid, + void ** ppvObject); + + virtual ULONG STDMETHODCALLTYPE AddRef(); + virtual ULONG STDMETHODCALLTYPE Release(); + + // From IClassFactory + virtual SCODE STDMETHODCALLTYPE CreateInstance( + IUnknown * pUnkOuter, + REFIID riid, void ** ppvObject); + + virtual SCODE STDMETHODCALLTYPE LockServer( + BOOL fLock); + +private: + friend SCODE STDMETHODCALLTYPE DllGetClassObject( + REFCLSID cid, + REFIID iid, + void ** ppvObj); + + COooFilterCF(); + virtual ~COooFilterCF(); + + long m_lRefs; // Reference count +}; diff --git a/shell/source/win32/shlxthandler/ooofilt/propspec.cxx b/shell/source/win32/shlxthandler/ooofilt/propspec.cxx new file mode 100644 index 000000000000..fd7a24f2711a --- /dev/null +++ b/shell/source/win32/shlxthandler/ooofilt/propspec.cxx @@ -0,0 +1,238 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_shell.hxx" + +//+------------------------------------------------------------------------- +// +// File: propspec.cxx +// +// Contents: C++ wrappers for FULLPROPSPEC +// +//-------------------------------------------------------------------------- +#if defined _MSC_VER +#pragma warning(push, 1) +#endif +#include <windows.h> +#ifdef _MSC_VER +#pragma warning(disable: 4512) +#endif +#include <filter.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif + +#include "propspec.hxx" + +//GUID CLSID_Storage = PSGUID_STORAGE; +// +// +//refer to ms-help://MS.VSCC/MS.MSDNVS.2052/com/stgasstg_7agk.htm +//FMTID_SummaryInformation +// +//GUID CLSID_SummaryInforation = { +// 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() +{ + memset( &_guidPropSet, 0, sizeof( _guidPropSet ) ); + _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 = 0; + } + else + { + _psProperty.propid = src._psProperty.propid; + } +} +inline void * operator new( size_t /*size*/, void * p ) +{ + return( p ); +} +//+------------------------------------------------------------------------- +// +// Member: CFullPropSpec::operator=, public +// +// Synopsis: Assignment operator +// +// Arguments: [Property] -- Source property +// +//-------------------------------------------------------------------------- +CFullPropSpec & CFullPropSpec::operator=( CFullPropSpec const & Property ) +{ + // Clean up. + this->CFullPropSpec::~CFullPropSpec(); + +#ifdef _MSC_VER +#pragma warning( disable : 4291 ) // unmatched operator new +#endif + new (this) CFullPropSpec( Property ); +#ifdef _MSC_VER +#pragma warning( default : 4291 ) +#endif + return *this; +} +CFullPropSpec::~CFullPropSpec() +{ + if ( _psProperty.ulKind == PRSPEC_LPWSTR && + _psProperty.lpwstr ) + { + CoTaskMemFree( _psProperty.lpwstr ); + } +} +void CFullPropSpec::SetProperty( PROPID pidProperty ) +{ + if ( _psProperty.ulKind == PRSPEC_LPWSTR && + 0 != _psProperty.lpwstr ) + { + CoTaskMemFree( _psProperty.lpwstr ); + } + _psProperty.ulKind = PRSPEC_PROPID; + _psProperty.propid = pidProperty; +} +BOOL CFullPropSpec::SetProperty( WCHAR const * wcsProperty ) +{ + if ( _psProperty.ulKind == PRSPEC_LPWSTR && + 0 != _psProperty.lpwstr ) + { + CoTaskMemFree( _psProperty.lpwstr ); + } + _psProperty.ulKind = PRSPEC_LPWSTR; + int len = (int) ( (wcslen( wcsProperty ) + 1) * sizeof( WCHAR ) ); + _psProperty.lpwstr = (WCHAR *)CoTaskMemAlloc( len ); + if ( 0 != _psProperty.lpwstr ) + { + memcpy( _psProperty.lpwstr, + wcsProperty, + len ); + return( TRUE ); + } + else + { + _psProperty.lpwstr = 0; + return( FALSE ); + } +} +int CFullPropSpec::operator==( CFullPropSpec const & prop ) const +{ + if ( memcmp( &prop._guidPropSet, + &_guidPropSet, + sizeof( _guidPropSet ) ) != 0 || + prop._psProperty.ulKind != _psProperty.ulKind ) + { + return( 0 ); + } + switch( _psProperty.ulKind ) + { + case PRSPEC_LPWSTR: + return( _wcsicmp( GetPropertyName(), prop.GetPropertyName() ) == 0 ); + break; + case PRSPEC_PROPID: + return( GetPropertyPropid() == prop.GetPropertyPropid() ); + break; + default: + return( 0 ); + break; + } +} +int CFullPropSpec::operator!=( CFullPropSpec const & prop ) const +{ + if (*this == prop) + return( 0 ); + else + return( 1 ); +} + diff --git a/shell/source/win32/shlxthandler/ooofilt/propspec.hxx b/shell/source/win32/shlxthandler/ooofilt/propspec.hxx new file mode 100644 index 000000000000..ba4c34233d64 --- /dev/null +++ b/shell/source/win32/shlxthandler/ooofilt/propspec.hxx @@ -0,0 +1,159 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +//+------------------------------------------------------------------------- +// +// File: propspec.hxx +// +// Contents: C++ wrapper(s) for FULLPROPSPEC +// +//------------------------------------------------------------------------- +#pragma once +#if defined _MSC_VER +#pragma warning(push, 1) +#endif +#include <windows.h> +#include <ole2.h> +#include <ntquery.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif +//+------------------------------------------------------------------------- +// +// Declare: CLSID_SummaryInforation, GUID +// CLSID_Storage, GUID +// +// Contents: Definitions of OpenOffice.org Document properties +// +//-------------------------------------------------------------------------- + +//extern GUID CLSID_Storage; +// +//extern GUID CLSID_SummaryInformation; +//const PID_TITLE = PIDSI_TITLE; // 2; +//const PID_SUBJECT = PIDSI_SUBJECT; // 3; +//const PID_AUTHOR = PIDSI_AUTHOR; // 4; +//const PID_KEYWORDS = PIDSI_KEYWORDS; // 5; +//const PID_COMMENTS = PIDSI_COMMENTS; //6; +//const PID_REVNUMBER = PIDSI_REVNUMBER; //9; +//const PID_WORDCOUNT = PIDSI_WORDCOUNT; //f; +//+------------------------------------------------------------------------- +// +// 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 ); + inline void * operator new( size_t size, void * p ); + void operator delete( void * p ); + inline FULLPROPSPEC * CastToStruct(); + inline FULLPROPSPEC const * CastToStruct() const; + // Comparators + int operator==( CFullPropSpec const & prop ) const; + int 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 new( size_t /*size*/, void * p ) +{ + return( p ); +} +inline void CFullPropSpec::operator delete( void * p ) +{ + if ( p ) + CoTaskMemFree( p ); +} +inline BOOL CFullPropSpec::IsValid() const +{ + return ( _psProperty.ulKind == PRSPEC_PROPID || + 0 != _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 ); +} + + + + diff --git a/shell/source/win32/shlxthandler/ooofilt/stream_helper.cxx b/shell/source/win32/shlxthandler/ooofilt/stream_helper.cxx new file mode 100755 index 000000000000..e12f95a88e50 --- /dev/null +++ b/shell/source/win32/shlxthandler/ooofilt/stream_helper.cxx @@ -0,0 +1,181 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2010 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_shell.hxx" + +#if defined _MSC_VER +#pragma warning(push, 1) +#endif +#include <windows.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif + +#include <stdio.h> +#include <objidl.h> + +/*#include <string.h> +#include <filter.h> +#include <filterr.h> +#include <ntquery.h> +#include "assert.h" +#include "propspec.hxx" +#ifdef __MINGW32__ +#include <algorithm> +using ::std::min; +#endif +*/ + +#include "internal/stream_helper.hxx" + +extern "C" { + voidpf ZCALLBACK cb_sopen OF((voidpf opaque, const char * filename, int mode)); + uLong ZCALLBACK cb_sread OF((voidpf opaque, voidpf stream, void* vuf, uLong size)); + uLong ZCALLBACK cb_swrite OF((voidpf opaque, voidpf stream, const void* buf, uLong size)); + long ZCALLBACK cb_stell OF((voidpf opaque, voidpf stream)); + long ZCALLBACK cb_sseek OF((voidpf opaque, voidpf stream, uLong offset, int origin)); + int ZCALLBACK cb_sclose OF((voidpf opaque, voidpf stream)); + int ZCALLBACK cb_serror OF((voidpf opaque, voidpf stream)); + + void fill_stream_filefunc (zlib_filefunc_def* pzlib_filefunc_def); +} + +//----------------------------- +IStream* PrepareIStream( IStream* pStream, zlib_filefunc_def &zFileFunc ) +{ + // These next few lines work around the "Seek pointer" bug found on Vista. + char cBuf[20]; + unsigned long nCount; + HRESULT hr; + ULARGE_INTEGER nNewPosition; + LARGE_INTEGER nMove; + nMove.QuadPart = 0; + hr = pStream->Seek( nMove, STREAM_SEEK_SET, &nNewPosition ); + hr = pStream->Read( cBuf, 20, &nCount ); + + fill_stream_filefunc( &zFileFunc ); + zFileFunc.opaque = (void*)pStream; + + return pStream; +} + +extern "C" { + + // IStream callback + voidpf ZCALLBACK cb_sopen (voidpf opaque, const char* /*filename*/, int /*mode*/) { + return opaque; + } + + uLong ZCALLBACK cb_sread (voidpf /*opaque*/, voidpf stream, void* buf, uLong size) { + unsigned long newsize; + HRESULT hr; + + hr = ((IStream *)stream)->Read (buf, size, &newsize); + if (hr == S_OK){ + return (unsigned long)newsize; + } + else { + return (uLong)0; + } + } + + long ZCALLBACK cb_sseek (voidpf /*opaque*/, voidpf stream, uLong offset, int origin) { + // IStream::Seek parameters + HRESULT hr; + LARGE_INTEGER Move; + DWORD dwOrigin; + Move.QuadPart = (__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 = ((IStream*)stream)->Seek (Move, dwOrigin, NULL); + if (hr == S_OK){ + return 0; + } + else { + return -1; + } + } + + long ZCALLBACK cb_stell (voidpf /*opaque*/, voidpf stream) { + // IStream::Seek parameters + HRESULT hr; + LARGE_INTEGER Move; + ULARGE_INTEGER NewPosition; + Move.QuadPart = 0; + NewPosition.QuadPart = 0; + + hr = ((IStream*)stream)->Seek (Move, STREAM_SEEK_CUR, &NewPosition); + if (hr == S_OK){ + return (long) NewPosition.QuadPart; + } + else { + return -1; + } + } + + int ZCALLBACK cb_sclose (voidpf /*opaque*/, voidpf /*stream*/) { + return 0; + } + + int ZCALLBACK cb_serror (voidpf /*opaque*/, voidpf /*stream*/) { + return 0; //RJK - for now + } + + uLong ZCALLBACK cb_swrite (voidpf /*opaque*/, voidpf stream, const void* buf, uLong size) { + HRESULT hr; + unsigned long writecount; + hr = ((IStream*)stream)->Write (buf, size, &writecount); + if (hr == S_OK) + return (unsigned int)writecount; + else + return (uLong)0; + } + + void fill_stream_filefunc (zlib_filefunc_def* pzlib_filefunc_def) { + pzlib_filefunc_def->zopen_file = cb_sopen; + pzlib_filefunc_def->zread_file = cb_sread; + pzlib_filefunc_def->zwrite_file = cb_swrite; + pzlib_filefunc_def->ztell_file = cb_stell; + pzlib_filefunc_def->zseek_file = cb_sseek; + pzlib_filefunc_def->zclose_file = cb_sclose; + pzlib_filefunc_def->zerror_file = cb_serror; + } +} diff --git a/shell/source/win32/shlxthandler/prophdl/exports.dxp b/shell/source/win32/shlxthandler/prophdl/exports.dxp new file mode 100755 index 000000000000..2ada8255f8f7 --- /dev/null +++ b/shell/source/win32/shlxthandler/prophdl/exports.dxp @@ -0,0 +1,2 @@ +DllGetClassObject PRIVATE +DllCanUnloadNow PRIVATE
\ No newline at end of file diff --git a/shell/source/win32/shlxthandler/prophdl/makefile.mk b/shell/source/win32/shlxthandler/prophdl/makefile.mk new file mode 100644 index 000000000000..dc6d0e159046 --- /dev/null +++ b/shell/source/win32/shlxthandler/prophdl/makefile.mk @@ -0,0 +1,142 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2010 by Sun Microsystems, Inc. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/..$/..$/.. +PRJNAME=shell +TARGET=propertyhdl +LIBTARGET=NO +ENABLE_EXCEPTIONS=TRUE +NO_DEFAULT_STL=YES +USE_DEFFILE=TRUE +.IF "$(BUILD_X64)"!="" +USE_DEFFILE_X64=TRUE +.ENDIF + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +UWINAPILIB = +UWINAPILIB_X64 = + +CFLAGS+=-DISOLATION_AWARE_ENABLED -DWIN32_LEAN_AND_MEAN -DXML_UNICODE -D_NTSDK -DUNICODE -D_UNICODE -D_WIN32_WINNT=0x0501 +CFLAGS+=-wd4710 -wd4711 -wd4514 -wd4619 -wd4217 -wd4820 -wd4100 +CDEFS+=-D_WIN32_IE=0x501 + +# --- Files -------------------------------------------------------- + +SLOFILES=$(SLO)$/$(TARGET).obj\ + $(SLO)$/stream_helper.obj + +SHL1TARGET=$(TARGET) + +.IF "$(COM)"=="GCC" +SHL1STDLIBS=$(ZLIB3RDLIB) $(EXPAT3RDLIB) $(COMCTL32LIB) +SHL1LIBS= +.ELSE +SHL1STDLIBS= +SHL1LIBS=$(SOLARLIBDIR)$/zlib.lib\ + $(SOLARLIBDIR)$/expat_xmlparse.lib\ + $(SOLARLIBDIR)$/expat_xmltok.lib +.ENDIF +SHL1STDLIBS+=\ + $(OLEAUT32LIB)\ + $(ADVAPI32LIB)\ + $(OLE32LIB)\ + $(UUIDLIB)\ + $(SHELL32LIB)\ + $(KERNEL32LIB)\ + $(GDI32LIB)\ + $(GDIPLUSLIB)\ + $(SHLWAPILIB)\ + $(PROPSYSLIB) + +.IF "$(COM)"!="GCC" +SHL1STDLIBS+=\ + msvcprt.lib + +.IF "$(PRODUCT)"!="full" +SHL1STDLIBS+=msvcrt.lib +.ENDIF +.ENDIF + +SHL1LIBS+=$(SLB)$/util.lib\ + $(SLB)$/ooofilereader.lib + +SHL1DEPN= +SHL1OBJS=$(SLOFILES) +SHL1DEF=$(MISC)$/$(SHL1TARGET).def +DEF1NAME=$(SHL1TARGET) +DEF1EXPORTFILE=exports.dxp + +# -------------------- x64 ----------------------- +.IF "$(BUILD_X64)"!="" +CFLAGS_X64+=-DISOLATION_AWARE_ENABLED -DWIN32_LEAN_AND_MEAN -DXML_UNICODE -D_NTSDK -DUNICODE -D_UNICODE -D_WIN32_WINNT=0x0501 +CFLAGS_X64+=-wd4710 -wd4711 -wd4514 -wd4619 -wd4217 -wd4820 +CDEFS_X64+=-D_WIN32_IE=0x501 +SLOFILES_X64=$(SLO_X64)$/$(TARGET).obj + +SLOFILES_X64= \ + $(SLO_X64)$/propertyhdl.obj\ + $(SLO_X64)$/stream_helper.obj\ + +SHL1TARGET_X64=$(TARGET) +SHL1LIBS_X64=$(SOLARLIBDIR_X64)$/zlib.lib\ + $(SOLARLIBDIR_X64)$/expat_xmlparse.lib\ + $(SOLARLIBDIR_X64)$/expat_xmltok.lib + +SHL1STDLIBS_X64+=\ + $(OLEAUT32LIB_X64)\ + $(ADVAPI32LIB_X64)\ + $(OLE32LIB_X64)\ + $(UUIDLIB_X64)\ + $(SHELL32LIB_X64)\ + $(KERNEL32LIB_X64)\ + $(GDI32LIB_X64)\ + $(USER32LIB_X64) \ + $(GDIPLUSLIB_X64) \ + $(MSVCRT_X64) \ + $(MSVCPRT_X64) \ + $(OLDNAMESLIB_X64)\ + $(PROPSYSLIB_X64) + +SHL1LIBS_X64+=$(SLB_X64)$/util.lib\ + $(SLB_X64)$/ooofilereader.lib +SHL1OBJS_X64=$(SLOFILES_X64) +SHL1DEF_X64=$(MISC_X64)$/$(SHL1TARGET).def + +DEF1NAME_X64=$(SHL1TARGET_X64) +DEF1EXPORTFILE_X64=exports.dxp + +.ENDIF # "$(BUILD_X64)"!="" + +# --- Targets ------------------------------------------------------ +.INCLUDE : set_wntx64.mk +.INCLUDE : target.mk +INCLUDE!:=$(subst,/stl, $(INCLUDE)) +.EXPORT : INCLUDE +.INCLUDE : tg_wntx64.mk diff --git a/shell/source/win32/shlxthandler/prophdl/propertyhdl.cxx b/shell/source/win32/shlxthandler/prophdl/propertyhdl.cxx new file mode 100755 index 000000000000..13d1a57fefd8 --- /dev/null +++ b/shell/source/win32/shlxthandler/prophdl/propertyhdl.cxx @@ -0,0 +1,463 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2010 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_shell.hxx" +#include "internal/global.hxx" +#include "internal/PropertyHdl.hxx" +#include "internal/fileextensions.hxx" +#include "internal/metainforeader.hxx" +#include "internal/utilities.hxx" +#include "internal/config.hxx" + +#include <propkey.h> +#include <propvarutil.h> + +#include <malloc.h> +#include <strsafe.h> + +#include "internal/stream_helper.hxx" + +//--------------------------- +// Module global +//--------------------------- +long g_DllRefCnt = 0; +HINSTANCE g_hModule = NULL; + +// +// Map of property keys to the locations of their value(s) in the .??? XML schema +// +struct PROPERTYMAP +{ + PROPERTYKEY key; + PCWSTR pszXPathParent; + PCWSTR pszValueNodeName; +}; + +PROPERTYMAP g_rgPROPERTYMAP[] = +{ + { PKEY_Title, L"OpenOffice.org", L"Title" }, + { PKEY_Author, L"OpenOffice.org", L"Author" }, + { PKEY_Subject, L"OpenOffice.org", L"Subject" }, + { PKEY_Keywords, L"OpenOffice.org", L"Keyword" }, + { PKEY_Comment, L"OpenOffice.org", L"Comments" }, +}; + +size_t gPropertyMapTableSize = sizeof(g_rgPROPERTYMAP)/sizeof(g_rgPROPERTYMAP[0]); + +//---------------------------- +// +//---------------------------- + +CPropertyHdl::CPropertyHdl( long nRefCnt ) : + m_RefCnt( nRefCnt ), + m_pCache( NULL ) +{ + OutputDebugStringFormat( "CPropertyHdl: CTOR\n" ); + InterlockedIncrement( &g_DllRefCnt ); +} + +//---------------------------- +// +//---------------------------- + +CPropertyHdl::~CPropertyHdl() +{ + if ( m_pCache ) + { + m_pCache->Release(); + m_pCache = NULL; + } + InterlockedDecrement( &g_DllRefCnt ); +} + +//----------------------------- +// IUnknown methods +//----------------------------- +HRESULT STDMETHODCALLTYPE CPropertyHdl::QueryInterface(REFIID riid, void __RPC_FAR *__RPC_FAR *ppvObject) +{ + *ppvObject = 0; + + if (IID_IUnknown == riid || IID_IPropertyStore == riid) + { + OutputDebugStringFormat( "CPropertyHdl: QueryInterface (IID_IPropertyStore)\n" ); + IUnknown* pUnk = static_cast<IPropertyStore*>(this); + pUnk->AddRef(); + *ppvObject = pUnk; + return S_OK; + } + else if (IID_IPropertyStoreCapabilities == riid) + { + OutputDebugStringFormat( "CPropertyHdl: QueryInterface (IID_IPropertyStoreCapabilities)\n" ); + IUnknown* pUnk = static_cast<IPropertyStore*>(this); + pUnk->AddRef(); + *ppvObject = pUnk; + return S_OK; + } + else if (IID_IInitializeWithStream == riid) + { + OutputDebugStringFormat( "CPropertyHdl: QueryInterface (IID_IInitializeWithStream)\n" ); + IUnknown* pUnk = static_cast<IInitializeWithStream*>(this); + pUnk->AddRef(); + *ppvObject = pUnk; + return S_OK; + } + OutputDebugStringFormat( "CPropertyHdl: QueryInterface (something different)\n" ); + + return E_NOINTERFACE; +} + +//---------------------------- +ULONG STDMETHODCALLTYPE CPropertyHdl::AddRef( void ) +{ + return InterlockedIncrement( &m_RefCnt ); +} + +//---------------------------- +ULONG STDMETHODCALLTYPE CPropertyHdl::Release( void ) +{ + long refcnt = InterlockedDecrement( &m_RefCnt ); + + if ( 0 == m_RefCnt ) + delete this; + + return refcnt; +} + +//----------------------------- +// IPropertyStore +//----------------------------- +HRESULT STDMETHODCALLTYPE CPropertyHdl::GetCount( DWORD *pcProps ) +{ + HRESULT hr = E_UNEXPECTED; + if ( m_pCache && pcProps ) + { + hr = m_pCache->GetCount( pcProps ); + } + + return hr; +} + +//----------------------------- +HRESULT STDMETHODCALLTYPE CPropertyHdl::GetAt( DWORD iProp, PROPERTYKEY *pKey ) +{ + HRESULT hr = E_UNEXPECTED; + if ( m_pCache ) + { + hr = m_pCache->GetAt( iProp, pKey ); + } + + return hr; +} + +//----------------------------- +HRESULT STDMETHODCALLTYPE CPropertyHdl::GetValue( REFPROPERTYKEY key, PROPVARIANT *pPropVar ) +{ + HRESULT hr = E_UNEXPECTED; + if ( m_pCache ) + { + hr = m_pCache->GetValue( key, pPropVar ); + } + + return hr; +} + +//----------------------------- +HRESULT STDMETHODCALLTYPE CPropertyHdl::SetValue( REFPROPERTYKEY key, REFPROPVARIANT propVar ) +{ + HRESULT hr = E_UNEXPECTED; + if ( m_pCache ) + { + hr = STG_E_ACCESSDENIED; + } + return hr; +} + +//----------------------------- +HRESULT STDMETHODCALLTYPE CPropertyHdl::Commit() +{ + return S_OK; +} + +//----------------------------- +// IPropertyStore +//----------------------------- +HRESULT STDMETHODCALLTYPE CPropertyHdl::IsPropertyWritable( REFPROPERTYKEY key ) +{ + // We start with read only properties only + return S_FALSE; +} + +//----------------------------- +// IInitializeWithStream +//----------------------------- +HRESULT STDMETHODCALLTYPE CPropertyHdl::Initialize( IStream *pStream, DWORD grfMode ) +{ + if ( grfMode & STGM_READWRITE ) + return STG_E_ACCESSDENIED; + + if ( !m_pCache ) + { +#ifdef __MINGW32__ + if ( FAILED( PSCreateMemoryPropertyStore( IID_IPropertyStoreCache, reinterpret_cast<void**>(&m_pCache) ) ) ) +#else + if ( FAILED( PSCreateMemoryPropertyStore( IID_PPV_ARGS( &m_pCache ) ) ) ) +#endif + OutputDebugStringFormat( "CPropertyHdl::Initialize: PSCreateMemoryPropertyStore failed" ); + + zlib_filefunc_def z_filefunc; + pStream = PrepareIStream( pStream, z_filefunc ); + + CMetaInfoReader *pMetaInfoReader = NULL; + + try + { + pMetaInfoReader = new CMetaInfoReader( (void*)pStream, &z_filefunc ); + LoadProperties( pMetaInfoReader ); + delete pMetaInfoReader; + } + catch (const std::exception& e) + { + OutputDebugStringFormat( "CPropertyHdl::Initialize: Caught exception [%s]", e.what() ); + return E_FAIL; + } +/* + // load extended properties and search content + _LoadExtendedProperties(); + _LoadSearchContent(); +*/ + } + + return S_OK; +} + +//----------------------------- +void CPropertyHdl::LoadProperties( CMetaInfoReader *pMetaInfoReader ) +{ + OutputDebugStringFormat( "CPropertyHdl: LoadProperties\n" ); + PROPVARIANT propvarValues; + + for ( UINT i = 0; i < (UINT)gPropertyMapTableSize; ++i ) + { + PropVariantClear( &propvarValues ); + HRESULT hr = GetItemData( pMetaInfoReader, i, &propvarValues); + if (hr == S_OK) + { + // coerce the value(s) to the appropriate type for the property key + hr = PSCoerceToCanonicalValue( g_rgPROPERTYMAP[i].key, &propvarValues ); + if (SUCCEEDED(hr)) + { + // cache the value(s) loaded + hr = m_pCache->SetValueAndState( g_rgPROPERTYMAP[i].key, &propvarValues, PSC_NORMAL ); + } + } + } +} + +//----------------------------- +HRESULT CPropertyHdl::GetItemData( CMetaInfoReader *pMetaInfoReader, UINT nIndex, PROPVARIANT *pVarData ) +{ + switch (nIndex) { + case 0: { + pVarData->vt = VT_BSTR; + pVarData->bstrVal = SysAllocString( pMetaInfoReader->getTagData( META_INFO_TITLE ).c_str() ); + OutputDebugStringFormat( "CPropertyHdl::GetItemData: Title=%S.\n", pMetaInfoReader->getTagData( META_INFO_TITLE ).c_str() ); + return S_OK; + } + case 1: { + pVarData->vt = VT_BSTR; + pVarData->bstrVal = SysAllocString( pMetaInfoReader->getTagData( META_INFO_AUTHOR ).c_str() ); + OutputDebugStringFormat( "CPropertyHdl::GetItemData: Author=%S.\n", pMetaInfoReader->getTagData( META_INFO_AUTHOR ).c_str() ); + return S_OK; + } + case 2: { + pVarData->vt = VT_BSTR; + pVarData->bstrVal = SysAllocString( pMetaInfoReader->getTagData( META_INFO_SUBJECT ).c_str() ); + OutputDebugStringFormat( "CPropertyHdl::GetItemData: Subject=%S.\n", pMetaInfoReader->getTagData( META_INFO_SUBJECT ).c_str() ); + return S_OK; + } + case 3: { + pVarData->vt = VT_BSTR; + pVarData->bstrVal = SysAllocString( pMetaInfoReader->getTagData( META_INFO_KEYWORDS ).c_str() ); + OutputDebugStringFormat( "CPropertyHdl::GetItemData: Keywords=%S.\n", pMetaInfoReader->getTagData( META_INFO_KEYWORDS ).c_str() ); + return S_OK; + } + case 4: { + pVarData->vt = VT_BSTR; + pVarData->bstrVal = SysAllocString( pMetaInfoReader->getTagData( META_INFO_DESCRIPTION ).c_str() ); + OutputDebugStringFormat( "CPropertyHdl::GetItemData: Description=%S.\n", pMetaInfoReader->getTagData( META_INFO_DESCRIPTION ).c_str() ); + return S_OK; + } + case 5: { + pVarData->vt = VT_BSTR; + pVarData->bstrVal = SysAllocString( pMetaInfoReader->getTagAttribute( META_INFO_DOCUMENT_STATISTIC, META_INFO_PAGES ).c_str() ); + OutputDebugStringFormat( "CPropertyHdl::GetItemData: Pages=%S.\n", pMetaInfoReader->getTagAttribute( META_INFO_DOCUMENT_STATISTIC, META_INFO_PAGES ).c_str() ); + return S_OK; + } + } + + return S_FALSE; +} + +//----------------------------------------------------------------------------- +// CClassFactory +//----------------------------------------------------------------------------- + +long CClassFactory::s_ServerLocks = 0; + +//----------------------------------------------------------------------------- +CClassFactory::CClassFactory( const CLSID& clsid ) : + m_RefCnt(1), + m_Clsid(clsid) +{ + InterlockedIncrement( &g_DllRefCnt ); +} + +//----------------------------------------------------------------------------- +CClassFactory::~CClassFactory() +{ + InterlockedDecrement( &g_DllRefCnt ); +} + +//----------------------------------------------------------------------------- +// IUnknown methods +//----------------------------------------------------------------------------- +HRESULT STDMETHODCALLTYPE CClassFactory::QueryInterface( REFIID riid, void __RPC_FAR *__RPC_FAR *ppvObject ) +{ + *ppvObject = 0; + + if ( IID_IUnknown == riid || IID_IClassFactory == riid ) + { + IUnknown* pUnk = this; + pUnk->AddRef(); + *ppvObject = pUnk; + return S_OK; + } + + return E_NOINTERFACE; +} + +//----------------------------------------------------------------------------- +ULONG STDMETHODCALLTYPE CClassFactory::AddRef( void ) +{ + return InterlockedIncrement( &m_RefCnt ); +} + +//----------------------------------------------------------------------------- +ULONG STDMETHODCALLTYPE CClassFactory::Release( void ) +{ + long refcnt = InterlockedDecrement( &m_RefCnt ); + + if (0 == refcnt) + delete this; + + return refcnt; +} + +//----------------------------------------------------------------------------- +// IClassFactory methods +//----------------------------------------------------------------------------- +HRESULT STDMETHODCALLTYPE CClassFactory::CreateInstance( + IUnknown __RPC_FAR *pUnkOuter, + REFIID riid, + void __RPC_FAR *__RPC_FAR *ppvObject) +{ + if ( pUnkOuter != NULL ) + return CLASS_E_NOAGGREGATION; + + IUnknown* pUnk = 0; + + if ( CLSID_PROPERTY_HANDLER == m_Clsid ) + pUnk = static_cast<IPropertyStore*>( new CPropertyHdl() ); + + POST_CONDITION(pUnk != 0, "Could not create COM object"); + + if (0 == pUnk) + return E_OUTOFMEMORY; + + HRESULT hr = pUnk->QueryInterface( riid, ppvObject ); + + // if QueryInterface failed the component will destroy itself + pUnk->Release(); + + return hr; +} + +//----------------------------------------------------------------------------- +HRESULT STDMETHODCALLTYPE CClassFactory::LockServer( BOOL fLock ) +{ + if ( fLock ) + InterlockedIncrement( &s_ServerLocks ); + else + InterlockedDecrement( &s_ServerLocks ); + + return S_OK; +} + +//----------------------------------------------------------------------------- +bool CClassFactory::IsLocked() +{ + return ( s_ServerLocks > 0 ); +} + +//----------------------------------------------------------------------------- +extern "C" STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void** ppv) +{ + OutputDebugStringFormat( "DllGetClassObject.\n" ); + *ppv = 0; + + if ( rclsid != CLSID_PROPERTY_HANDLER ) + return CLASS_E_CLASSNOTAVAILABLE; + + if ( (riid != IID_IUnknown) && (riid != IID_IClassFactory) ) + return E_NOINTERFACE; + + IUnknown* pUnk = new CClassFactory( rclsid ); + if ( 0 == pUnk ) + return E_OUTOFMEMORY; + + *ppv = pUnk; + return S_OK; +} + +//----------------------------------------------------------------------------- +extern "C" STDAPI DllCanUnloadNow( void ) +{ + OutputDebugStringFormat( "DllCanUnloadNow.\n" ); + if (CClassFactory::IsLocked() || g_DllRefCnt > 0) + return S_FALSE; + + return S_OK; +} + +//----------------------------------------------------------------------------- +BOOL WINAPI DllMain( HINSTANCE hInst, ULONG /*ul_reason_for_call*/, LPVOID /*lpReserved*/ ) +{ + OutputDebugStringFormat( "DllMain.\n" ); + g_hModule = hInst; + return TRUE; +} diff --git a/shell/source/win32/shlxthandler/propsheets/document_statistic.cxx b/shell/source/win32/shlxthandler/propsheets/document_statistic.cxx new file mode 100644 index 000000000000..1e41f478b95b --- /dev/null +++ b/shell/source/win32/shlxthandler/propsheets/document_statistic.cxx @@ -0,0 +1,170 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_shell.hxx" + +#ifdef _MSC_VER +#pragma warning (disable : 4786 4503) +#endif +#include "document_statistic.hxx" +#include "internal/utilities.hxx" +#include "internal/metainforeader.hxx" +#include "internal/resource.h" +#include "internal/fileextensions.hxx" +#include "internal/config.hxx" +#include "internal/iso8601_converter.hxx" + +//##################################### +const bool READONLY = false; +const bool WRITEABLE = true; + +//##################################### +document_statistic_reader_ptr create_document_statistic_reader(const std::string& document_name, CMetaInfoReader* meta_info_accessor) +{ + File_Type_t file_type = get_file_type(document_name); + + if (WRITER == file_type) + return document_statistic_reader_ptr(new writer_document_statistic_reader(document_name, meta_info_accessor)); + else if (CALC == file_type) + return document_statistic_reader_ptr(new calc_document_statistic_reader(document_name, meta_info_accessor)); + else + return document_statistic_reader_ptr(new draw_impress_math_document_statistic_reader(document_name, meta_info_accessor)); +} + + +//##################################### +document_statistic_reader::document_statistic_reader(const std::string& document_name, CMetaInfoReader* meta_info_accessor) : + document_name_(document_name), + meta_info_accessor_(meta_info_accessor) +{} + +//##################################### +document_statistic_reader::~document_statistic_reader() +{} + +//##################################### +void document_statistic_reader::read(statistic_group_list_t* group_list) +{ + group_list->clear(); + fill_description_section(meta_info_accessor_, group_list); + fill_origin_section(meta_info_accessor_, group_list); +} + +//##################################### +std::string document_statistic_reader::get_document_name() const +{ + return document_name_; +} + +//##################################### +void document_statistic_reader::fill_origin_section(CMetaInfoReader *meta_info_accessor, statistic_group_list_t* group_list) +{ + statistic_item_list_t il; + + il.push_back(statistic_item(GetResString(IDS_AUTHOR), meta_info_accessor->getTagData( META_INFO_AUTHOR ), READONLY)); + + il.push_back(statistic_item(GetResString(IDS_MODIFIED), + iso8601_date_to_local_date(meta_info_accessor->getTagData(META_INFO_MODIFIED )), READONLY)); + + il.push_back(statistic_item(GetResString(IDS_DOCUMENT_NUMBER), meta_info_accessor->getTagData( META_INFO_DOCUMENT_NUMBER ), READONLY)); + + il.push_back(statistic_item(GetResString(IDS_EDITING_TIME), + iso8601_duration_to_local_duration(meta_info_accessor->getTagData( META_INFO_EDITING_TIME )), READONLY)); + + group_list->push_back(statistic_group_t(GetResString(IDS_ORIGIN), il)); +} + +//##################################### +writer_document_statistic_reader::writer_document_statistic_reader(const std::string& document_name, CMetaInfoReader* meta_info_accessor) : + document_statistic_reader(document_name, meta_info_accessor) +{} + +//##################################### +void writer_document_statistic_reader::fill_description_section(CMetaInfoReader *meta_info_accessor, statistic_group_list_t* group_list) +{ + statistic_item_list_t il; + + il.push_back(statistic_item(GetResString(IDS_TITLE), meta_info_accessor->getTagData( META_INFO_TITLE ), READONLY)); + il.push_back(statistic_item(GetResString(IDS_COMMENTS), meta_info_accessor->getTagData( META_INFO_DESCRIPTION ), READONLY)); + il.push_back(statistic_item(GetResString(IDS_SUBJECT), meta_info_accessor->getTagData( META_INFO_SUBJECT ), READONLY)); + il.push_back(statistic_item(GetResString(IDS_KEYWORDS), meta_info_accessor->getTagData(META_INFO_KEYWORDS ), READONLY)); + il.push_back(statistic_item(GetResString(IDS_PAGES), meta_info_accessor->getTagAttribute( META_INFO_DOCUMENT_STATISTIC,META_INFO_PAGES) , READONLY)); + il.push_back(statistic_item(GetResString(IDS_TABLES), meta_info_accessor->getTagAttribute( META_INFO_DOCUMENT_STATISTIC,META_INFO_TABLES) , READONLY)); + il.push_back(statistic_item(GetResString(IDS_GRAPHICS), meta_info_accessor->getTagAttribute( META_INFO_DOCUMENT_STATISTIC,META_INFO_DRAWS) , READONLY)); + il.push_back(statistic_item(GetResString(IDS_OLE_OBJECTS), meta_info_accessor->getTagAttribute( META_INFO_DOCUMENT_STATISTIC,META_INFO_OBJECTS) , READONLY)); + il.push_back(statistic_item(GetResString(IDS_PARAGRAPHS), meta_info_accessor->getTagAttribute( META_INFO_DOCUMENT_STATISTIC,META_INFO_PARAGRAPHS) , READONLY)); + il.push_back(statistic_item(GetResString(IDS_WORDS), meta_info_accessor->getTagAttribute( META_INFO_DOCUMENT_STATISTIC,META_INFO_WORDS) , READONLY)); + il.push_back(statistic_item(GetResString(IDS_CHARACTERS), meta_info_accessor->getTagAttribute( META_INFO_DOCUMENT_STATISTIC,META_INFO_CHARACTERS) , READONLY)); + + group_list->push_back(statistic_group_t(GetResString(IDS_DESCRIPTION), il)); +} + +//####################################### +calc_document_statistic_reader::calc_document_statistic_reader( + const std::string& document_name, CMetaInfoReader* meta_info_accessor) : + document_statistic_reader(document_name, meta_info_accessor) +{} + +//####################################### +void calc_document_statistic_reader::fill_description_section( + CMetaInfoReader *meta_info_accessor,statistic_group_list_t* group_list) +{ + statistic_item_list_t il; + + il.push_back(statistic_item(GetResString(IDS_TITLE), meta_info_accessor->getTagData( META_INFO_TITLE ), READONLY)); + il.push_back(statistic_item(GetResString(IDS_COMMENTS), meta_info_accessor->getTagData( META_INFO_DESCRIPTION ), READONLY)); + il.push_back(statistic_item(GetResString(IDS_SUBJECT), meta_info_accessor->getTagData( META_INFO_SUBJECT ), READONLY)); + il.push_back(statistic_item(GetResString(IDS_KEYWORDS), meta_info_accessor->getTagData(META_INFO_KEYWORDS ), READONLY)); + il.push_back(statistic_item(GetResString(IDS_TABLES), meta_info_accessor->getTagAttribute( META_INFO_DOCUMENT_STATISTIC,META_INFO_TABLES) , READONLY)); + il.push_back(statistic_item(GetResString(IDS_CELLS), meta_info_accessor->getTagAttribute( META_INFO_DOCUMENT_STATISTIC,META_INFO_CELLS) , READONLY)); + il.push_back(statistic_item(GetResString(IDS_OLE_OBJECTS), meta_info_accessor->getTagAttribute( META_INFO_DOCUMENT_STATISTIC,META_INFO_OBJECTS) , READONLY)); + + group_list->push_back(statistic_group_t(GetResString(IDS_DESCRIPTION), il)); +} + +//####################################### +draw_impress_math_document_statistic_reader::draw_impress_math_document_statistic_reader( + const std::string& document_name, CMetaInfoReader* meta_info_accessor) : + document_statistic_reader(document_name, meta_info_accessor) +{} + +//####################################### +void draw_impress_math_document_statistic_reader::fill_description_section( + CMetaInfoReader *meta_info_accessor, statistic_group_list_t* group_list) +{ + statistic_item_list_t il; + + il.push_back(statistic_item(GetResString(IDS_TITLE), meta_info_accessor->getTagData( META_INFO_TITLE ), READONLY)); + il.push_back(statistic_item(GetResString(IDS_COMMENTS), meta_info_accessor->getTagData( META_INFO_DESCRIPTION ), READONLY)); + il.push_back(statistic_item(GetResString(IDS_SUBJECT), meta_info_accessor->getTagData( META_INFO_SUBJECT ), READONLY)); + il.push_back(statistic_item(GetResString(IDS_KEYWORDS), meta_info_accessor->getTagData(META_INFO_KEYWORDS ), READONLY)); + il.push_back(statistic_item(GetResString(IDS_PAGES), meta_info_accessor->getTagAttribute( META_INFO_DOCUMENT_STATISTIC,META_INFO_PAGES) , READONLY)); + il.push_back(statistic_item(GetResString(IDS_OLE_OBJECTS), meta_info_accessor->getTagAttribute( META_INFO_DOCUMENT_STATISTIC,META_INFO_OBJECTS) , READONLY)); + + group_list->push_back(statistic_group_t(GetResString(IDS_DESCRIPTION), il)); +} diff --git a/shell/source/win32/shlxthandler/propsheets/document_statistic.hxx b/shell/source/win32/shlxthandler/propsheets/document_statistic.hxx new file mode 100644 index 000000000000..0b3a3dd96c07 --- /dev/null +++ b/shell/source/win32/shlxthandler/propsheets/document_statistic.hxx @@ -0,0 +1,149 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef DOCUMENT_STATISTIC_HXX_INCLUDED +#define DOCUMENT_STATISTIC_HXX_INCLUDED + +#include <utility> +#include <string> +#include <vector> +#include "internal/metainforeader.hxx" + + +//------------------------------------ +// +//------------------------------------ + +struct statistic_item +{ + statistic_item(); + + statistic_item( + const std::wstring& title, + const std::wstring& value, + bool editable) : + title_(title), + value_(value), + editable_(editable) + {} + + std::wstring title_; + std::wstring value_; + bool editable_; +}; + +//------------------------------------ +// +//------------------------------------ + +typedef std::vector<statistic_item> statistic_item_list_t; +typedef std::pair<std::wstring, statistic_item_list_t> statistic_group_t; +typedef std::vector<statistic_group_t> statistic_group_list_t; + +//------------------------------------ +// +//------------------------------------ + +class document_statistic_reader; +typedef std::auto_ptr<document_statistic_reader> document_statistic_reader_ptr; + +document_statistic_reader_ptr create_document_statistic_reader(const std::string& document_name, CMetaInfoReader* meta_info_accessor); + +//------------------------------------ +// +//------------------------------------ + +class document_statistic_reader +{ +public: + virtual ~document_statistic_reader(); + + void read(statistic_group_list_t* group_list); + + std::string get_document_name() const; + +protected: + document_statistic_reader(const std::string& document_name, CMetaInfoReader* meta_info_accessor); + + virtual void fill_description_section(CMetaInfoReader *meta_info_accessor,statistic_group_list_t* group_list) = 0; + + virtual void fill_origin_section( CMetaInfoReader *meta_info_accessor,statistic_group_list_t* group_list); + +private: + std::string document_name_; + CMetaInfoReader* meta_info_accessor_; + + friend document_statistic_reader_ptr create_document_statistic_reader( + const std::string& document_name, CMetaInfoReader* meta_info_accessor); +}; + +//------------------------------------ +// +//------------------------------------ + +class writer_document_statistic_reader : public document_statistic_reader +{ +protected: + writer_document_statistic_reader(const std::string& document_name, CMetaInfoReader* meta_info_accessor); + + virtual void fill_description_section(CMetaInfoReader *meta_info_accessor, statistic_group_list_t* group_list); + + friend document_statistic_reader_ptr create_document_statistic_reader( + const std::string& document_name, CMetaInfoReader* meta_info_accessor); +}; + +//------------------------------------ +// +//------------------------------------ + +class calc_document_statistic_reader : public document_statistic_reader +{ +protected: + calc_document_statistic_reader(const std::string& document_name, CMetaInfoReader* meta_info_accessor); + + virtual void fill_description_section( CMetaInfoReader *meta_info_accessor,statistic_group_list_t* group_list); + + friend document_statistic_reader_ptr create_document_statistic_reader( + const std::string& document_name, CMetaInfoReader* meta_info_accessor); +}; + +//------------------------------------ +// +//------------------------------------ + +class draw_impress_math_document_statistic_reader : public document_statistic_reader +{ +protected: + draw_impress_math_document_statistic_reader(const std::string& document_name, CMetaInfoReader* meta_info_accessor); + + virtual void fill_description_section(CMetaInfoReader *meta_info_accessor, statistic_group_list_t* group_list); + + friend document_statistic_reader_ptr create_document_statistic_reader( + const std::string& document_name, CMetaInfoReader* meta_info_accessor); +}; + +#endif diff --git a/shell/source/win32/shlxthandler/propsheets/listviewbuilder.cxx b/shell/source/win32/shlxthandler/propsheets/listviewbuilder.cxx new file mode 100644 index 000000000000..5d3d365beb62 --- /dev/null +++ b/shell/source/win32/shlxthandler/propsheets/listviewbuilder.cxx @@ -0,0 +1,281 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_shell.hxx" + +#ifdef _MSC_VER +#pragma warning (disable : 4786 4503) +#endif + +//------------------------------------ +// include +//------------------------------------ +#include "listviewbuilder.hxx" +#include "document_statistic.hxx" +#include "internal/utilities.hxx" +#include "internal/config.hxx" + +#if defined _MSC_VER +#pragma warning(push, 1) +#endif +#include <commctrl.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif +#include <commctrl.h> +#include <tchar.h> +#include "internal/resource.h" + +//------------------------------------ +// +//------------------------------------ + +list_view_builder_ptr create_list_view_builder( + HWND hwnd_lv, const std::wstring& col1, const std::wstring& col2) +{ + if (is_windows_xp_or_above()) + return list_view_builder_ptr(new winxp_list_view_builder(hwnd_lv, col1, col2)); + else + return list_view_builder_ptr(new list_view_builder(hwnd_lv, col1, col2)); +} + +//------------------------------------ +// +//------------------------------------ + +list_view_builder::list_view_builder( + HWND hwnd_list_view, + const std::wstring& column1_title, + const std::wstring& column2_title) : + hwnd_list_view_(hwnd_list_view), + row_index_(-1), + column1_title_(column1_title), + column2_title_(column2_title) +{ +} + +//------------------------------------ +// +//------------------------------------ + +list_view_builder::~list_view_builder() +{ +} + +//------------------------------------ +// +//------------------------------------ + +void list_view_builder::build(statistic_group_list_t& gl) +{ + setup_list_view(); + + statistic_group_list_t::iterator group_iter = gl.begin(); + statistic_group_list_t::iterator group_iter_end = gl.end(); + + for (/**/; group_iter != group_iter_end; ++group_iter) + { + statistic_item_list_t::iterator item_iter = group_iter->second.begin(); + statistic_item_list_t::iterator item_iter_end = group_iter->second.end(); + + if (item_iter != item_iter_end) + insert_group(group_iter->first); + + for (/**/; item_iter != item_iter_end; ++item_iter) + insert_item(item_iter->title_, item_iter->value_, item_iter->editable_); + } +} + +//------------------------------------ +// +//------------------------------------ + +void list_view_builder::setup_list_view() +{ + HIMAGELIST h_ils = ImageList_Create(16,15,ILC_MASK, 7, 0); + HBITMAP h_bmp = LoadBitmap(GetModuleHandle(MODULE_NAME), MAKEINTRESOURCE(IDB_PROPERTY_IMAGES)); + ImageList_AddMasked(h_ils, h_bmp, RGB(255, 0, 255)); + + ListView_SetImageList(hwnd_list_view_, h_ils, LVSIL_SMALL); + + std::wstring header = GetResString(IDS_PROPERTY); + + LVCOLUMN lvc; + lvc.mask = LVCF_FMT | + LVCF_WIDTH | + LVCF_TEXT | + LVCF_SUBITEM; + + lvc.iSubItem = 0; + lvc.pszText = const_cast<wchar_t*>(header.c_str()); + lvc.cx = 120; + lvc.fmt = LVCFMT_LEFT; + + ListView_InsertColumn(hwnd_list_view_, 0, &lvc); + lvc.iSubItem = 1; + header = GetResString(IDS_PROPERTY_VALUE); + lvc.pszText = const_cast<wchar_t*>(header.c_str()); + ListView_InsertColumn(hwnd_list_view_, 1, &lvc); +} + +//------------------------------------ +// +//------------------------------------ + +void list_view_builder::insert_group(const std::wstring& /*title*/) +{ + insert_item(L"", L"", false); +} + +//------------------------------------ +// +//------------------------------------ + +void list_view_builder::insert_item(const std::wstring& title, const std::wstring& value, bool is_editable) +{ + LVITEM lvi; + + lvi.iItem = ++row_index_; + lvi.iSubItem = 0; + lvi.mask = LVIF_TEXT; + lvi.state = 0; + lvi.cchTextMax = title.size() + 1; + lvi.stateMask = 0; + lvi.pszText = const_cast<wchar_t*>(title.c_str()); + + if (title.length() > 0) + { + lvi.mask |= LVIF_IMAGE; + + if (is_editable) + lvi.iImage = 4; + else + lvi.iImage = 3; + } + + ListView_InsertItem(hwnd_list_view_, &lvi); + + lvi.mask = LVIF_TEXT; + lvi.iSubItem = 1; + lvi.pszText = const_cast<wchar_t*>(value.c_str()); + + ListView_SetItem(hwnd_list_view_, &lvi); +} + +//------------------------------------ +// +//------------------------------------ + +HWND list_view_builder::get_list_view() const +{ + return hwnd_list_view_; +} + +//------------------------------------ +// +//------------------------------------ + +winxp_list_view_builder::winxp_list_view_builder( + HWND hwnd_list_view, + const std::wstring& column1_title, + const std::wstring& column2_title) : + list_view_builder(hwnd_list_view, column1_title, column2_title), + group_count_(-1), + row_count_(0) +{ +} + +//------------------------------------ +// +//------------------------------------ + +void winxp_list_view_builder::setup_list_view() +{ + list_view_builder::setup_list_view(); + + ListView_EnableGroupView(get_list_view(), TRUE); +} + +//------------------------------------ +// +//------------------------------------ + +void winxp_list_view_builder::insert_group(const std::wstring& name) +{ + LVGROUP lvg; + + ZeroMemory(&lvg, sizeof(lvg)); + + lvg.cbSize = sizeof(lvg); + lvg.mask = LVGF_HEADER | LVGF_STATE | LVGF_GROUPID; + lvg.pszHeader = const_cast<wchar_t*>(name.c_str()); + lvg.cchHeader = name.size() + 1; + lvg.iGroupId = ++group_count_; + lvg.state = LVGS_NORMAL; + lvg.uAlign = LVGA_HEADER_CENTER; + + ListView_InsertGroup(get_list_view(), row_count_++, &lvg); +} + +//------------------------------------ +// +//------------------------------------ + +void winxp_list_view_builder::insert_item( + const std::wstring& title, const std::wstring& value, bool is_editable) +{ + LVITEM lvi; + + lvi.iItem = ++row_index_; + lvi.iSubItem = 0; + lvi.mask = LVIF_TEXT | LVIF_GROUPID; + lvi.state = 0; + lvi.stateMask = 0; + lvi.pszText = const_cast<wchar_t*>(title.c_str()); + lvi.iGroupId = group_count_; + + if (title.length() > 0) + { + lvi.mask |= LVIF_IMAGE; + + if (is_editable) + lvi.iImage = 4; + else + lvi.iImage = 3; + } + + ListView_InsertItem(get_list_view(), &lvi); + + lvi.mask = LVIF_TEXT; + lvi.iSubItem = 1; + lvi.pszText = const_cast<wchar_t*>(value.c_str()); + + ListView_SetItem(get_list_view(), &lvi); + + row_count_++; +} diff --git a/shell/source/win32/shlxthandler/propsheets/listviewbuilder.hxx b/shell/source/win32/shlxthandler/propsheets/listviewbuilder.hxx new file mode 100644 index 000000000000..c764ff9809ad --- /dev/null +++ b/shell/source/win32/shlxthandler/propsheets/listviewbuilder.hxx @@ -0,0 +1,115 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef LISTVIEWBUILDER_HXX_INCLUDED +#define LISTVIEWBUILDER_HXX_INCLUDED + +//------------------------------------ +// include +//------------------------------------ + +#if defined _MSC_VER +#pragma warning(push, 1) +#endif +#include <windows.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif + +#include <string> +#include <memory> +#include "document_statistic.hxx" + +//------------------------------------ +// +//------------------------------------ + +class list_view_builder; +typedef std::auto_ptr<list_view_builder> list_view_builder_ptr; + +// factory method for list_view_builder +list_view_builder_ptr create_list_view_builder( + HWND hwnd_lv, const std::wstring& col1, const std::wstring& col2); + +//------------------------------------ +// +//------------------------------------ + +class list_view_builder +{ +public: + virtual ~list_view_builder(); + + void build(statistic_group_list_t& gl); + +protected: + list_view_builder( + HWND hwnd_list_view, + const std::wstring& column1_title, + const std::wstring& column2_title); + + virtual void setup_list_view(); + virtual void insert_group(const std::wstring& title); + virtual void insert_item(const std::wstring& title, const std::wstring& value, bool is_editable); + + HWND get_list_view() const; + int get_current_row() const; + + int row_index_; + +private: + HWND hwnd_list_view_; + std::wstring column1_title_; + std::wstring column2_title_; + + friend list_view_builder_ptr create_list_view_builder(HWND hwnd_lv, const std::wstring& col1, const std::wstring& col2); +}; + +//------------------------------------ +// +//------------------------------------ + +class winxp_list_view_builder : public list_view_builder +{ +protected: + winxp_list_view_builder( + HWND hwnd_list_view, + const std::wstring& column1_title, + const std::wstring& column2_title); + + virtual void setup_list_view(); + virtual void insert_group(const std::wstring& name); + virtual void insert_item(const std::wstring& title, const std::wstring& value, bool is_editable); + +private: + int group_count_; + int row_count_; + + friend list_view_builder_ptr create_list_view_builder(HWND hwnd_lv, const std::wstring& col1, const std::wstring& col2); +}; + +#endif diff --git a/shell/source/win32/shlxthandler/propsheets/makefile.mk b/shell/source/win32/shlxthandler/propsheets/makefile.mk new file mode 100644 index 000000000000..55a31c9c59d3 --- /dev/null +++ b/shell/source/win32/shlxthandler/propsheets/makefile.mk @@ -0,0 +1,65 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/..$/..$/.. +PRJNAME=shell +TARGET=propsheets +LIBTARGET=NO +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +CFLAGS+=-DISOLATION_AWARE_ENABLED -DWIN32_LEAN_AND_MEAN -DXML_UNICODE -D_NTSDK -DUNICODE -D_UNICODE +CDEFS+=-U_WIN32_WINNT -D_WIN32_WINNT=0x0501 -U_WIN32_IE -D_WIN32_IE=0x501 +.IF "$(COM)"!="GCC" +CFLAGS+=-wd4710 -wd4711 -wd4514 -wd4619 -wd4217 -wd4820 +CFLAGS_X64+=-DISOLATION_AWARE_ENABLED -DWIN32_LEAN_AND_MEAN -DXML_UNICODE -D_NTSDK -DUNICODE -D_UNICODE +CFLAGS_X64+=-wd4710 -wd4711 -wd4514 -wd4619 -wd4217 -wd4820 +CDEFS_X64+=-D_WIN32_WINNT=0x0501 -D_WIN32_IE=0x501 +.ENDIF + +# --- Files -------------------------------------------------------- + +SLOFILES=$(SLO)$/propsheets.obj\ + $(SLO)$/listviewbuilder.obj\ + $(SLO)$/document_statistic.obj + +.IF "$(BUILD_X64)"!="" +SLOFILES_X64=$(SLO_X64)$/propsheets.obj\ + $(SLO_X64)$/listviewbuilder.obj\ + $(SLO_X64)$/document_statistic.obj +.ENDIF # "$(BUILD_X64)"!="" + +# --- Targets ------------------------------------------------------ + +.INCLUDE : set_wntx64.mk +.INCLUDE : target.mk +INCLUDE!:=$(subst,/stl, $(INCLUDE)) +.EXPORT : INCLUDE +.INCLUDE : tg_wntx64.mk
\ No newline at end of file diff --git a/shell/source/win32/shlxthandler/propsheets/propsheets.cxx b/shell/source/win32/shlxthandler/propsheets/propsheets.cxx new file mode 100755 index 000000000000..d668479d5ff5 --- /dev/null +++ b/shell/source/win32/shlxthandler/propsheets/propsheets.cxx @@ -0,0 +1,385 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_shell.hxx" +#include "internal/config.hxx" +#include "internal/global.hxx" + +#ifndef PROPSEETS_HXX_INCLUDED +#include "internal/propsheets.hxx" +#endif +#include "internal/utilities.hxx" +#include "internal/resource.h" +#include "listviewbuilder.hxx" + +#if defined _MSC_VER +#pragma warning(push, 1) +#endif +#include <shellapi.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif + +#include <string> +#include <vector> +#include <utility> +#include <strsafe.h> + + +/*--------------------------------------------- + INFO - INFO - INFO - INFO - INFO - INFO + + See MSDN "Using Windows XP Visual Styles" + for hints how to enable the new common + control library for our property sheet. + + INFO - INFO - INFO - INFO - INFO - INFO +----------------------------------------------*/ + +//----------------------------- +// +//----------------------------- + +CPropertySheet::CPropertySheet(long RefCnt) : + m_RefCnt(RefCnt) +{ + OutputDebugStringFormat("CPropertySheet::CTor [%d], [%d]", m_RefCnt, g_DllRefCnt ); + InterlockedIncrement(&g_DllRefCnt); +} + +//----------------------------- +// +//----------------------------- + +CPropertySheet::~CPropertySheet() +{ + OutputDebugStringFormat("CPropertySheet::DTor [%d], [%d]", m_RefCnt, g_DllRefCnt ); + InterlockedDecrement(&g_DllRefCnt); +} + +//----------------------------- +// IUnknown methods +//----------------------------- + +HRESULT STDMETHODCALLTYPE CPropertySheet::QueryInterface( + REFIID riid, void __RPC_FAR *__RPC_FAR *ppvObject) +{ + *ppvObject = 0; + + IUnknown* pUnk = 0; + if (IID_IUnknown == riid || IID_IShellExtInit == riid) + { + pUnk = static_cast<IShellExtInit*>(this); + pUnk->AddRef(); + *ppvObject = pUnk; + return S_OK; + } + else if (IID_IShellPropSheetExt == riid) + { + pUnk = static_cast<IShellPropSheetExt*>(this); + pUnk->AddRef(); + *ppvObject = pUnk; + return S_OK; + } + + return E_NOINTERFACE; +} + +//----------------------------- +// +//----------------------------- + +ULONG STDMETHODCALLTYPE CPropertySheet::AddRef(void) +{ + OutputDebugStringFormat("CPropertySheet::AddRef [%d]", m_RefCnt ); + return InterlockedIncrement(&m_RefCnt); +} + +//----------------------------- +// +//----------------------------- + +ULONG STDMETHODCALLTYPE CPropertySheet::Release(void) +{ + OutputDebugStringFormat("CPropertySheet::Release [%d]", m_RefCnt ); + long refcnt = InterlockedDecrement(&m_RefCnt); + + if (0 == refcnt) + delete this; + + return refcnt; +} + +//----------------------------- +// IShellExtInit +//----------------------------- + +HRESULT STDMETHODCALLTYPE CPropertySheet::Initialize( + LPCITEMIDLIST /*pidlFolder*/, LPDATAOBJECT lpdobj, HKEY /*hkeyProgID*/) +{ + InitCommonControls(); + + STGMEDIUM medium; + FORMATETC fe = {CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}; + + HRESULT hr = lpdobj->GetData(&fe, &medium); + + // save the file name + if (SUCCEEDED(hr) && + (1 == DragQueryFileA( + reinterpret_cast<HDROP>(medium.hGlobal), + 0xFFFFFFFF, + NULL, + 0))) + { + UINT size = DragQueryFile( reinterpret_cast<HDROP>(medium.hGlobal), 0, 0, 0 ); + if ( size != 0 ) + { + TCHAR * buffer = new TCHAR[ size + 1 ]; + UINT result_size = DragQueryFile( reinterpret_cast<HDROP>(medium.hGlobal), + 0, buffer, size + 1 ); + if ( result_size != 0 ) + { + std::wstring fname = getShortPathName( buffer ); + std::string fnameA = WStringToString( fname ); + ZeroMemory( m_szFileName, sizeof( m_szFileName ) ); + strncpy( m_szFileName, fnameA.c_str(), ( sizeof( m_szFileName ) - 1 ) ); + hr = S_OK; + } + else + hr = E_INVALIDARG; + delete [] buffer; + } + else + hr = E_INVALIDARG; + } + else + hr = E_INVALIDARG; + + ReleaseStgMedium(&medium); + + return hr; +} + +//----------------------------- +// IShellPropSheetExt +//----------------------------- + +HRESULT STDMETHODCALLTYPE CPropertySheet::AddPages(LPFNADDPROPSHEETPAGE lpfnAddPage, LPARAM lParam) +{ + // Get OS version (we don't need the summary page on Windows Vista or later) + OSVERSIONINFO sInfoOS; + + ZeroMemory( &sInfoOS, sizeof(OSVERSIONINFO) ); + sInfoOS.dwOSVersionInfoSize = sizeof( OSVERSIONINFO ); + GetVersionEx( &sInfoOS ); + bool bIsVistaOrLater = (sInfoOS.dwMajorVersion >= 6); + + std::wstring proppage_header; + + PROPSHEETPAGE psp; + ZeroMemory(&psp, sizeof(PROPSHEETPAGEA)); + + // add the summary property page + psp.dwSize = sizeof(PROPSHEETPAGE); + psp.dwFlags = PSP_DEFAULT | PSP_USETITLE | PSP_USECALLBACK; + psp.hInstance = GetModuleHandle(MODULE_NAME); + psp.lParam = reinterpret_cast<LPARAM>(this); + psp.pfnCallback = reinterpret_cast<LPFNPSPCALLBACK>(CPropertySheet::PropPageSummaryCallback); + + HPROPSHEETPAGE hPage = NULL; + + if ( !bIsVistaOrLater ) + { + proppage_header = GetResString(IDS_PROPPAGE_SUMMARY_TITLE); + + psp.pszTemplate = MAKEINTRESOURCE(IDD_PROPPAGE_SUMMARY); + psp.pszTitle = proppage_header.c_str(); + psp.pfnDlgProc = reinterpret_cast<DLGPROC>(CPropertySheet::PropPageSummaryProc); + + hPage = CreatePropertySheetPage(&psp); + + // keep this instance alive, will be released when the + // the page is about to be destroyed in the callback function + + if (hPage) + { + if (lpfnAddPage(hPage, lParam)) + AddRef(); + else + DestroyPropertySheetPage(hPage); + } + } + + // add the statistics property page + proppage_header = GetResString(IDS_PROPPAGE_STATISTICS_TITLE); + + psp.pszTemplate = MAKEINTRESOURCE(IDD_PROPPAGE_STATISTICS); + psp.pszTitle = proppage_header.c_str(); + psp.pfnDlgProc = reinterpret_cast<DLGPROC>(CPropertySheet::PropPageStatisticsProc); + + hPage = CreatePropertySheetPage(&psp); + + if (hPage) + { + if (lpfnAddPage(hPage, lParam)) + AddRef(); + else + DestroyPropertySheetPage(hPage); + } + + // always return success else + // no property sheet will be + // displayed at all + return NOERROR; +} + +//----------------------------- +// +//----------------------------- + +HRESULT STDMETHODCALLTYPE CPropertySheet::ReplacePage( + UINT /*uPageID*/, LPFNADDPROPSHEETPAGE /*lpfnReplaceWith*/, LPARAM /*lParam*/) +{ + return E_NOTIMPL; +} + +//----------------------------- +// +//----------------------------- + +UINT CALLBACK CPropertySheet::PropPageSummaryCallback( + HWND /*hwnd*/, UINT uMsg, LPPROPSHEETPAGE ppsp) +{ + CPropertySheet* pImpl = + reinterpret_cast<CPropertySheet*>(ppsp->lParam); + + // release this instance, acquired + // in the AddPages method + if (PSPCB_RELEASE == uMsg) + { + pImpl->Release(); + } + + return TRUE; +} + + +//----------------------------- +// +//----------------------------- + +BOOL CALLBACK CPropertySheet::PropPageSummaryProc(HWND hwnd, UINT uiMsg, WPARAM /*wParam*/, LPARAM lParam) +{ + switch (uiMsg) + { + case WM_INITDIALOG: + { + LPPROPSHEETPAGE psp = reinterpret_cast<LPPROPSHEETPAGE>(lParam); + CPropertySheet* pImpl = reinterpret_cast<CPropertySheet*>(psp->lParam); + pImpl->InitPropPageSummary(hwnd, psp); + return TRUE; + } + } + + return FALSE; +} + +//----------------------------- +// +//----------------------------- + +BOOL CALLBACK CPropertySheet::PropPageStatisticsProc(HWND hwnd, UINT uiMsg, WPARAM /*wParam*/, LPARAM lParam) +{ + switch (uiMsg) + { + case WM_INITDIALOG: + { + LPPROPSHEETPAGE psp = reinterpret_cast<LPPROPSHEETPAGE>(lParam); + CPropertySheet* pImpl = reinterpret_cast<CPropertySheet*>(psp->lParam); + pImpl->InitPropPageStatistics(hwnd, psp); + return TRUE; + } + } + + return FALSE; +} + +//################################## +void CPropertySheet::InitPropPageSummary(HWND hwnd, LPPROPSHEETPAGE /*lppsp*/) +{ + try + { + CMetaInfoReader metaInfo(m_szFileName); + + SetWindowText(GetDlgItem(hwnd,IDC_TITLE), metaInfo.getTagData( META_INFO_TITLE ).c_str() ); + SetWindowText(GetDlgItem(hwnd,IDC_AUTHOR), metaInfo.getTagData( META_INFO_AUTHOR ).c_str() ); + SetWindowText(GetDlgItem(hwnd,IDC_SUBJECT), metaInfo.getTagData( META_INFO_SUBJECT ).c_str() ); + SetWindowText(GetDlgItem(hwnd,IDC_KEYWORDS), metaInfo.getTagData( META_INFO_KEYWORDS ).c_str() ); + + // comments read from meta.xml use "\n" for return, but this will not displayable in Edit control, add + // "\r" before "\n" to form "\r\n" in order to display return in Edit control. + std::wstring tempStr = metaInfo.getTagData( META_INFO_DESCRIPTION ).c_str(); + std::wstring::size_type itor = tempStr.find ( L"\n" , 0 ); + while (itor != std::wstring::npos) + { + tempStr.insert(itor, L"\r"); + itor = tempStr.find(L"\n", itor + 2); + } + SetWindowText(GetDlgItem(hwnd,IDC_COMMENTS), tempStr.c_str()); + } + catch (const std::exception&) + { + } +} + +//--------------------------------- +/** +*/ +void CPropertySheet::InitPropPageStatistics(HWND hwnd, LPPROPSHEETPAGE /*lppsp*/) +{ + try + { + CMetaInfoReader metaInfo(m_szFileName); + + document_statistic_reader_ptr doc_stat_reader = create_document_statistic_reader(m_szFileName, &metaInfo); + + statistic_group_list_t sgl; + doc_stat_reader->read(&sgl); + + list_view_builder_ptr lv_builder = create_list_view_builder( + GetDlgItem(hwnd, IDC_STATISTICSLIST), + GetResString(IDS_PROPERTY), + GetResString(IDS_PROPERTY_VALUE)); + + lv_builder->build(sgl); + } + catch (const std::exception&) + { + } +} diff --git a/shell/source/win32/shlxthandler/res/ctrylnglist.txt b/shell/source/win32/shlxthandler/res/ctrylnglist.txt new file mode 100644 index 000000000000..ec2196e4da43 --- /dev/null +++ b/shell/source/win32/shlxthandler/res/ctrylnglist.txt @@ -0,0 +1,29 @@ +1 LANG_ENGLISH SUBLANG_ENGLISH_US +3 LANG_PORTUGUESE SUBLANG_PORTUGUESE +4 LANG_GERMAN SUBLANG_GERMAN +7 LANG_RUSSIAN SUBLANG_DEFAULT +30 LANG_GREEK SUBLANG_DEFAULT +31 LANG_DUTCH SUBLANG_DUTCH +33 LANG_FRENCH SUBLANG_FRENCH +34 LANG_SPANISH SUBLANG_SPANISH +35 LANG_FINNISH SUBLANG_DEFAULT +36 LANG_HUNGARIAN SUBLANG_DEFAULT +39 LANG_ITALIAN SUBLANG_ITALIAN +42 LANG_CZECH SUBLANG_DEFAULT +43 LANG_SLOVAK SUBLANG_DEFAULT +44 LANG_ENGLISH SUBLANG_ENGLISH_UK +45 LANG_DANISH SUBLANG_DEFAULT +46 LANG_SWEDISH SUBLANG_SWEDISH +47 LANG_NORWEGIAN SUBLANG_NORWEGIAN_BOKMAL +48 LANG_POLISH SUBLANG_DEFAULT +49 LANG_GERMAN SUBLANG_DEFAULT +55 LANG_PORTUGUESE SUBLANG_PORTUGUESE_BRAZILIAN +81 LANG_JAPANESE SUBLANG_DEFAULT +82 LANG_KOREAN SUBLANG_KOREAN +86 LANG_CHINESE SUBLANG_CHINESE_SIMPLIFIED +88 LANG_CHINESE SUBLANG_CHINESE_TRADITIONAL +90 LANG_TURKISH SUBLANG_DEFAULT +96 LANG_ARABIC SUBLANG_DEFAULT +97 LANG_HEBREW SUBLANG_DEFAULT +37 LANG_CATALAN SUBLANG_DEFAULT +66 LANG_THAI SUBLANG_DEFAULT diff --git a/shell/source/win32/shlxthandler/res/makefile.mk b/shell/source/win32/shlxthandler/res/makefile.mk new file mode 100644 index 000000000000..ec0529015179 --- /dev/null +++ b/shell/source/win32/shlxthandler/res/makefile.mk @@ -0,0 +1,72 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + + +PRJ=..$/..$/..$/.. + +PRJNAME=shell +TARGET=shlxthdl + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +INCPRE+=$(MFC_INCLUDE) + +# --- Files -------------------------------------------------------- + + +RCFILES=$(RES)$/$(TARGET).rc + +ULFFILES=$(TARGET).ulf + +.IF "$(WITH_LANG)"!="" +ULFDIR:=$(COMMONMISC)$/$(TARGET) +.ELSE # "$(WITH_LANG)"!="" +ULFDIR:=. +.ENDIF # "$(WITH_LANG)"!="" + +# --- Targets ------------------------------------------------------ + +.IF "$(BUILD_X64)"!="" +$(RES)$/x64$/$(TARGET).res : $(RES)$/$(TARGET).res + -$(MKDIR) $(RES)$/x64 + @@cp $< $@ +.ENDIF # "$(BUILD_X64)"!="" + +.INCLUDE : set_wntx64.mk +.INCLUDE : target.mk +.INCLUDE : tg_wntx64.mk + + + +# Generate the native Windows resource file +# using lngconvex.exe + +$(RCFILES) : $(ULFDIR)$/shlxthdl.ulf makefile.mk rcfooter.txt rcheader.txt rctmpl.txt + $(subst,$(SOLARBINDIR)$/lngconvex,$(BIN)$/lngconvex $(LNGCONVEX)) -ulf $(ULFDIR)$/shlxthdl.ulf -rc $(RES)$/shlxthdl.rc -rct rctmpl.txt -rch rcheader.txt -rcf rcfooter.txt + diff --git a/shell/source/win32/shlxthandler/res/prop_img.bmp b/shell/source/win32/shlxthandler/res/prop_img.bmp Binary files differnew file mode 100644 index 000000000000..1849a8bb62f4 --- /dev/null +++ b/shell/source/win32/shlxthandler/res/prop_img.bmp diff --git a/shell/source/win32/shlxthandler/res/rcfooter.txt b/shell/source/win32/shlxthandler/res/rcfooter.txt new file mode 100644 index 000000000000..ce333b32a1d5 --- /dev/null +++ b/shell/source/win32/shlxthandler/res/rcfooter.txt @@ -0,0 +1,4 @@ + + +IDP_SIGNET RCDATA "signet.png" + diff --git a/shell/source/win32/shlxthandler/res/rcheader.txt b/shell/source/win32/shlxthandler/res/rcheader.txt new file mode 100644 index 000000000000..fac9fa31f256 --- /dev/null +++ b/shell/source/win32/shlxthandler/res/rcheader.txt @@ -0,0 +1,15 @@ +#if defined(_MSC_VER) && (_MSC_VER < 1500) +#include <winres.h> +#else +#define WINVER 0x0500 +#include <winresrc.h> +#define LB_ADDSTRING (WM_USER+1) +#define CB_ADDSTRING (WM_USER+3) +#define IDC_STATIC (-1) +#endif + +#include "internal/resource.h" + +MANIFEST_RESOURCE_ID RT_MANIFEST "shlxthdl.manifest" + +IDB_PROPERTY_IMAGES BITMAP "prop_img.bmp" diff --git a/shell/source/win32/shlxthandler/res/rctmpl.txt b/shell/source/win32/shlxthandler/res/rctmpl.txt new file mode 100644 index 000000000000..a512c69dd9d7 --- /dev/null +++ b/shell/source/win32/shlxthandler/res/rctmpl.txt @@ -0,0 +1,71 @@ + +// Dialog + +IDD_PROPPAGE_SUMMARY DIALOGEX 0, 0, 222, 211 +STYLE WS_CHILD +FONT 8, "MS Sans Serif" +BEGIN + LTEXT %TITLE_COLON% ,IDC_STATIC,7,14,39,10 + LTEXT %AUTHOR_COLON% ,IDC_STATIC,7,31,47,10 + LTEXT %SUBJECT_COLON% ,IDC_STATIC,7,47,39,10 + LTEXT %KEYWORDS_COLON% ,IDC_STATIC,7,94,49,10 + EDITTEXT IDC_TITLE,63,12,154,12,ES_AUTOHSCROLL | ES_READONLY | + NOT WS_BORDER,WS_EX_CLIENTEDGE + EDITTEXT IDC_AUTHOR,63,29,154,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER, + WS_EX_CLIENTEDGE + EDITTEXT IDC_SUBJECT,63,46,154,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER, + WS_EX_CLIENTEDGE + EDITTEXT IDC_KEYWORDS,64,93,154,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER, + WS_EX_CLIENTEDGE + CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,7,75,211,1 + EDITTEXT IDC_COMMENTS,64,111,154,83,ES_MULTILINE | ES_LEFT | ES_READONLY | ES_WANTRETURN | + NOT WS_BORDER | WS_VSCROLL,WS_EX_CLIENTEDGE + LTEXT %COMMENTS_COLON% ,IDC_STATIC,7,112,49,10 +END + +IDD_PROPPAGE_STATISTICS DIALOG DISCARDABLE 0, 0, 222, 215 +STYLE WS_CHILD +FONT 8, "MS Sans Serif" +BEGIN + CONTROL "",IDC_STATISTICSLIST,"SysListView32",LVS_REPORT | + WS_BORDER | WS_TABSTOP,6,7,214,186 +END + +// String Table + +STRINGTABLE DISCARDABLE +BEGIN + IDS_TITLE %TITLE% + IDS_TITLE_COLON %TITLE_COLON% + IDS_SUBJECT %SUBJECT% + IDS_SUBJECT_COLON %SUBJECT_COLON% + IDS_AUTHOR %AUTHOR% + IDS_AUTHOR_COLON %AUTHOR_COLON% + IDS_KEYWORDS %KEYWORDS% + IDS_COMMENTS %COMMENTS% + IDS_COMMENTS_COLON %COMMENTS_COLON% + IDS_PAGES %PAGES% + IDS_TABLES %TABLES% + IDS_GRAPHICS %GRAPHICS% + IDS_OBJECTS %OBJECTS% + IDS_OLE_OBJECTS %OLE_OBJECTS% + IDS_PARAGRAPHS %PARAGRAPHS% + IDS_WORDS %WORDS% + IDS_CHARACTERS %CHARACTERS% + IDS_ROWS %ROWS% + IDS_ORIGIN %ORIGIN% + IDS_VERSION %VERSION% + IDS_SHEETS %SHEETS% + IDS_CELLS %CELLS% + IDS_MODIFIED %MODIFIED% + IDS_MODIFIED_COLON %MODIFIED_COLON% + IDS_DOCUMENT_NUMBER %DOCUMENT_NUMBER% + IDS_EDITING_TIME %EDITING_TIME% + IDS_PROPPAGE_STATISTICS_TITLE %STATISTICS_TITLE% + IDS_PROPPAGE_SUMMARY_TITLE %SUMMARY_TITLE% + IDS_PROPERTY %PROPERTY% + IDS_PROPERTY_VALUE %PROPERTY_VALUE% + IDS_DESCRIPTION %DESCRIPTION% + IDS_SIZE_COLON %SIZE_COLON% + IDS_TYPE_COLON %TYPE_COLON% +END diff --git a/shell/source/win32/shlxthandler/res/shlxthdl.manifest b/shell/source/win32/shlxthandler/res/shlxthdl.manifest new file mode 100644 index 000000000000..a785006a9601 --- /dev/null +++ b/shell/source/win32/shlxthandler/res/shlxthdl.manifest @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> +<assemblyIdentity version="1.0.0.0" processorArchitecture="x86" name="OpenOffice.shlxthdl" type="win32" /> +<description>OpenOffice Shell Extension</description> +<dependency> +<dependentAssembly> +<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="X86" + publicKeyToken="6595b64144ccf1df" language="*"/> +</dependentAssembly> +</dependency> +</assembly> diff --git a/shell/source/win32/shlxthandler/res/shlxthdl.ulf b/shell/source/win32/shlxthandler/res/shlxthdl.ulf new file mode 100644 index 000000000000..c0e879724e5d --- /dev/null +++ b/shell/source/win32/shlxthandler/res/shlxthdl.ulf @@ -0,0 +1,148 @@ +[%TITLE%] +en-US = "Title" + +[%TITLE_COLON%] +en-US = "Title:" + +[%SUBJECT%] +en-US = "Subject" + +[%SUBJECT_COLON%] +en-US = "Subject:" + +[%AUTHOR%] +en-US = "Author" + +[%AUTHOR_COLON%] +en-US = "Author:" + +[%KEYWORDS%] +en-US = "Keywords" + +[%KEYWORDS_COLON%] +en-US = "Keywords:" + +[%COMMENTS%] +en-US = "Comments" + +[%COMMENTS_COLON%] +en-US = "Comments:" + +[%PAGES%] +en-US = "Pages" + +[%TABLES%] +en-US = "Tables" + +[%GRAPHICS%] +en-US = "Graphics" + +[%OBJECTS%] +en-US = "Objects" + +[%OLE_OBJECTS%] +en-US = "OLE Objects" + +[%PARAGRAPHS%] +en-US = "Paragraphs" + +[%WORDS%] +en-US = "Words" + +[%CHARACTERS%] +en-US = "Characters" + +[%ROWS%] +en-US = "Lines" + +[%ORIGIN%] +en-US = "Origin" + +[%VERSION%] +en-US = "Version" + +[%SHEETS%] +en-US = "Sheets" + +[%CELLS%] +en-US = "Cells" + +[%STATISTICS_TITLE%] +en-US = "Document Statistics" + +[%SUMMARY_TITLE%] +en-US = "Summary" + +[%PROPERTY%] +en-US = "Property" + +[%PROPERTY_VALUE%] +en-US = "Value" + +[%MODIFIED%] +en-US = "Modified" + +[%MODIFIED_COLON%] +en-US = "Modified:" + +[%DOCUMENT_NUMBER%] +en-US = "Revision number" + +[%DOCUMENT_NUMBER_COLON%] +en-US = "Revision number:" + +[%EDITING_TIME%] +en-US = "Total editing time" + +[%EDITING_TIME_COLON%] +en-US = "Total editing time:" + +[%DESCRIPTION%] +en-US = "Description" + +[%DESCRIPTION_COLON%] +en-US = "Description:" + +[%SIZE_COLON%] +en-US = "Size:" + +[%TYPE_COLON%] +en-US = "Type:" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/shell/source/win32/shlxthandler/res/signet.png b/shell/source/win32/shlxthandler/res/signet.png Binary files differnew file mode 100644 index 000000000000..bccaaff817d1 --- /dev/null +++ b/shell/source/win32/shlxthandler/res/signet.png diff --git a/shell/source/win32/shlxthandler/shlxthdl.cxx b/shell/source/win32/shlxthandler/shlxthdl.cxx new file mode 100755 index 000000000000..6263c98ea749 --- /dev/null +++ b/shell/source/win32/shlxthandler/shlxthdl.cxx @@ -0,0 +1,427 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_shell.hxx" +#include "internal/config.hxx" +#include "internal/global.hxx" +#include "internal/shlxthdl.hxx" +#include "classfactory.hxx" +#include "internal/registry.hxx" +#include "internal/fileextensions.hxx" +#include "internal/utilities.hxx" + +#include <tchar.h> +#include <string> +#include <shlobj.h> + +//--------------------------- +// Module global +//--------------------------- +long g_DllRefCnt = 0; +HINSTANCE g_hModule = NULL; + +namespace /* private */ +{ + const char* GUID_PLACEHOLDER = "{GUID}"; + const char* EXTENSION_PLACEHOLDER = "{EXT}"; + const char* FORWARDKEY_PLACEHOLDER = "{FWDKEY}"; + + const char* CLSID_ENTRY = "CLSID\\{GUID}\\InProcServer32"; + const char* SHELLEX_IID_ENTRY = "{EXT}\\shellex\\{GUID}"; + const char* SHELLEX_ENTRY = "{EXT}\\shellex"; + const char* PROPSHEET_ENTRY = "{EXT}\\CLSID\\{GUID}\\InProcServer32"; + const char* EXTENSION_CLSID = "{EXT}\\CLSID"; + const char* EXTENSION_CLSID_GUID = "{EXT}\\CLSID\\{GUID}"; + const char* FORWARD_PROPSHEET_MYPROPSHEET_ENTRY = "{FWDKEY}\\shellex\\PropertySheetHandlers\\MyPropSheet1"; + const char* FORWARD_PROPSHEET_ENTRY = "{FWDKEY}\\shellex\\PropertySheetHandlers"; + const char* FORWARD_SHELLEX_ENTRY = "{FWDKEY}\\shellex"; + + const char* SHELL_EXTENSION_APPROVED_KEY_NAME = "Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved"; + + //--------------------------- + // "String Placeholder" -> + // "String Replacement" + //--------------------------- + void SubstitutePlaceholder(std::string& String, const std::string& Placeholder, const std::string& Replacement) + { + std::string::size_type idx = String.find(Placeholder); + std::string::size_type len = Placeholder.length(); + + while (std::string::npos != idx) + { + String.replace(idx, len, Replacement); + idx = String.find(Placeholder); + } + } + + /* Make the registry entry + HKCR\CLSID\{GUID} + InProcServer32 = Path\shlxthdl.dll + ThreadingModel = Apartment + */ + HRESULT RegisterComComponent(const char* FilePath, const CLSID& Guid) + { + std::string ClsidEntry = CLSID_ENTRY; + SubstitutePlaceholder(ClsidEntry, GUID_PLACEHOLDER, ClsidToString(Guid)); + + if (!SetRegistryKey(HKEY_CLASSES_ROOT, ClsidEntry.c_str(), "", FilePath)) + return E_FAIL; + + if (!SetRegistryKey(HKEY_CLASSES_ROOT, ClsidEntry.c_str(), "ThreadingModel", "Apartment")) + return E_FAIL; + + return S_OK; + } + + HRESULT UnregisterComComponent(const CLSID& Guid) + { + std::string tmp = "CLSID\\"; + tmp += ClsidToString(Guid); + return DeleteRegistryKey(HKEY_CLASSES_ROOT, tmp.c_str()) ? S_OK : E_FAIL; + } + + HRESULT RegisterColumnHandler(const char* ModuleFileName) + { + if (FAILED(RegisterComComponent(ModuleFileName, CLSID_COLUMN_HANDLER))) + return E_FAIL; + + std::string tmp = "Folder\\shellex\\ColumnHandlers\\"; + tmp += ClsidToString(CLSID_COLUMN_HANDLER); + + return SetRegistryKey( + HKEY_CLASSES_ROOT, + tmp.c_str(), + "", + WStringToString(COLUMN_HANDLER_DESCRIPTIVE_NAME).c_str()) ? S_OK : E_FAIL; + } + + HRESULT UnregisterColumnHandler() + { + std::string tmp = "Folder\\shellex\\ColumnHandlers\\"; + tmp += ClsidToString(CLSID_COLUMN_HANDLER); + + if (!DeleteRegistryKey(HKEY_CLASSES_ROOT, tmp.c_str())) + return E_FAIL; + + return UnregisterComComponent(CLSID_COLUMN_HANDLER); + } + + HRESULT RegisterInfotipHandler(const char* ModuleFileName) + { + if (FAILED(RegisterComComponent(ModuleFileName, CLSID_INFOTIP_HANDLER))) + return E_FAIL; + + std::string iid = ClsidToString(IID_IQueryInfo); + std::string tmp; + + for(size_t i = 0; i < OOFileExtensionTableSize; i++) + { + tmp = SHELLEX_IID_ENTRY; + SubstitutePlaceholder(tmp, EXTENSION_PLACEHOLDER, OOFileExtensionTable[i].ExtensionAnsi); + SubstitutePlaceholder(tmp, GUID_PLACEHOLDER, iid); + + if (!SetRegistryKey(HKEY_CLASSES_ROOT, tmp.c_str(), "", ClsidToString(CLSID_INFOTIP_HANDLER).c_str())) + return E_FAIL; + } + return S_OK; + } + + HRESULT UnregisterInfotipHandler() + { + std::string iid = ClsidToString(IID_IQueryInfo); + std::string tmp; + + for (size_t i = 0; i < OOFileExtensionTableSize; i++) + { + tmp = SHELLEX_IID_ENTRY; + + SubstitutePlaceholder(tmp, EXTENSION_PLACEHOLDER, OOFileExtensionTable[i].ExtensionAnsi); + SubstitutePlaceholder(tmp, GUID_PLACEHOLDER, iid); + + DeleteRegistryKey(HKEY_CLASSES_ROOT, tmp.c_str()); + + // if there are no further subkey below .ext\\shellex + // delete the whole subkey + tmp = SHELLEX_ENTRY; + SubstitutePlaceholder(tmp, EXTENSION_PLACEHOLDER, OOFileExtensionTable[i].ExtensionAnsi); + + bool HasSubKeys = true; + if (HasSubkeysRegistryKey(HKEY_CLASSES_ROOT, tmp.c_str(), HasSubKeys) && !HasSubKeys) + DeleteRegistryKey(HKEY_CLASSES_ROOT, tmp.c_str()); + } + return UnregisterComComponent(CLSID_INFOTIP_HANDLER); + } + + HRESULT RegisterPropSheetHandler(const char* ModuleFileName) + { + std::string ExtEntry; + std::string FwdKeyEntry; + + if (FAILED(RegisterComComponent(ModuleFileName, CLSID_PROPERTYSHEET_HANDLER))) + return E_FAIL; + + for (size_t i = 0; i < OOFileExtensionTableSize; i++) + { + FwdKeyEntry = FORWARD_PROPSHEET_MYPROPSHEET_ENTRY; + SubstitutePlaceholder(FwdKeyEntry, FORWARDKEY_PLACEHOLDER, OOFileExtensionTable[i].RegistryForwardKey); + + if (!SetRegistryKey(HKEY_CLASSES_ROOT, FwdKeyEntry.c_str(), "", ClsidToString(CLSID_PROPERTYSHEET_HANDLER).c_str())) + return E_FAIL; + } + return S_OK; + } + + HRESULT UnregisterPropSheetHandler() + { + std::string ExtEntry; + std::string FwdKeyEntry; + + for (size_t i = 0; i < OOFileExtensionTableSize; i++) + { + FwdKeyEntry = FORWARD_PROPSHEET_MYPROPSHEET_ENTRY; + SubstitutePlaceholder(FwdKeyEntry, FORWARDKEY_PLACEHOLDER, OOFileExtensionTable[i].RegistryForwardKey); + + DeleteRegistryKey(HKEY_CLASSES_ROOT, FwdKeyEntry.c_str()); + + FwdKeyEntry = FORWARD_PROPSHEET_ENTRY; + SubstitutePlaceholder(FwdKeyEntry, FORWARDKEY_PLACEHOLDER, OOFileExtensionTable[i].RegistryForwardKey); + + bool HasSubKeys = true; + if (HasSubkeysRegistryKey(HKEY_CLASSES_ROOT, FwdKeyEntry.c_str(), HasSubKeys) && !HasSubKeys) + DeleteRegistryKey(HKEY_CLASSES_ROOT, FwdKeyEntry.c_str()); + + FwdKeyEntry = FORWARD_SHELLEX_ENTRY; + SubstitutePlaceholder(FwdKeyEntry, FORWARDKEY_PLACEHOLDER, OOFileExtensionTable[i].RegistryForwardKey); + + HasSubKeys = true; + if (HasSubkeysRegistryKey(HKEY_CLASSES_ROOT, FwdKeyEntry.c_str(), HasSubKeys) && !HasSubKeys) + DeleteRegistryKey(HKEY_CLASSES_ROOT, FwdKeyEntry.c_str()); + } + + return UnregisterComComponent(CLSID_PROPERTYSHEET_HANDLER); + } + + HRESULT RegisterThumbviewerHandler(const char* ModuleFileName) + { + if (FAILED(RegisterComComponent(ModuleFileName, CLSID_THUMBVIEWER_HANDLER))) + return E_FAIL; + + std::string iid = ClsidToString(IID_IExtractImage); + std::string tmp; + + for(size_t i = 0; i < OOFileExtensionTableSize; i++) + { + tmp = SHELLEX_IID_ENTRY; + + SubstitutePlaceholder(tmp, EXTENSION_PLACEHOLDER, OOFileExtensionTable[i].ExtensionAnsi); + SubstitutePlaceholder(tmp, GUID_PLACEHOLDER, iid); + + if (!SetRegistryKey(HKEY_CLASSES_ROOT, tmp.c_str(), "", ClsidToString(CLSID_THUMBVIEWER_HANDLER).c_str())) + return E_FAIL; + } + return S_OK; + } + + HRESULT UnregisterThumbviewerHandler() + { + std::string iid = ClsidToString(IID_IExtractImage); + std::string tmp; + + for (size_t i = 0; i < OOFileExtensionTableSize; i++) + { + tmp = SHELLEX_IID_ENTRY; + + SubstitutePlaceholder(tmp, EXTENSION_PLACEHOLDER, OOFileExtensionTable[i].ExtensionAnsi); + SubstitutePlaceholder(tmp, GUID_PLACEHOLDER, iid); + + DeleteRegistryKey(HKEY_CLASSES_ROOT, tmp.c_str()); + + // if there are no further subkey below .ext\\shellex + // delete the whole subkey + tmp = SHELLEX_ENTRY; + SubstitutePlaceholder(tmp, EXTENSION_PLACEHOLDER, OOFileExtensionTable[i].ExtensionAnsi); + + bool HasSubKeys = true; + if (HasSubkeysRegistryKey(HKEY_CLASSES_ROOT, tmp.c_str(), HasSubKeys) && !HasSubKeys) + DeleteRegistryKey(HKEY_CLASSES_ROOT, tmp.c_str()); + } + return UnregisterComComponent(CLSID_THUMBVIEWER_HANDLER); + } + + /** Approving/Unapproving the Shell Extension, it's important under Windows + NT/2000/XP, see MSDN: Creating Shell Extension Handlers */ + HRESULT ApproveShellExtension(CLSID clsid, const std::wstring& Description) + { + bool bRet = SetRegistryKey( + HKEY_LOCAL_MACHINE, + SHELL_EXTENSION_APPROVED_KEY_NAME, + ClsidToString(clsid).c_str(), + WStringToString(Description).c_str()); + + return bRet ? S_OK : E_FAIL; + } + + HRESULT UnapproveShellExtension(CLSID Clsid) + { + HKEY hkey; + + LONG rc = RegOpenKeyA( + HKEY_LOCAL_MACHINE, + SHELL_EXTENSION_APPROVED_KEY_NAME, + &hkey); + + if (ERROR_SUCCESS == rc) + { + rc = RegDeleteValueA( + hkey, + ClsidToString(Clsid).c_str()); + + rc = RegCloseKey(hkey); + } + + return rc == ERROR_SUCCESS ? S_OK : E_FAIL; + } + +} // namespace /* private */ + + +//--------------------- +// COM exports +//--------------------- + +extern "C" STDAPI DllRegisterServer() +{ + TCHAR ModuleFileName[MAX_PATH]; + + GetModuleFileName( + GetModuleHandle(MODULE_NAME), + ModuleFileName, + sizeof(ModuleFileName)); + + std::string module_path = WStringToString(ModuleFileName); + HRESULT hr = S_OK; + + if (SUCCEEDED(RegisterColumnHandler(module_path.c_str()))) + ApproveShellExtension(CLSID_COLUMN_HANDLER, COLUMN_HANDLER_DESCRIPTIVE_NAME); + else + hr = E_FAIL; + + if (SUCCEEDED(RegisterInfotipHandler(module_path.c_str()))) + ApproveShellExtension(CLSID_INFOTIP_HANDLER, INFOTIP_HANDLER_DESCRIPTIVE_NAME); + else + hr = E_FAIL; + + if (SUCCEEDED(RegisterPropSheetHandler(module_path.c_str()))) + ApproveShellExtension(CLSID_PROPERTYSHEET_HANDLER, PROPSHEET_HANDLER_DESCRIPTIVE_NAME); + else + hr = E_FAIL; + + if (SUCCEEDED(RegisterThumbviewerHandler(module_path.c_str()))) + ApproveShellExtension(CLSID_THUMBVIEWER_HANDLER, THUMBVIEWER_HANDLER_DESCRIPTIVAE_NAME); + else + hr = E_FAIL; + + // notify the Shell that something has changed + SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, 0, 0); + + return hr; +} + +extern "C" STDAPI DllUnregisterServer() +{ + HRESULT hr = S_OK; + + if (FAILED(UnregisterColumnHandler())) + hr = E_FAIL; + + UnapproveShellExtension(CLSID_COLUMN_HANDLER); + + if (FAILED(UnregisterInfotipHandler())) + hr = E_FAIL; + + UnapproveShellExtension(CLSID_INFOTIP_HANDLER); + + if (FAILED(UnregisterPropSheetHandler())) + hr = E_FAIL; + + UnapproveShellExtension(CLSID_PROPERTYSHEET_HANDLER); + + if (FAILED(UnregisterThumbviewerHandler())) + hr = E_FAIL; + + UnapproveShellExtension(CLSID_THUMBVIEWER_HANDLER); + + // notify the Shell that something has changed + SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, 0, 0); + + return hr; +} + +extern "C" STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void** ppv) +{ + *ppv = 0; + + if ((rclsid != CLSID_INFOTIP_HANDLER) && + (rclsid != CLSID_COLUMN_HANDLER) && + (rclsid != CLSID_PROPERTYSHEET_HANDLER) && + (rclsid != CLSID_THUMBVIEWER_HANDLER)) + return CLASS_E_CLASSNOTAVAILABLE; + + if ((riid != IID_IUnknown) && (riid != IID_IClassFactory)) + return E_NOINTERFACE; + + if ( rclsid == CLSID_INFOTIP_HANDLER ) + OutputDebugStringFormat( "DllGetClassObject: Create CLSID_INFOTIP_HANDLER\n" ); + else if ( rclsid == CLSID_COLUMN_HANDLER ) + OutputDebugStringFormat( "DllGetClassObject: Create CLSID_COLUMN_HANDLER\n" ); + else if ( rclsid == CLSID_PROPERTYSHEET_HANDLER ) + OutputDebugStringFormat( "DllGetClassObject: Create CLSID_PROPERTYSHEET_HANDLER\n" ); + else if ( rclsid == CLSID_THUMBVIEWER_HANDLER ) + OutputDebugStringFormat( "DllGetClassObject: Create CLSID_THUMBVIEWER_HANDLER\n" ); + + IUnknown* pUnk = new CClassFactory(rclsid); + if (0 == pUnk) + return E_OUTOFMEMORY; + + *ppv = pUnk; + return S_OK; +} + +extern "C" STDAPI DllCanUnloadNow(void) +{ + if (CClassFactory::IsLocked() || g_DllRefCnt > 0) + return S_FALSE; + + return S_OK; +} + +BOOL WINAPI DllMain(HINSTANCE hInst, ULONG /*ul_reason_for_call*/, LPVOID /*lpReserved*/) +{ + g_hModule = hInst; + return TRUE; +} diff --git a/shell/source/win32/shlxthandler/thumbviewer/makefile.mk b/shell/source/win32/shlxthandler/thumbviewer/makefile.mk new file mode 100644 index 000000000000..1b7dd103026e --- /dev/null +++ b/shell/source/win32/shlxthandler/thumbviewer/makefile.mk @@ -0,0 +1,62 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/..$/..$/.. +PRJNAME=shell +TARGET=thumbviewer +LIBTARGET=NO +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +CFLAGS+=-DWIN32_LEAN_AND_MEAN -D_NTSDK -DUNICODE -D_UNICODE -D_WIN32_WINNT=0x0501 +#CFLAGS+=-wd4710 -wd4711 -wd4514 -wd4619 -wd4217 -wd4820 +CDEFS+=-D_WIN32_IE=0x501 + +# --- Files -------------------------------------------------------- + +SLOFILES=$(SLO)$/$(TARGET).obj + +.IF "$(BUILD_X64)"!="" +# ----------------- x64 ------------------------ +CFLAGS_X64+=-DWIN32_LEAN_AND_MEAN -D_NTSDK -DUNICODE -D_UNICODE -D_WIN32_WINNT=0x0501 +CDEFS_X64+=-D_WIN32_IE=0x501 + +SLOFILES_X64=$(SLO_X64)$/$(TARGET).obj +.ENDIF # "$(BUILD_X64)"!="" + + +# --- Targets ------------------------------------------------------ + +.INCLUDE : set_wntx64.mk +.INCLUDE : target.mk +INCLUDE!:=$(subst,/stl, $(INCLUDE)) +.EXPORT : INCLUDE +.INCLUDE : tg_wntx64.mk + diff --git a/shell/source/win32/shlxthandler/thumbviewer/thumbviewer.cxx b/shell/source/win32/shlxthandler/thumbviewer/thumbviewer.cxx new file mode 100755 index 000000000000..62fd306317be --- /dev/null +++ b/shell/source/win32/shlxthandler/thumbviewer/thumbviewer.cxx @@ -0,0 +1,533 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_shell.hxx" + +#include "internal/global.hxx" + +#ifndef INFOTIPS_HXX_INCLUDED +#include "internal/thumbviewer.hxx" +#endif +#include "internal/shlxthdl.hxx" +#include "internal/registry.hxx" +#include "internal/fileextensions.hxx" +#include "internal/config.hxx" +#include "internal/zipfile.hxx" +#include "internal/utilities.hxx" + +#include "internal/resource.h" + +#include <stdio.h> +#include <utility> +#include <stdlib.h> + +#if defined _MSC_VER +#pragma warning(push, 1) +#endif +#include <shellapi.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif +#include <memory> + +extern HINSTANCE g_hModule; + +namespace internal +{ + /* The signet.png used for thumbnails of signed documents + is contained as resource in this module, the resource + id is 2000 */ + void LoadSignetImageFromResource(ZipFile::ZipContentBuffer_t& buffer) + { + HRSRC hrc = FindResource(g_hModule, TEXT("#2000"), RT_RCDATA); + DWORD size = SizeofResource(g_hModule, hrc); + HGLOBAL hglob = LoadResource(g_hModule, hrc); + char* data = reinterpret_cast<char*>(LockResource(hglob)); + buffer = ZipFile::ZipContentBuffer_t(data, data + size); + } + + bool IsSignedDocument(const ZipFile* zipfile) + { + return zipfile->HasContent("META-INF/documentsignatures.xml"); + } + + bool IsWindowsXP() + { + OSVERSIONINFO osvi; + ZeroMemory(&osvi, sizeof(osvi)); + osvi.dwOSVersionInfoSize = sizeof(osvi); + GetVersionEx(&osvi); + + return ((osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) && + ((osvi.dwMajorVersion >= 5) && (osvi.dwMinorVersion >= 1))); + } + + /* Calculate where to position the signet image. + On Windows ME we need to shift the signet a + little bit to the left because Windows ME + puts an overlay icon to the lower right + corner of a thumbnail image so that our signet + we be hidden. */ + Gdiplus::Point CalcSignetPosition( + const Gdiplus::Rect& canvas, const Gdiplus::Rect& thumbnail_border, const Gdiplus::Rect& signet) + { + int x = 0; + int y = 0; + int hoffset = canvas.GetRight() - thumbnail_border.GetRight(); + int voffset = canvas.GetBottom() - thumbnail_border.GetBottom(); + + if (hoffset > voffset) + { + x = thumbnail_border.GetRight() - signet.GetRight() + min(signet.GetRight() / 2, hoffset); + y = thumbnail_border.GetBottom() - signet.GetBottom(); + } + else + { + x = thumbnail_border.GetRight() - signet.GetRight(); + y = thumbnail_border.GetBottom() - signet.GetBottom() + min(signet.GetBottom() / 2, voffset); + } + + if (!IsWindowsXP()) + x -= 15; + + return Gdiplus::Point(x,y); + } +} + +class StreamOnZipBuffer : public IStream +{ +public: + StreamOnZipBuffer(const ZipFile::ZipContentBuffer_t& zip_buffer); + + // IUnknown + virtual ULONG STDMETHODCALLTYPE AddRef(); + virtual ULONG STDMETHODCALLTYPE Release( void); + virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void __RPC_FAR *__RPC_FAR *ppvObject); + + // IStream + virtual HRESULT STDMETHODCALLTYPE Read(void *pv, ULONG cb, ULONG *pcbRead); + virtual HRESULT STDMETHODCALLTYPE Write(void const *pv, ULONG cb, ULONG *pcbWritten); + virtual HRESULT STDMETHODCALLTYPE Seek(LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition); + virtual HRESULT STDMETHODCALLTYPE SetSize(ULARGE_INTEGER libNewSize); + virtual HRESULT STDMETHODCALLTYPE CopyTo(IStream *pstm, ULARGE_INTEGER cb, ULARGE_INTEGER *pcbRead, ULARGE_INTEGER *pcbWritten); + virtual HRESULT STDMETHODCALLTYPE Commit(DWORD grfCommitFlags); + virtual HRESULT STDMETHODCALLTYPE Revert(void); + virtual HRESULT STDMETHODCALLTYPE LockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType); + virtual HRESULT STDMETHODCALLTYPE UnlockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType); + virtual HRESULT STDMETHODCALLTYPE Stat(STATSTG *pstatstg, DWORD grfStatFlag); + virtual HRESULT STDMETHODCALLTYPE Clone(IStream **ppstm); + +private: + LONG ref_count_; + const ZipFile::ZipContentBuffer_t& ref_zip_buffer_; + size_t pos_; +}; + +StreamOnZipBuffer::StreamOnZipBuffer(const ZipFile::ZipContentBuffer_t& zip_buffer) : + ref_count_(1), + ref_zip_buffer_(zip_buffer), + pos_(0) +{ +} + +// IUnknown methods + +ULONG STDMETHODCALLTYPE StreamOnZipBuffer::AddRef(void) +{ + return InterlockedIncrement(&ref_count_); +} + +ULONG STDMETHODCALLTYPE StreamOnZipBuffer::Release( void) +{ + long refcnt = InterlockedDecrement(&ref_count_); + + if (0 == ref_count_) + delete this; + + return refcnt; +} + +HRESULT STDMETHODCALLTYPE StreamOnZipBuffer::QueryInterface(REFIID riid, void __RPC_FAR *__RPC_FAR *ppvObject) +{ + *ppvObject = 0; + IUnknown* pUnk = 0; + + if ((IID_IUnknown == riid) || (IID_IStream == riid)) + { + pUnk = static_cast<IStream*>(this); + pUnk->AddRef(); + *ppvObject = pUnk; + return S_OK; + } + return E_NOINTERFACE; +} + +HRESULT STDMETHODCALLTYPE StreamOnZipBuffer::Read(void *pv, ULONG cb, ULONG *pcbRead) +{ + if (pv == NULL) + return STG_E_INVALIDPOINTER; + + size_t size = ref_zip_buffer_.size(); + + if (pos_ > size) + return S_FALSE; + + char* p = reinterpret_cast<char*>(pv); + ULONG read = 0; + + for ( ;(pos_ < size) && (cb > 0); pos_++, cb--, read++) + *p++ = ref_zip_buffer_[pos_]; + + if (pcbRead) + *pcbRead = read; + + return S_OK; +} + +HRESULT STDMETHODCALLTYPE StreamOnZipBuffer::Seek(LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *) +{ + __int64 size = (__int64) ref_zip_buffer_.size(); + __int64 p = 0; + + switch (dwOrigin) + { + case STREAM_SEEK_SET: + break; + case STREAM_SEEK_CUR: + p = (__int64) pos_; + break; + case STREAM_SEEK_END: + p = size - 1; + break; + } + + HRESULT hr = STG_E_INVALIDFUNCTION; + + p += dlibMove.QuadPart; + + if ( ( p >= 0 ) && (p < size) ) + { + pos_ = (size_t) p; + hr = S_OK; + } + return hr; +} + +HRESULT STDMETHODCALLTYPE StreamOnZipBuffer::Stat(STATSTG *pstatstg, DWORD grfStatFlag) +{ + if (pstatstg == NULL) + return STG_E_INVALIDPOINTER; + + ZeroMemory(pstatstg, sizeof(STATSTG)); + + if (grfStatFlag == STATFLAG_DEFAULT) + { + size_t sz = 4 * sizeof(wchar_t); + wchar_t* name = reinterpret_cast<wchar_t*>(CoTaskMemAlloc(sz)); + ZeroMemory(name, sz); + memcpy(name, L"png", 3 * sizeof(wchar_t)); + pstatstg->pwcsName = name; + } + + pstatstg->type = STGTY_LOCKBYTES; + + ULARGE_INTEGER uli; + uli.LowPart = ref_zip_buffer_.size(); + uli.HighPart = 0; + + pstatstg->cbSize = uli; + + return S_OK; +} + +HRESULT STDMETHODCALLTYPE StreamOnZipBuffer::Write(void const *, ULONG, ULONG *) +{ return E_NOTIMPL; } + +HRESULT STDMETHODCALLTYPE StreamOnZipBuffer::SetSize(ULARGE_INTEGER) +{ return E_NOTIMPL; } + +HRESULT STDMETHODCALLTYPE StreamOnZipBuffer::CopyTo(IStream *, ULARGE_INTEGER, ULARGE_INTEGER *, ULARGE_INTEGER *) +{ return E_NOTIMPL; } + +HRESULT STDMETHODCALLTYPE StreamOnZipBuffer::Commit(DWORD) +{ return E_NOTIMPL; } + +HRESULT STDMETHODCALLTYPE StreamOnZipBuffer::Revert(void) +{ return E_NOTIMPL; } + +HRESULT STDMETHODCALLTYPE StreamOnZipBuffer::LockRegion(ULARGE_INTEGER, ULARGE_INTEGER, DWORD) +{ return E_NOTIMPL; } + +HRESULT STDMETHODCALLTYPE StreamOnZipBuffer::UnlockRegion(ULARGE_INTEGER, ULARGE_INTEGER, DWORD) +{ return E_NOTIMPL; } + +HRESULT STDMETHODCALLTYPE StreamOnZipBuffer::Clone(IStream **) +{ return E_NOTIMPL; } + + +//######################################### + + +CThumbviewer::CThumbviewer(long RefCnt) : + ref_count_(RefCnt) +{ + InterlockedIncrement(&g_DllRefCnt); + + thumbnail_size_.cx = 0; + thumbnail_size_.cy = 0; + + Gdiplus::GdiplusStartupInput gdiplusStartupInput; + Gdiplus::GdiplusStartup(&gdiplus_token_, &gdiplusStartupInput, NULL); + + ZipFile::ZipContentBuffer_t img_data; + internal::LoadSignetImageFromResource(img_data); + IStream* stream = new StreamOnZipBuffer(img_data); + signet_ = new Gdiplus::Bitmap(stream, TRUE); + stream->Release(); +} + +CThumbviewer::~CThumbviewer() +{ + delete signet_; + Gdiplus::GdiplusShutdown(gdiplus_token_); + InterlockedDecrement(&g_DllRefCnt); +} + +// IUnknown methods + +HRESULT STDMETHODCALLTYPE CThumbviewer::QueryInterface(REFIID riid, void __RPC_FAR *__RPC_FAR *ppvObject) +{ + *ppvObject = 0; + IUnknown* pUnk = 0; + + if ((IID_IUnknown == riid) || (IID_IPersistFile == riid)) + { + pUnk = static_cast<IPersistFile*>(this); + pUnk->AddRef(); + *ppvObject = pUnk; + return S_OK; + } + else if (IID_IExtractImage == riid) + { + pUnk = static_cast<IExtractImage*>(this); + pUnk->AddRef(); + *ppvObject = pUnk; + return S_OK; + } + return E_NOINTERFACE; +} + +ULONG STDMETHODCALLTYPE CThumbviewer::AddRef(void) +{ + return InterlockedIncrement(&ref_count_); +} + +ULONG STDMETHODCALLTYPE CThumbviewer::Release( void) +{ + long refcnt = InterlockedDecrement(&ref_count_); + + if (0 == ref_count_) + delete this; + + return refcnt; +} + +// IExtractImage2 methods + +const std::string THUMBNAIL_CONTENT = "Thumbnails/thumbnail.png"; + +HRESULT STDMETHODCALLTYPE CThumbviewer::Extract(HBITMAP *phBmpImage) +{ + HRESULT hr = E_FAIL; + + try + { + std::wstring fname = getShortPathName( filename_ ); + std::auto_ptr<ZipFile> zipfile( new ZipFile( WStringToString( fname ) ) ); + + if (zipfile->HasContent(THUMBNAIL_CONTENT)) + { + ZipFile::ZipContentBuffer_t thumbnail; + zipfile->GetUncompressedContent(THUMBNAIL_CONTENT, thumbnail); + IStream* stream = new StreamOnZipBuffer(thumbnail); + + Gdiplus::Bitmap thumbnail_png(stream, TRUE); + + if ((thumbnail_png.GetHeight() == 0) || (thumbnail_png.GetWidth() == 0)) + { + stream->Release(); + return E_FAIL; + } + + HWND hwnd = GetDesktopWindow(); + HDC hdc = GetDC(hwnd); + HDC memDC = CreateCompatibleDC(hdc); + + if (memDC) + { + UINT offset = 3; // reserve a little border space + + Gdiplus::Rect canvas(0, 0, thumbnail_size_.cx, thumbnail_size_.cy); + Gdiplus::Rect canvas_thumbnail(offset, offset, thumbnail_size_.cx - 2 * offset, thumbnail_size_.cy - 2 * offset); + + Gdiplus::Rect scaledRect = CalcScaledAspectRatio( + Gdiplus::Rect(0, 0, thumbnail_png.GetWidth(), thumbnail_png.GetHeight()), canvas_thumbnail); + + struct { + BITMAPINFOHEADER bi; + DWORD ct[256]; + } dib; + + ZeroMemory(&dib, sizeof(dib)); + + dib.bi.biSize = sizeof(BITMAPINFOHEADER); + dib.bi.biWidth = thumbnail_size_.cx; + dib.bi.biHeight = thumbnail_size_.cy; + dib.bi.biPlanes = 1; + dib.bi.biBitCount = static_cast<WORD>(color_depth_); + dib.bi.biCompression = BI_RGB; + + LPVOID lpBits; + HBITMAP hMemBmp = CreateDIBSection(memDC, (LPBITMAPINFO)&dib, DIB_RGB_COLORS, &lpBits, NULL, 0); + HGDIOBJ hOldObj = SelectObject(memDC, hMemBmp); + + Gdiplus::Graphics graphics(memDC); + Gdiplus::Pen blackPen(Gdiplus::Color(255, 0, 0, 0), 1); + + Gdiplus::SolidBrush whiteBrush(Gdiplus::Color(255, 255, 255, 255)); + graphics.FillRectangle(&whiteBrush, canvas); + + scaledRect.X = (canvas.Width - scaledRect.Width) / 2; + scaledRect.Y = (canvas.Height - scaledRect.Height) / 2; + + Gdiplus::Rect border_rect(scaledRect.X, scaledRect.Y, scaledRect.Width, scaledRect.Height); + graphics.DrawRectangle(&blackPen, border_rect); + + scaledRect.X += 1; + scaledRect.Y += 1; + scaledRect.Width -= 1; + scaledRect.Height -= 1; + + graphics.SetInterpolationMode(Gdiplus::InterpolationModeHighQualityBicubic); + Gdiplus::Status stat = graphics.DrawImage( + &thumbnail_png, scaledRect, 0 , 0, + thumbnail_png.GetWidth(), thumbnail_png.GetHeight(), Gdiplus::UnitPixel); + + /* Add a signet sign to the thumbnail of signed documents */ + if (internal::IsSignedDocument(zipfile.get())) + { + double SCALING_FACTOR = 0.6; + Gdiplus::Rect signet_scaled( + 0, 0, static_cast<INT>(signet_->GetWidth() * SCALING_FACTOR), static_cast<INT>(signet_->GetHeight() * SCALING_FACTOR)); + Gdiplus::Point pos_signet = internal::CalcSignetPosition(canvas_thumbnail, border_rect, signet_scaled); + Gdiplus::Rect dest(pos_signet.X, pos_signet.Y, signet_scaled.GetRight(), signet_scaled.GetBottom()); + + stat = graphics.DrawImage( + signet_, dest, + 0, 0, signet_->GetWidth(), signet_->GetHeight(), + Gdiplus::UnitPixel); + } + + if (stat == Gdiplus::Ok) + { + *phBmpImage = hMemBmp; + hr = NOERROR; + } + + SelectObject(memDC, hOldObj); + DeleteDC(memDC); + } + + ReleaseDC(hwnd, hdc); + stream->Release(); + } + } + catch(std::exception&) + { + OutputDebugStringFormat( "CThumbviewer Extract ERROR!\n" ); + hr = E_FAIL; + } + return hr; +} + +HRESULT STDMETHODCALLTYPE CThumbviewer::GetLocation( + LPWSTR pszPathBuffer, DWORD cchMax, DWORD *pdwPriority, const SIZE *prgSize, DWORD dwRecClrDepth, DWORD *pdwFlags) +{ + if ((prgSize == NULL) || (pdwFlags == NULL) || ((*pdwFlags & IEIFLAG_ASYNC) && (pdwPriority == NULL))) + return E_INVALIDARG; + + thumbnail_size_ = *prgSize; + color_depth_ = dwRecClrDepth; + + *pdwFlags = IEIFLAG_CACHE; // we don't cache the image + + wcsncpy(pszPathBuffer, filename_.c_str(), cchMax); + + return NOERROR; +} + +// IPersist methods + +HRESULT STDMETHODCALLTYPE CThumbviewer::GetClassID(CLSID* pClassID) +{ + pClassID = const_cast<CLSID*>(&CLSID_THUMBVIEWER_HANDLER); + return S_OK; +} + +// IPersistFile methods + +HRESULT STDMETHODCALLTYPE CThumbviewer::Load(LPCOLESTR pszFileName, DWORD) +{ + filename_ = pszFileName; + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CThumbviewer::IsDirty() +{ return E_NOTIMPL; } + +HRESULT STDMETHODCALLTYPE CThumbviewer::Save(LPCOLESTR, BOOL) +{ return E_NOTIMPL; } + +HRESULT STDMETHODCALLTYPE CThumbviewer::SaveCompleted(LPCOLESTR) +{ return E_NOTIMPL; } + +HRESULT STDMETHODCALLTYPE CThumbviewer::GetCurFile(LPOLESTR __RPC_FAR*) +{ return E_NOTIMPL; } + + +Gdiplus::Rect CThumbviewer::CalcScaledAspectRatio(Gdiplus::Rect src, Gdiplus::Rect dest) +{ + Gdiplus::Rect result; + if (src.Width >= src.Height) + result = Gdiplus::Rect(0, 0, dest.Width, src.Height * dest.Width / src.Width); + else + result = Gdiplus::Rect(0, 0, src.Width * dest.Height / src.Height, dest.Height); + + return result; +} + diff --git a/shell/source/win32/shlxthandler/util/dbgmacros.cxx b/shell/source/win32/shlxthandler/util/dbgmacros.cxx new file mode 100644 index 000000000000..01ef1d47c083 --- /dev/null +++ b/shell/source/win32/shlxthandler/util/dbgmacros.cxx @@ -0,0 +1,58 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_shell.hxx" + +#if defined _MSC_VER +#pragma warning(push, 1) +#endif +#include <windows.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif +#include <stdio.h> +#include "internal/dbgmacros.hxx" + +void DbgAssert(bool /*condition*/, const char* /*message*/) +{ + + //if (!condition) + //{ + // char msg[1024]; + // + // sprintf(msg, "Assertion in file %s at line %d\n%s", __FILE__, __LINE__, message); + + // int nRet = MessageBoxA( + // 0, + // msg, + // "Assertion violation", + // MB_ICONEXCLAMATION | MB_ABORTRETRYIGNORE); + //} + +} + diff --git a/shell/source/win32/shlxthandler/util/fileextensions.cxx b/shell/source/win32/shlxthandler/util/fileextensions.cxx new file mode 100755 index 000000000000..13e3535c7aa7 --- /dev/null +++ b/shell/source/win32/shlxthandler/util/fileextensions.cxx @@ -0,0 +1,120 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_shell.hxx" +#include "algorithm" +#include "internal/fileextensions.hxx" + +//------------------------------------ +// +//------------------------------------ + +const std::string WRITER_FILE_EXTENSIONS = "sxwstwsxgodtottodm"; +const std::string CALC_FILE_EXTENSIONS = "sxcstcodsots"; +const std::string DRAW_FILE_EXTENSIONS = "sxdstdodgotg"; +const std::string IMPRESS_FILE_EXTENSIONS = "sxistiodpotp"; +const std::string MATH_FILE_EXTENSIONS = "sxmodf"; +const std::string WEB_FILE_EXTENSIONS = "oth"; +const std::string DATABASE_FILE_EXTENSIONS = "odb"; + +FileExtensionEntry OOFileExtensionTable[] = { + { ".sxw", L".sxw", "soffice.StarWriterDocument.6" }, + { ".sxc", L".sxc", "soffice.StarCalcDocument.6" }, + { ".sxi", L".sxi", "soffice.StarImpressDocument.6" }, + { ".sxd", L".sxd", "soffice.StarDrawDocument.6" }, + { ".sxm", L".sxm", "soffice.StarMathDocument.6" }, + { ".stw", L".stw", "soffice.StarWriterTemplate.6" }, + { ".sxg", L".sxg", "soffice.StarWriterGlobalDocument.6"}, + { ".std", L".std", "soffice.StarDrawTemplate.6" }, + { ".sti", L".sti", "soffice.StarImpressTemplate.6" }, + { ".stc", L".stc", "soffice.StarCalcTemplate.6" }, + { ".odt", L".odt", "opendocument.WriterDocument.1" }, + { ".ott", L".ott", "opendocument.WriterTemplate.1" }, + { ".odm", L".odm", "opendocument.WriterGlobalDocument.1" }, + { ".oth", L".oth", "opendocument.WriterWebTemplate.1" }, + { ".ods", L".ods", "opendocument.CalcDocument.1" }, + { ".ots", L".ots", "opendocument.CalcTemplate.1" }, + { ".odg", L".odg", "opendocument.DrawDocument.1" }, + { ".otg", L".otg", "opendocument.DrawTemplate.1" }, + { ".odp", L".odp", "opendocument.ImpressDocument.1" }, + { ".otp", L".otp", "opendocument.ImpressTemplate.1" }, + { ".odf", L".odf", "opendocument.MathDocument.1" }, + { ".odb", L".odb", "opendocument.DatabaseDocument.1" } + }; + + +size_t OOFileExtensionTableSize = sizeof(OOFileExtensionTable)/sizeof(OOFileExtensionTable[0]); + +//--------------------------------- +/** Return the extension of a file + name without the '.' +*/ +std::string get_file_name_extension(const std::string& file_name) +{ + std::string::size_type idx = file_name.find_last_of("."); + + if (std::string::npos != idx++) + return std::string(file_name.begin() + idx, file_name.end()); + + return std::string(); +} + +//--------------------------------- +/** Return the type of a file +*/ + +char easytolower( char in ) +{ + if( in<='Z' && in>='A' ) + return in-('Z'-'z'); + return in; +} + +File_Type_t get_file_type(const std::string& file_name) +{ + std::string fext = get_file_name_extension(file_name); + std::transform(fext.begin(), fext.end(), fext.begin(), easytolower); + + if (std::string::npos != WRITER_FILE_EXTENSIONS.find(fext)) + return WRITER; + else if (std::string::npos != CALC_FILE_EXTENSIONS.find(fext)) + return CALC; + else if (std::string::npos != DRAW_FILE_EXTENSIONS.find(fext)) + return DRAW; + else if (std::string::npos != IMPRESS_FILE_EXTENSIONS.find(fext)) + return IMPRESS; + else if (std::string::npos != MATH_FILE_EXTENSIONS.find(fext)) + return MATH; + else if (std::string::npos != WEB_FILE_EXTENSIONS.find(fext)) + return WEB; + else if (std::string::npos != DATABASE_FILE_EXTENSIONS.find(fext)) + return DATABASE; + else + return UNKNOWN; +} + diff --git a/shell/source/win32/shlxthandler/util/iso8601_converter.cxx b/shell/source/win32/shlxthandler/util/iso8601_converter.cxx new file mode 100644 index 000000000000..dcd779098865 --- /dev/null +++ b/shell/source/win32/shlxthandler/util/iso8601_converter.cxx @@ -0,0 +1,182 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_shell.hxx" +#include "internal/iso8601_converter.hxx" +#include "internal/utilities.hxx" + +#include <sstream> +#include <iomanip> + +//----------------------------------- +/* Converts ISO 8601 conform date/time + represenation to the representation + conforming to the current locale +*/ +std::wstring iso8601_date_to_local_date(const std::wstring& isoDate ) +{ + const std::wstring CONST_SPACE(L" "); + ::std::wstring ws8601DateTime(isoDate); + + if ( ws8601DateTime.length() == 19 ) + { + //fill in the SYSTEMTIME structure; + std::string asDateTime = WStringToString( ws8601DateTime ); + SYSTEMTIME DateTime; + DateTime.wYear = ( unsigned short )strtol( asDateTime.substr( 0, 4 ).c_str(), NULL, 10 ); + DateTime.wMonth = ( unsigned short )strtol( asDateTime.substr( 5, 2 ).c_str(), NULL, 10 ); + DateTime.wDayOfWeek = 0; + DateTime.wDay = ( unsigned short )strtol( asDateTime.substr( 8, 2 ).c_str(), NULL, 10 ); + DateTime.wHour = ( unsigned short )strtol( asDateTime.substr( 11,2 ).c_str(), NULL, 10 ); + DateTime.wMinute = ( unsigned short )strtol( asDateTime.substr( 14,2 ).c_str(), NULL, 10 ); + DateTime.wSecond = ( unsigned short )strtol( asDateTime.substr( 17,2 ).c_str(), NULL, 10 ); + DateTime.wMilliseconds = 0; + + //get Date info from structure + WCHAR DateBuffer[ MAX_PATH ]; + int DateSize = GetDateFormatW( + LOCALE_SYSTEM_DEFAULT, + 0, + &DateTime, + NULL, + DateBuffer, + MAX_PATH ); + + if ( DateSize ) + ws8601DateTime.assign(DateBuffer); + else + ws8601DateTime = StringToWString( asDateTime ); + + //get Time info from structure + WCHAR TimeBuffer[ MAX_PATH ]; + + int TimeSize = GetTimeFormatW( + LOCALE_SYSTEM_DEFAULT, + 0, + &DateTime, + NULL, + TimeBuffer, + MAX_PATH ); + + if ( TimeSize ) + { + ws8601DateTime.append(L" "); + ws8601DateTime.append(TimeBuffer); + } + else + ws8601DateTime = StringToWString( asDateTime ); + } + + return ws8601DateTime; +} + +//------------------------------------ +/* Converts ISO 8601 conform duration + representation to the representation + conforming to the current locale + + Expect format PTnHnMnS according to + ISO 8601 where n is abitrary number + of digits +*/ + +std::wstring iso8601_duration_to_local_duration(const std::wstring& iso8601duration) +{ + std::wstring days; + std::wstring hours; + std::wstring minutes; + std::wstring seconds; + + std::wstring::const_iterator iter = iso8601duration.begin(); + std::wstring::const_iterator iter_end = iso8601duration.end(); + + std::wstring num; + + for (/**/; iter != iter_end; ++iter) + { + if (isdigit(*iter)) + { + num += *iter; + } + else + { + if (*iter == L'D' || *iter == L'd') + days = num; + else if (*iter == L'H' || *iter == L'h') + hours = num; + else if (*iter == L'M' || *iter == L'm') + minutes = num; + else if (*iter == L'S' || *iter == L's') + seconds = num; + + num.clear(); + } + } + + if (days.length() > 0) + { + int h = ((_wtoi(days.c_str()) * 24) + _wtoi(hours.c_str())); + wchar_t buff[10]; + _itow(h, buff, 10); + hours = buff; + } + +#if defined(_MSC_VER) //&& defined(_M_X64) + std::wostringstream oss; + oss << std::setw(2) << std::setfill(wchar_t('0')) << hours << L":" << + std::setw(2) << std::setfill(wchar_t('0')) << minutes << L":" << + std::setw(2) << std::setfill(wchar_t('0')) << seconds; + return oss.str(); +#elif defined( __MINGW32__ ) +#define ADD_AS_PREFILLED( st, out ) \ + if ( st.length() == 0 ) \ + out += L"00"; \ + else if ( st.length() == 1 ) \ + out += L"0"; \ + out += st; + + std::wstring result; + ADD_AS_PREFILLED( hours, result ) + result += L":"; + ADD_AS_PREFILLED( minutes, result ) + result += L":"; + ADD_AS_PREFILLED( seconds, result ) + + return result; +#undef ADD_AS_PREFILLED +/* +#else + std::wostringstream oss; + oss << std::setw(2) << std::setfill('0') << hours << L":" << + std::setw(2) << std::setfill('0') << minutes << L":" << + std::setw(2) << std::setfill('0') << seconds; + return oss.str(); +*/ +#endif +} + diff --git a/shell/source/win32/shlxthandler/util/makefile.mk b/shell/source/win32/shlxthandler/util/makefile.mk new file mode 100644 index 000000000000..8ccf50602f93 --- /dev/null +++ b/shell/source/win32/shlxthandler/util/makefile.mk @@ -0,0 +1,68 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/..$/..$/.. +PRJNAME=shell +TARGET=util +#LIBTARGET=NO +ENABLE_EXCEPTIONS=TRUE + + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +CFLAGS+=-DISOLATION_AWARE_ENABLED -DWIN32_LEAN_AND_MEAN -DXML_UNICODE -D_NTSDK -DUNICODE -D_UNICODE -D_WIN32_WINNT=0x0501 +CFLAGS+=-wd4710 -wd4711 -wd4514 -wd4619 -wd4217 -wd4820 +CDEFS+=-D_WIN32_IE=0x501 + +CFLAGS_X64+=-DISOLATION_AWARE_ENABLED -DWIN32_LEAN_AND_MEAN -DXML_UNICODE -D_NTSDK -DUNICODE -D_UNICODE -D_WIN32_WINNT=0x0501 +CFLAGS_X64+=-wd4710 -wd4711 -wd4514 -wd4619 -wd4217 -wd4820 +CDEFS_X64+=-D_WIN32_IE=0x501 + +# --- Files -------------------------------------------------------- + +SLOFILES=$(SLO)$/dbgmacros.obj\ + $(SLO)$/fileextensions.obj\ + $(SLO)$/registry.obj\ + $(SLO)$/utilities.obj\ + $(SLO)$/iso8601_converter.obj + +SLOFILES_X64=$(SLO_X64)$/dbgmacros.obj\ + $(SLO_X64)$/fileextensions.obj\ + $(SLO_X64)$/registry.obj\ + $(SLO_X64)$/utilities.obj\ + $(SLO_X64)$/iso8601_converter.obj + +# --- Targets ------------------------------------------------------ + +.INCLUDE : set_wntx64.mk +.INCLUDE : target.mk +INCLUDE!:=$(subst,/stl, $(INCLUDE)) +.EXPORT : INCLUDE +.INCLUDE : tg_wntx64.mk + diff --git a/shell/source/win32/shlxthandler/util/registry.cxx b/shell/source/win32/shlxthandler/util/registry.cxx new file mode 100644 index 000000000000..bac126bb0504 --- /dev/null +++ b/shell/source/win32/shlxthandler/util/registry.cxx @@ -0,0 +1,205 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_shell.hxx" + +#if defined _MSC_VER +#pragma warning(push, 1) +#endif +#include <windows.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif +#include <malloc.h> +#include "internal/dbgmacros.hxx" +#include "internal/registry.hxx" + +#if defined _MSC_VER +#pragma warning(push, 1) +#endif +#include <objbase.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif + +//--------------------------------------- +// +//--------------------------------------- + +// Size of a CLSID as a string +const int CLSID_STRING_SIZE = 39; + +//--------------------------------------- +// +//--------------------------------------- + +bool SetRegistryKey(HKEY RootKey, const char* KeyName, const char* ValueName, const char* Value) +{ + HKEY hSubKey; + + // open or create the desired key + int rc = RegCreateKeyExA( + RootKey, KeyName, 0, "", REG_OPTION_NON_VOLATILE, KEY_WRITE, 0, &hSubKey, 0); + + if (ERROR_SUCCESS == rc) + { + rc = RegSetValueExA( + hSubKey, ValueName, 0, REG_SZ, reinterpret_cast<const BYTE*>(Value), strlen(Value) + 1); + + RegCloseKey(hSubKey); + } + + return (ERROR_SUCCESS == rc); +} + +//--------------------------------------- +// +//--------------------------------------- + +bool DeleteRegistryKey(HKEY RootKey, const char* KeyName) +{ + HKEY hKey; + + int rc = RegOpenKeyExA( + RootKey, + KeyName, + 0, + KEY_READ | DELETE, + &hKey); + + if ( rc == ERROR_FILE_NOT_FOUND ) + return true; + + if (ERROR_SUCCESS == rc) + { + char* SubKey; + DWORD nMaxSubKeyLen; + + rc = RegQueryInfoKeyA( + hKey, 0, 0, 0, 0, + &nMaxSubKeyLen, + 0, 0, 0, 0, 0, 0); + + nMaxSubKeyLen++; // space for trailing '\0' + + SubKey = reinterpret_cast<char*>( + _alloca(nMaxSubKeyLen*sizeof(char))); + + while (ERROR_SUCCESS == rc) + { + DWORD nLen = nMaxSubKeyLen; + + rc = RegEnumKeyExA( + hKey, + 0, // always index zero + SubKey, + &nLen, + 0, 0, 0, 0); + + if (ERROR_NO_MORE_ITEMS == rc) + { + rc = RegDeleteKeyA(RootKey, KeyName); + break; + } + else if (rc == ERROR_SUCCESS) + { + DeleteRegistryKey(hKey, SubKey); + } + + } // while + + RegCloseKey(hKey); + + } // if + + return (ERROR_SUCCESS == rc); +} + +/** May be used to determine if the specified registry key has subkeys + The function returns true on success else if an error occures false +*/ +bool HasSubkeysRegistryKey(HKEY RootKey, const char* KeyName, /* out */ bool& bResult) +{ + HKEY hKey; + + LONG rc = RegOpenKeyExA(RootKey, KeyName, 0, KEY_READ, &hKey); + + if (ERROR_SUCCESS == rc) + { + DWORD nSubKeys = 0; + + rc = RegQueryInfoKeyA(hKey, 0, 0, 0, &nSubKeys, 0, 0, 0, 0, 0, 0, 0); + + bResult = (nSubKeys > 0); + } + + return (ERROR_SUCCESS == rc); +} + +// Convert a CLSID to a char string. +std::string ClsidToString(const CLSID& clsid) +{ + // Get CLSID + LPOLESTR wszCLSID = NULL; + StringFromCLSID(clsid, &wszCLSID); + + char buff[39]; + // Covert from wide characters to non-wide. + wcstombs(buff, wszCLSID, sizeof(buff)); + + // Free memory. + CoTaskMemFree(wszCLSID) ; + + return std::string(buff); +} + +//--------------------------------------- +// +//--------------------------------------- + +bool QueryRegistryKey(HKEY RootKey, const char* KeyName, const char* ValueName, char *pszData, DWORD dwBufLen) +{ + HKEY hKey; + + int rc = RegOpenKeyExA( + RootKey, + KeyName, + 0, + KEY_READ, + &hKey); + + if (ERROR_SUCCESS == rc) + { + rc = RegQueryValueExA( + hKey, ValueName, NULL, NULL, (LPBYTE)pszData,&dwBufLen); + + RegCloseKey(hKey); + } + + return (ERROR_SUCCESS == rc); +} diff --git a/shell/source/win32/shlxthandler/util/utilities.cxx b/shell/source/win32/shlxthandler/util/utilities.cxx new file mode 100755 index 000000000000..005e4689cdce --- /dev/null +++ b/shell/source/win32/shlxthandler/util/utilities.cxx @@ -0,0 +1,599 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_shell.hxx" + + +#include "internal/config.hxx" +#include "internal/dbgmacros.hxx" +#include "internal/utilities.hxx" + +//----------------------------- +// constants +//----------------------------- + +const size_t MAX_RES_STRING = 1024; +const wchar_t SPACE_CHAR = _T(' '); + +//--------------------------------- +/** +*/ +std::wstring StringToWString(const std::string& String) +{ + int len = MultiByteToWideChar( + CP_ACP, 0, String.c_str(), -1, 0, 0); + + wchar_t* buff = reinterpret_cast<wchar_t*>( + _alloca(len * sizeof(wchar_t))); + + MultiByteToWideChar( + CP_ACP, 0, String.c_str(), -1, buff, len); + + return std::wstring(buff); +} + +//--------------------------------- +/** +*/ +std::string WStringToString(const std::wstring& String) +{ + int len = WideCharToMultiByte( + CP_ACP, 0, String.c_str(), -1, 0, 0, 0, 0); + + char* buff = reinterpret_cast<char*>( + _alloca(len * sizeof(char))); + + WideCharToMultiByte( + CP_ACP, 0, String.c_str(), -1, buff, len, 0, 0); + + return std::string(buff); +} + +//--------------------------------- +/** +*/ +std::wstring GetResString(int ResId) +{ + wchar_t szResStr[MAX_RES_STRING]; + + int rc = LoadStringW( GetModuleHandleW(MODULE_NAME), ResId, szResStr, sizeof(szResStr) ); + + OutputDebugStringFormat( "GetResString: read %d chars\n", rc ); + ENSURE(rc, "String resource not found"); + + return std::wstring(szResStr); +} + +//--------------------------------- +/** +*/ +bool is_windows_xp_or_above() +{ + OSVERSIONINFO osvi; + ZeroMemory(&osvi, sizeof(osvi)); + osvi.dwOSVersionInfoSize = sizeof(osvi); + GetVersionEx(&osvi); + + // LLA: check for windows xp or above (Vista) + if (osvi.dwMajorVersion > 5 || + (5 == osvi.dwMajorVersion && osvi.dwMinorVersion >= 1)) + { + return true; + } + return false; +} + +//--------------------------------- +/** +*/ + +void SaveDebugInfoToFile( const std::wstring& str ) +{ + int handle; + + if ((handle = open("c:\\temp\\SHELLRESULT.$$$", O_CREAT | O_RDWR | O_APPEND )) == -1) + { + perror("Error: open file error"); + return; + } + write(handle, str.c_str(), str.length() ); + close(handle); +} + +//--------------------------------- +/** helper function to judge if the string is only has spaces. + @returns + <TRUE>if the provided string contains only but at least one space + character else <FALSE/>. +*/ + +bool HasOnlySpaces(const std::wstring& String) +{ + if ( String.length() == 0 ) + return false; + + const wchar_t* p = String.c_str(); + + while (*p) + { + if (*p++ != SPACE_CHAR) + return false; + } + + return true; +} + +//--------------------------------- +/** helper function to convert windows pathes to short form. + @returns + shortend path. +*/ + +std::wstring getShortPathName( const std::wstring& aLongName ) +{ + std::wstring shortName = aLongName; + long length = GetShortPathName( aLongName.c_str(), NULL, 0 ); + + if ( length != 0 ) + { + TCHAR* buffer = new TCHAR[ length+1 ]; + length = GetShortPathName( aLongName.c_str(), buffer, length ); + if ( length != 0 ) + shortName = std::wstring( buffer ); + delete [] buffer; + } + return shortName; +} + +/** convert LocaleSet pair into Microsoft List of Locale ID (LCID) + according to ISO-639 and ISO-3166. + http://etext.lib.virginia.edu/tei/iso639.html + http://nl.ijs.si/gnusl/cee/std/ISO_3166.html + @param + Locale, LocaleSet + @returns + Windows Locale Identifier corresponding to input LocaleSet. + @Usage Sample + LocaleSet_t myDefaultLocale( ::std::wstring( L"zh" ),::std::wstring(L"HK") ); + DWORD myLCID = LocaleSetToLCID( myDefaultLocale ); + wchar_t buffer[20]; + _ultow( myLCID, buffer, 16 ); + MessageBox( NULL, buffer,L"the LCID is:",MB_OK ); +*/ + +LCID LocaleSetToLCID( const LocaleSet_t & Locale ) +{ + if ( EMPTY_LOCALE == Locale ) + return GetSystemDefaultLCID(); + + USHORT usPrimaryLang= LANG_NEUTRAL; + USHORT usSubLang=SUBLANG_DEFAULT; + + ::std::wstring wsLanguage(Locale.first); + ::std::wstring wsCountry(Locale.second); + + if ( wsLanguage == L"ar" ) + { + usPrimaryLang = LANG_ARABIC; // Arabic 01 + + if ( wsCountry == L"SA" ) + usSubLang = SUBLANG_ARABIC_SAUDI_ARABIA; // Arabic (Saudi Arabia) + else if ( wsCountry == L"IQ" ) + usSubLang = SUBLANG_ARABIC_IRAQ; // Arabic (Iraq) + else if ( wsCountry == L"EG" ) + usSubLang = SUBLANG_ARABIC_EGYPT; // Arabic (Egypt) + else if ( wsCountry == L"LY" ) + usSubLang = SUBLANG_ARABIC_LIBYA; // Arabic (Libya) + else if ( wsCountry == L"DZ" ) + usSubLang = SUBLANG_ARABIC_ALGERIA; // Arabic (Algeria) + else if ( wsCountry == L"MA" ) + usSubLang = SUBLANG_ARABIC_MOROCCO; // Arabic (Morocco) + else if ( wsCountry == L"TN" ) + usSubLang = SUBLANG_ARABIC_TUNISIA; // Arabic (Tunisia) + else if ( wsCountry == L"OM" ) + usSubLang = SUBLANG_ARABIC_OMAN; // Arabic (Oman) + else if ( wsCountry == L"YE" ) + usSubLang = SUBLANG_ARABIC_YEMEN; // Arabic (Yemen) + else if ( wsCountry == L"SY" ) + usSubLang = SUBLANG_ARABIC_SYRIA; // Arabic (Syria) + else if ( wsCountry == L"JO" ) + usSubLang = SUBLANG_ARABIC_JORDAN; // Arabic (Jordan) + else if ( wsCountry == L"LB" ) + usSubLang = SUBLANG_ARABIC_LEBANON; // Arabic (Lebanon) + else if ( wsCountry == L"KW" ) + usSubLang = SUBLANG_ARABIC_KUWAIT; // Arabic (Kuwait) + else if ( wsCountry == L"AE" ) + usSubLang = SUBLANG_ARABIC_UAE; // Arabic (U.A.E.) + else if ( wsCountry == L"BH" ) + usSubLang = SUBLANG_ARABIC_BAHRAIN; // Arabic (Bahrain) + else if ( wsCountry == L"QA" ) + usSubLang = SUBLANG_ARABIC_QATAR; // Arabic (Qatar) + else + usSubLang = SUBLANG_DEFAULT; //default sub language + } + else if ( wsLanguage == L"bg" ) + usPrimaryLang = LANG_BULGARIAN; //Bulgarian 02 + else if ( wsLanguage == L"ca" ) + usPrimaryLang = LANG_CATALAN; //Catalan 03 + else if ( wsLanguage == L"zh" ) + { + usPrimaryLang = LANG_CHINESE; //Chinese + if ( wsCountry == L"TW" ) + usSubLang = SUBLANG_CHINESE_TRADITIONAL; // Chinese (Traditional) + else if ( wsCountry == L"CN" ) + usSubLang = SUBLANG_CHINESE_SIMPLIFIED; // Chinese (Simplified) + else if ( wsCountry == L"HK" ) + usSubLang = SUBLANG_CHINESE_HONGKONG; // Chinese (Hong Kong SAR, PRC) + else if ( wsCountry == L"SG" ) + usSubLang = SUBLANG_CHINESE_SINGAPORE; // Chinese (Singapore) + else if ( wsCountry == L"MO" ) + usSubLang = SUBLANG_CHINESE_MACAU; // Chinese (Macau SAR) + else + usSubLang = SUBLANG_DEFAULT; //default sub language + } + else if ( wsLanguage == L"cs" ) + usPrimaryLang = LANG_CZECH; //Czech + else if ( wsLanguage == L"da" ) + usPrimaryLang = LANG_DANISH; //Danish + else if ( wsLanguage == L"de" ) + { + usPrimaryLang = LANG_GERMAN; //German + if ( wsCountry == L"DE" ) + usSubLang = SUBLANG_GERMAN; // German + else if ( wsCountry == L"CH" ) + usSubLang = SUBLANG_GERMAN_SWISS; // German (Swiss) + else if ( wsCountry == L"AT" ) + usSubLang = SUBLANG_GERMAN_AUSTRIAN; // German (Austrian) + else if ( wsCountry == L"LU" ) + usSubLang = SUBLANG_GERMAN_LUXEMBOURG; // German (Luxembourg) + else if ( wsCountry == L"LI" ) + usSubLang = SUBLANG_GERMAN_LIECHTENSTEIN; // German (Liechtenstein) + else + usSubLang = SUBLANG_DEFAULT; //default sub language + } + else if ( wsLanguage == L"el" ) + usPrimaryLang = LANG_GREEK; //Greek + else if ( wsLanguage == L"en" ) + { + usPrimaryLang = LANG_ENGLISH; //English + if ( wsCountry == L"US" ) + usSubLang = SUBLANG_ENGLISH_US; // English (US) + else if ( wsCountry == L"GB" ) + usSubLang = SUBLANG_ENGLISH_UK; // English (UK) + else if ( wsCountry == L"AU" ) + usSubLang = SUBLANG_ENGLISH_AUS; // English (Australian) + else if ( wsCountry == L"CA" ) + usSubLang = SUBLANG_ENGLISH_CAN; // English (Canadian) + else if ( wsCountry == L"NZ" ) + usSubLang = SUBLANG_ENGLISH_NZ; // English (New Zealand) + else if ( wsCountry == L"IE" ) + usSubLang = SUBLANG_ENGLISH_EIRE; // English (Ireland) + else if ( wsCountry == L"ZA" ) + usSubLang = SUBLANG_ENGLISH_SOUTH_AFRICA; // English (South Africa) + else if ( wsCountry == L"JM" ) + usSubLang = SUBLANG_ENGLISH_JAMAICA; // English (Jamaica) + else if ( wsCountry == L"GD" ) + usSubLang = SUBLANG_ENGLISH_CARIBBEAN; // English (Caribbean) Grenada + else if ( wsCountry == L"BZ" ) + usSubLang = SUBLANG_ENGLISH_BELIZE; // English (Belize) + else if ( wsCountry == L"TT" ) + usSubLang = SUBLANG_ENGLISH_TRINIDAD; // English (Trinidad) + else if ( wsCountry == L"ZW" ) + usSubLang = SUBLANG_ENGLISH_ZIMBABWE; // English (Zimbabwe) + else if ( wsCountry == L"PH" ) + usSubLang = SUBLANG_ENGLISH_PHILIPPINES; // English (Philippines) + else + usSubLang = SUBLANG_DEFAULT; //default sub language + } + else if ( wsLanguage == L"es" ) + { + usPrimaryLang = LANG_SPANISH; //Spanish + //else if ( wsCountry == L"ES" ) + // usSubLang = SUBLANG_SPANISH; // Spanish (Castilian) + if ( wsCountry == L"MX" ) + usSubLang = SUBLANG_SPANISH_MEXICAN; // Spanish (Mexican) + else if ( wsCountry == L"ES" ) + usSubLang = SUBLANG_SPANISH_MODERN; // Spanish (Spain) + else if ( wsCountry == L"GT" ) + usSubLang = SUBLANG_SPANISH_GUATEMALA; // Spanish (Guatemala) + else if ( wsCountry == L"CR" ) + usSubLang = SUBLANG_SPANISH_COSTA_RICA; // Spanish (Costa Rica) + else if ( wsCountry == L"PA" ) + usSubLang = SUBLANG_SPANISH_PANAMA; // Spanish (Panama) + else if ( wsCountry == L"DO" ) + usSubLang = SUBLANG_SPANISH_DOMINICAN_REPUBLIC; // Spanish (Dominican Republic) + else if ( wsCountry == L"VE" ) + usSubLang = SUBLANG_SPANISH_VENEZUELA; // Spanish (Venezuela) + else if ( wsCountry == L"CO" ) + usSubLang = SUBLANG_SPANISH_COLOMBIA; // Spanish (Colombia) + else if ( wsCountry == L"PE" ) + usSubLang = SUBLANG_SPANISH_PERU; // Spanish (Peru) + else if ( wsCountry == L"AR" ) + usSubLang = SUBLANG_SPANISH_ARGENTINA; // Spanish (Argentina) + else if ( wsCountry == L"EC" ) + usSubLang = SUBLANG_SPANISH_ECUADOR; // Spanish (Ecuador) + else if ( wsCountry == L"CL" ) + usSubLang = SUBLANG_SPANISH_CHILE; // Spanish (Chile) + else if ( wsCountry == L"UY" ) + usSubLang = SUBLANG_SPANISH_URUGUAY; // Spanish (Uruguay) + else if ( wsCountry == L"PY" ) + usSubLang = SUBLANG_SPANISH_PARAGUAY; // Spanish (Paraguay) + else if ( wsCountry == L"BO" ) + usSubLang = SUBLANG_SPANISH_BOLIVIA; // Spanish (Bolivia) + else if ( wsCountry == L"SV" ) + usSubLang = SUBLANG_SPANISH_EL_SALVADOR; // Spanish (El Salvador) + else if ( wsCountry == L"HN" ) + usSubLang = SUBLANG_SPANISH_HONDURAS; // Spanish (Honduras) + else if ( wsCountry == L"NI" ) + usSubLang = SUBLANG_SPANISH_NICARAGUA; // Spanish (Nicaragua) + else if ( wsCountry == L"PR" ) + usSubLang = SUBLANG_SPANISH_PUERTO_RICO; // Spanish (Puerto Rico) + else + usSubLang = SUBLANG_DEFAULT; //default sub language + } + else if ( wsLanguage == L"fi" ) + usPrimaryLang = LANG_FINNISH; //Finnish + else if ( wsLanguage == L"fr" ) + { + usPrimaryLang = LANG_FRENCH; //French + if ( wsCountry == L"FR" ) + usSubLang = SUBLANG_FRENCH; // French + else if ( wsCountry == L"BE" ) + usSubLang = SUBLANG_FRENCH_BELGIAN; // French (Belgian) + else if ( wsCountry == L"CA" ) + usSubLang = SUBLANG_FRENCH_CANADIAN; // French (Canadian) + else if ( wsCountry == L"CH" ) + usSubLang = SUBLANG_FRENCH_SWISS; // French (Swiss) + else if ( wsCountry == L"LU" ) + usSubLang = SUBLANG_FRENCH_LUXEMBOURG; // French (Luxembourg) + else if ( wsCountry == L"MC" ) + usSubLang = SUBLANG_FRENCH_MONACO; // French (Monaco) + else + usSubLang = SUBLANG_DEFAULT; //default sub language + } + else if ( wsLanguage == L"iw" ) + usPrimaryLang = LANG_HEBREW; //Hebrew + else if ( wsLanguage == L"hu" ) + usPrimaryLang = LANG_HUNGARIAN; //Hungarian + else if ( wsLanguage == L"is" ) + usPrimaryLang = LANG_ICELANDIC; //Icelandic + else if ( wsLanguage == L"it" ) + { + usPrimaryLang = LANG_ITALIAN; //Italian + if ( wsCountry == L"IT" ) + usSubLang = SUBLANG_ITALIAN; // Italian + else if ( wsCountry == L"CH" ) + usSubLang = SUBLANG_ITALIAN_SWISS; // Italian (Swiss) + else + usSubLang = SUBLANG_DEFAULT; //default sub language + } + else if ( wsLanguage == L"ja" ) + usPrimaryLang = LANG_JAPANESE; //Japanese + else if ( wsLanguage == L"ko" ) + { + usPrimaryLang = LANG_KOREAN; //Korean + if ( wsCountry == L"KR" ) + usSubLang = SUBLANG_KOREAN; // Korean + else + usSubLang = SUBLANG_DEFAULT; //default sub language + } + else if ( wsLanguage == L"nl" ) + { + usPrimaryLang = LANG_DUTCH; //Dutch + if ( wsCountry == L"NL" ) + usSubLang = SUBLANG_DUTCH; // Dutch + else if ( wsCountry == L"BE" ) + usSubLang = SUBLANG_DUTCH_BELGIAN; // Dutch (Belgian) + else + usSubLang = SUBLANG_DEFAULT; //default sub language + } + else if ( wsLanguage == L"no" ) + { + usPrimaryLang = LANG_NORWEGIAN; //Norwegian + if ( wsCountry == L"NO" ) + usSubLang = SUBLANG_NORWEGIAN_BOKMAL; // Norwegian (Bokmal) + //else if ( wsCountry == L"NO" ) + // usSubLang = SUBLANG_NORWEGIAN_NYNORSK; // Norwegian (Nynorsk) + else + usSubLang = SUBLANG_DEFAULT; //default sub language + } + else if ( wsLanguage == L"pl" ) + usPrimaryLang = LANG_POLISH; //Polish + else if ( wsLanguage == L"pt" ) + { + usPrimaryLang = LANG_PORTUGUESE; //Portuguese + if ( wsCountry == L"BR" ) + usSubLang = SUBLANG_PORTUGUESE_BRAZILIAN; // Portuguese (Brazil) + else if ( wsCountry == L"PT" ) + usSubLang = SUBLANG_PORTUGUESE; // Portuguese (Portugal) + else + usSubLang = SUBLANG_DEFAULT; //default sub language + } + else if ( wsLanguage == L"ro" ) + usPrimaryLang = LANG_ROMANIAN; //Romanian + else if ( wsLanguage == L"ru" ) + usPrimaryLang = LANG_RUSSIAN; //Russian + else if ( wsLanguage == L"hr" ) + usPrimaryLang = LANG_CROATIAN; //Croatian + else if ( wsLanguage == L"sr" ) + { + usPrimaryLang = LANG_SERBIAN; //Serbian + if ( wsCountry == L"VA" ) + usSubLang = SUBLANG_SERBIAN_LATIN; // Serbian (Latin) + else if ( wsCountry == L"HR" ) + usSubLang = SUBLANG_SERBIAN_CYRILLIC; // Serbian (Cyrillic) + else + usSubLang = SUBLANG_DEFAULT; //default sub language + } + else if ( wsLanguage == L"sk" ) + usPrimaryLang = LANG_SLOVAK; //Slovak + else if ( wsLanguage == L"sq" ) + usPrimaryLang = LANG_ALBANIAN; //Albanian + else if ( wsLanguage == L"sv" ) + { + usPrimaryLang = LANG_SWEDISH; //Swedish + if ( wsCountry == L"SE" ) + usSubLang = SUBLANG_SWEDISH; // Swedish + else if ( wsCountry == L"FI" ) + usSubLang = SUBLANG_SWEDISH_FINLAND; // Swedish (Finland) + else + usSubLang = SUBLANG_DEFAULT; //default sub language + } + else if ( wsLanguage == L"th" ) + usPrimaryLang = LANG_THAI; //Thai + else if ( wsLanguage == L"tr" ) + usPrimaryLang = LANG_TURKISH; //Turkish + else if ( wsLanguage == L"ur" ) + { + usPrimaryLang = LANG_URDU; //Urdu + if ( wsCountry == L"PK" ) + usSubLang = SUBLANG_URDU_PAKISTAN; // Urdu (Pakistan) + else if ( wsCountry == L"IN" ) + usSubLang = SUBLANG_URDU_INDIA; // Urdu (India) + else + usSubLang = SUBLANG_DEFAULT; //default sub language + } + else if ( wsLanguage == L"in" ) + usPrimaryLang = LANG_INDONESIAN; //Indonesian + else if ( wsLanguage == L"uk" ) + usPrimaryLang = LANG_UKRAINIAN; //Ukrainian + else if ( wsLanguage == L"be" ) + usPrimaryLang = LANG_BELARUSIAN; //Belarusian + else if ( wsLanguage == L"sl" ) + usPrimaryLang = LANG_SLOVENIAN; //Slovenian + else if ( wsLanguage == L"et" ) + usPrimaryLang = LANG_ESTONIAN; //Estonian + else if ( wsLanguage == L"lv" ) + usPrimaryLang = LANG_LATVIAN; //Latvian + else if ( wsLanguage == L"lt" ) + { + usPrimaryLang = LANG_LITHUANIAN; //Lithuanian + if ( wsCountry == L"LT" ) + usSubLang = SUBLANG_LITHUANIAN; // Lithuanian + else + usSubLang = SUBLANG_DEFAULT; //default sub language + } + else if ( wsLanguage == L"fa" ) + usPrimaryLang = LANG_FARSI; //Farsi + else if ( wsLanguage == L"vi" ) + usPrimaryLang = LANG_VIETNAMESE; //Vietnamese + else if ( wsLanguage == L"hy" ) + usPrimaryLang = LANG_ARMENIAN; //Armenian + else if ( wsLanguage == L"az" ) + { + usPrimaryLang = LANG_AZERI; //Azeri + //if ( wsCountry == L" " ) + // usSubLang = SUBLANG_AZERI_LATIN; // Azeri (Latin) + //else if ( wsCountry == L" " ) + // usSubLang = SUBLANG_AZERI_CYRILLIC; // Azeri (Cyrillic) + } + else if ( wsLanguage == L"eu" ) + usPrimaryLang = LANG_BASQUE; //Basque + else if ( wsLanguage == L"mk" ) + usPrimaryLang = LANG_MACEDONIAN; //FYRO Macedonian + else if ( wsLanguage == L"af" ) + usPrimaryLang = LANG_AFRIKAANS; //Afrikaans + else if ( wsLanguage == L"ka" ) + usPrimaryLang = LANG_GEORGIAN; //Georgian + else if ( wsLanguage == L"fo" ) + usPrimaryLang = LANG_FAEROESE; //Faeroese + else if ( wsLanguage == L"hi" ) + usPrimaryLang = LANG_HINDI; //Hindi + else if ( wsLanguage == L"ms" ) + { + usPrimaryLang = LANG_MALAY; //Malay + if ( wsCountry == L"MY" ) + usSubLang = SUBLANG_MALAY_MALAYSIA; // Malay (Malaysia) + else if ( wsCountry == L"BN" ) + usSubLang = SUBLANG_MALAY_BRUNEI_DARUSSALAM; // Malay (Brunei Darassalam) + else + usSubLang = SUBLANG_DEFAULT; //default sub language + } + else if ( wsLanguage == L"kk" ) + usPrimaryLang = LANG_KAZAK; //Kazak + else if ( wsLanguage == L"ky" ) + usPrimaryLang = LANG_KYRGYZ; //Kyrgyz + else if ( wsLanguage == L"sw" ) + usPrimaryLang = LANG_SWAHILI; //Swahili + else if ( wsLanguage == L"uz" ) + { + usPrimaryLang = LANG_UZBEK; //Uzbek + if ( wsCountry == L"UZ" ) + usSubLang = SUBLANG_UZBEK_LATIN; // Uzbek (Latin) + else if ( wsCountry == L"DE" ) + usSubLang = SUBLANG_UZBEK_CYRILLIC; // Uzbek (Cyrillic) + else + usSubLang = SUBLANG_DEFAULT; //default sub language + } + else if ( wsLanguage == L"tt" ) + usPrimaryLang = LANG_TATAR; //Tatar + else if ( wsLanguage == L"bn" ) + usPrimaryLang = LANG_BENGALI; //Not supported. + else if ( wsLanguage == L"pa" ) + usPrimaryLang = LANG_PUNJABI; //Punjabi + else if ( wsLanguage == L"gu" ) + usPrimaryLang = LANG_GUJARATI; //Gujarati + else if ( wsLanguage == L"or" ) + usPrimaryLang = LANG_ORIYA; //Not supported. + else if ( wsLanguage == L"ta" ) + usPrimaryLang = LANG_TAMIL; //Tamil + else if ( wsLanguage == L"te" ) + usPrimaryLang = LANG_TELUGU; //Telugu + else if ( wsLanguage == L"kn" ) + usPrimaryLang = LANG_KANNADA; //Kannada + else if ( wsLanguage == L"ml" ) + usPrimaryLang = LANG_MALAYALAM; //Not supported. + else if ( wsLanguage == L"as" ) + usPrimaryLang = LANG_ASSAMESE; //Not supported. + else if ( wsLanguage == L"mr" ) + usPrimaryLang = LANG_MARATHI; //Marathi + else if ( wsLanguage == L"sa" ) + usPrimaryLang = LANG_SANSKRIT; //Sanskrit + else if ( wsLanguage == L"mn" ) + usPrimaryLang = LANG_MONGOLIAN; //Mongolian + else if ( wsLanguage == L"gl" ) + usPrimaryLang = LANG_GALICIAN; //Galician + else if ( wsLanguage == L"sd" ) + usPrimaryLang = LANG_SINDHI; //Not supported. + else if ( wsLanguage == L"ks" ) + usPrimaryLang = LANG_KASHMIRI; //Not supported. + else if ( wsLanguage == L"ne" ) + usPrimaryLang = LANG_NEPALI; //Not supported. + //else if ( wsLanguage == L" " ) + // usPrimaryLang = LANG_MANIPURI; //Not supported. + //else if ( wsLanguage == L" " ) + // usPrimaryLang = LANG_KONKANI; //Konkani + //else if ( wsLanguage == L" " ) + // usPrimaryLang = LANG_SYRIAC; //Syriac + //else if ( wsLanguage == L" " ) + // usPrimaryLang = LANG_DIVEHI; //Divehi + else + return GetSystemDefaultLCID(); //System Default Locale + + return MAKELCID( MAKELANGID( usPrimaryLang, usSubLang ), SORT_DEFAULT ); +} |