From b718f390bf3dcc85dc97b2ef7483d93bbe3968ec Mon Sep 17 00:00:00 2001 From: Jens-Heiner Rechtien Date: Wed, 7 Apr 2004 10:13:37 +0000 Subject: [PATCH] INTEGRATION: CWS desktintgr01 (1.1.2); FILE ADDED 2004/04/06 03:15:11 deuce 1.1.2.5: Issue number: #97686 resolve bug on infotips open violation problem. Submitted by: Gorden Lin gorden.lin@sun.com Reviewed by: Tino Rachui tino.rachui@sun.com 2004/03/14 20:16:38 tra 1.1.2.4: #97686#merge changes 2004/03/12 12:28:20 tra 1.1.2.3: #115531#using strncpy instead of strcpy because it more secure 2004/03/12 12:22:08 tra 1.1.2.2: #97686#smaller adaptions and code polishing 2004/02/26 13:35:48 deuce 1.1.2.1: Issue number: 97686, 115531, 108219 restructure shxthdl module Submitted by: Gorden Lin/gorden.lin@sun.com Reviewed by: Tino Rachui/tino.rachui@sun.com --- .../win32/shlxthandler/infotips/infotips.cxx | 491 ++++++++++++++++++ 1 file changed, 491 insertions(+) create mode 100644 shell/source/win32/shlxthandler/infotips/infotips.cxx diff --git a/shell/source/win32/shlxthandler/infotips/infotips.cxx b/shell/source/win32/shlxthandler/infotips/infotips.cxx new file mode 100644 index 000000000000..22a7fb74557b --- /dev/null +++ b/shell/source/win32/shlxthandler/infotips/infotips.cxx @@ -0,0 +1,491 @@ +/************************************************************************* + * + * $RCSfile: infotips.cxx,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: hr $ $Date: 2004-04-07 11:13:37 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef GLOBAL_HXX_INCLUDED +#include "internal/global.hxx" +#endif + +#ifndef INFOTIPS_HXX_INCLUDED +#include "internal/infotips.hxx" +#endif + +#ifndef SHLXTHDL_HXX_INCLUDED +#include "internal/shlxthdl.hxx" +#endif + +#ifndef METAINFO_HXX_INCLUDED +#include "internal/metainfo.hxx" +#endif + +#ifndef UTILITIES_HXX_INCLUDED +#include "internal/utilities.hxx" +#endif + +#ifndef REGISTRY_HXX_INCLUDED +#include "internal/registry.hxx" +#endif + +#ifndef FILEEXTENSIONS_HXX_INCLUDED +#include "internal/fileextensions.hxx" +#endif + +#ifndef CONFIG_HXX_INCLUDED +#include "internal/config.hxx" +#endif + +#include "internal/resource.h" +#include +#include +#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(this); + pUnk->AddRef(); + *ppvObject = pUnk; + return S_OK; + } + else if (IID_IPersistFile == riid) + { + pUnk = static_cast(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 ) +{ + char *buffer; + 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 + { + COpenOfficeMetaInformation meta_info_accessor(m_szFileName); + + //display document title; + if ( meta_info_accessor.getTagData( META_INFO_TITLE ).length() > 0) + { + msg += L"\n"; + msg += GetResString(IDS_TITLE_COLON) + CONST_SPACE; + msg += meta_info_accessor.getTagData( META_INFO_TITLE ); + } + else + { + 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) + { + 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) + { + 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) + { + 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. + ::std::wstring wsDateTime = meta_info_accessor.getTagData( META_INFO_MODIFIED ); + if ( wsDateTime.length() == 19 ) + { + msg += L"\n"; + msg += GetResString( IDS_MODIFIED_COLON ) + CONST_SPACE; + + //fill in the SYSTEMTIME structure; + std::string asDateTime = WStringToString( wsDateTime ); + 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_STRING ]; + int DateSize = GetDateFormatW( + LOCALE_SYSTEM_DEFAULT, + 0, + &DateTime, + NULL, + DateBuffer, + MAX_STRING ); + + if ( DateSize ) + wsDateTime.assign(DateBuffer); + else + wsDateTime = StringToWString( asDateTime ); + + //get Time info from structure + WCHAR TimeBuffer[ MAX_STRING ]; + + int TimeSize = GetTimeFormatW( + LOCALE_SYSTEM_DEFAULT, + 0, + &DateTime, + NULL, + TimeBuffer, + MAX_STRING ); + + if ( TimeSize ) + { + wsDateTime.append(SPACE); + wsDateTime.append(TimeBuffer); + } + else + wsDateTime = StringToWString( asDateTime ); + + msg += wsDateTime; + } + else if ( wsDateTime.length() > 0) + { + msg += L"\n"; + msg += GetResString( IDS_MODIFIED_COLON ) + CONST_SPACE; + msg += wsDateTime; + } + + } + 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(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_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); + + 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; +}