1*b1cdbd2cSJim Jagielski /**************************************************************
2*b1cdbd2cSJim Jagielski  *
3*b1cdbd2cSJim Jagielski  * Licensed to the Apache Software Foundation (ASF) under one
4*b1cdbd2cSJim Jagielski  * or more contributor license agreements.  See the NOTICE file
5*b1cdbd2cSJim Jagielski  * distributed with this work for additional information
6*b1cdbd2cSJim Jagielski  * regarding copyright ownership.  The ASF licenses this file
7*b1cdbd2cSJim Jagielski  * to you under the Apache License, Version 2.0 (the
8*b1cdbd2cSJim Jagielski  * "License"); you may not use this file except in compliance
9*b1cdbd2cSJim Jagielski  * with the License.  You may obtain a copy of the License at
10*b1cdbd2cSJim Jagielski  *
11*b1cdbd2cSJim Jagielski  *   http://www.apache.org/licenses/LICENSE-2.0
12*b1cdbd2cSJim Jagielski  *
13*b1cdbd2cSJim Jagielski  * Unless required by applicable law or agreed to in writing,
14*b1cdbd2cSJim Jagielski  * software distributed under the License is distributed on an
15*b1cdbd2cSJim Jagielski  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b1cdbd2cSJim Jagielski  * KIND, either express or implied.  See the License for the
17*b1cdbd2cSJim Jagielski  * specific language governing permissions and limitations
18*b1cdbd2cSJim Jagielski  * under the License.
19*b1cdbd2cSJim Jagielski  *
20*b1cdbd2cSJim Jagielski  *************************************************************/
21*b1cdbd2cSJim Jagielski 
22*b1cdbd2cSJim Jagielski 
23*b1cdbd2cSJim Jagielski 
24*b1cdbd2cSJim Jagielski // MARKER(update_precomp.py): autogen include statement, do not remove
25*b1cdbd2cSJim Jagielski #include "precompiled_shell.hxx"
26*b1cdbd2cSJim Jagielski #include "internal/global.hxx"
27*b1cdbd2cSJim Jagielski #include "internal/infotips.hxx"
28*b1cdbd2cSJim Jagielski #include "internal/shlxthdl.hxx"
29*b1cdbd2cSJim Jagielski #include "internal/metainforeader.hxx"
30*b1cdbd2cSJim Jagielski #include "internal/contentreader.hxx"
31*b1cdbd2cSJim Jagielski #include "internal/utilities.hxx"
32*b1cdbd2cSJim Jagielski #include "internal/registry.hxx"
33*b1cdbd2cSJim Jagielski #include "internal/fileextensions.hxx"
34*b1cdbd2cSJim Jagielski #include "internal/iso8601_converter.hxx"
35*b1cdbd2cSJim Jagielski #include "internal/config.hxx"
36*b1cdbd2cSJim Jagielski 
37*b1cdbd2cSJim Jagielski #include "internal/resource.h"
38*b1cdbd2cSJim Jagielski #include <stdio.h>
39*b1cdbd2cSJim Jagielski #include <utility>
40*b1cdbd2cSJim Jagielski #include <stdlib.h>
41*b1cdbd2cSJim Jagielski 
42*b1cdbd2cSJim Jagielski 
43*b1cdbd2cSJim Jagielski #define MAX_STRING 80
44*b1cdbd2cSJim Jagielski #define KB 1024.0
45*b1cdbd2cSJim Jagielski const std::wstring WSPACE = std::wstring(SPACE);
46*b1cdbd2cSJim Jagielski 
47*b1cdbd2cSJim Jagielski //-----------------------------
48*b1cdbd2cSJim Jagielski //
49*b1cdbd2cSJim Jagielski //-----------------------------
50*b1cdbd2cSJim Jagielski 
CInfoTip(long RefCnt)51*b1cdbd2cSJim Jagielski CInfoTip::CInfoTip(long RefCnt) :
52*b1cdbd2cSJim Jagielski     m_RefCnt(RefCnt)
53*b1cdbd2cSJim Jagielski {
54*b1cdbd2cSJim Jagielski     ZeroMemory(m_szFileName, sizeof(m_szFileName));
55*b1cdbd2cSJim Jagielski     InterlockedIncrement(&g_DllRefCnt);
56*b1cdbd2cSJim Jagielski }
57*b1cdbd2cSJim Jagielski 
58*b1cdbd2cSJim Jagielski //-----------------------------
59*b1cdbd2cSJim Jagielski //
60*b1cdbd2cSJim Jagielski //-----------------------------
61*b1cdbd2cSJim Jagielski 
~CInfoTip()62*b1cdbd2cSJim Jagielski CInfoTip::~CInfoTip()
63*b1cdbd2cSJim Jagielski {
64*b1cdbd2cSJim Jagielski     InterlockedDecrement(&g_DllRefCnt);
65*b1cdbd2cSJim Jagielski }
66*b1cdbd2cSJim Jagielski 
67*b1cdbd2cSJim Jagielski //-----------------------------
68*b1cdbd2cSJim Jagielski // IUnknown methods
69*b1cdbd2cSJim Jagielski //-----------------------------
70*b1cdbd2cSJim Jagielski 
QueryInterface(REFIID riid,void __RPC_FAR * __RPC_FAR * ppvObject)71*b1cdbd2cSJim Jagielski HRESULT STDMETHODCALLTYPE CInfoTip::QueryInterface(REFIID riid, void __RPC_FAR *__RPC_FAR *ppvObject)
72*b1cdbd2cSJim Jagielski {
73*b1cdbd2cSJim Jagielski     *ppvObject = 0;
74*b1cdbd2cSJim Jagielski 
75*b1cdbd2cSJim Jagielski     IUnknown* pUnk = 0;
76*b1cdbd2cSJim Jagielski 
77*b1cdbd2cSJim Jagielski     if (IID_IUnknown == riid || IID_IQueryInfo == riid)
78*b1cdbd2cSJim Jagielski     {
79*b1cdbd2cSJim Jagielski         pUnk = static_cast<IQueryInfo*>(this);
80*b1cdbd2cSJim Jagielski         pUnk->AddRef();
81*b1cdbd2cSJim Jagielski         *ppvObject = pUnk;
82*b1cdbd2cSJim Jagielski         return S_OK;
83*b1cdbd2cSJim Jagielski     }
84*b1cdbd2cSJim Jagielski     else if (IID_IPersistFile == riid)
85*b1cdbd2cSJim Jagielski     {
86*b1cdbd2cSJim Jagielski         pUnk = static_cast<IPersistFile*>(this);
87*b1cdbd2cSJim Jagielski         pUnk->AddRef();
88*b1cdbd2cSJim Jagielski         *ppvObject = pUnk;
89*b1cdbd2cSJim Jagielski         return S_OK;
90*b1cdbd2cSJim Jagielski     }
91*b1cdbd2cSJim Jagielski 
92*b1cdbd2cSJim Jagielski     return E_NOINTERFACE;
93*b1cdbd2cSJim Jagielski }
94*b1cdbd2cSJim Jagielski 
95*b1cdbd2cSJim Jagielski //----------------------------
96*b1cdbd2cSJim Jagielski //
97*b1cdbd2cSJim Jagielski //----------------------------
98*b1cdbd2cSJim Jagielski 
AddRef(void)99*b1cdbd2cSJim Jagielski ULONG STDMETHODCALLTYPE CInfoTip::AddRef(void)
100*b1cdbd2cSJim Jagielski {
101*b1cdbd2cSJim Jagielski     return InterlockedIncrement(&m_RefCnt);
102*b1cdbd2cSJim Jagielski }
103*b1cdbd2cSJim Jagielski 
104*b1cdbd2cSJim Jagielski //----------------------------
105*b1cdbd2cSJim Jagielski //
106*b1cdbd2cSJim Jagielski //----------------------------
107*b1cdbd2cSJim Jagielski 
Release(void)108*b1cdbd2cSJim Jagielski ULONG STDMETHODCALLTYPE CInfoTip::Release( void)
109*b1cdbd2cSJim Jagielski {
110*b1cdbd2cSJim Jagielski     long refcnt = InterlockedDecrement(&m_RefCnt);
111*b1cdbd2cSJim Jagielski 
112*b1cdbd2cSJim Jagielski     if (0 == m_RefCnt)
113*b1cdbd2cSJim Jagielski         delete this;
114*b1cdbd2cSJim Jagielski 
115*b1cdbd2cSJim Jagielski     return refcnt;
116*b1cdbd2cSJim Jagielski }
117*b1cdbd2cSJim Jagielski 
118*b1cdbd2cSJim Jagielski //********************helper functions for GetInfoTip functions**********************
119*b1cdbd2cSJim Jagielski 
120*b1cdbd2cSJim Jagielski /** get file type information from registry.
121*b1cdbd2cSJim Jagielski */
getFileTypeInfo(const std::string & file_extension)122*b1cdbd2cSJim Jagielski std::wstring getFileTypeInfo(const std::string& file_extension)
123*b1cdbd2cSJim Jagielski {
124*b1cdbd2cSJim Jagielski     char extKeyValue[MAX_STRING];
125*b1cdbd2cSJim Jagielski     char typeKeyValue[MAX_STRING];
126*b1cdbd2cSJim Jagielski     ::std::string sDot(".");
127*b1cdbd2cSJim Jagielski     if (QueryRegistryKey(HKEY_CLASSES_ROOT, (sDot.append(file_extension)).c_str(), "", extKeyValue, MAX_STRING))
128*b1cdbd2cSJim Jagielski 		if (QueryRegistryKey( HKEY_CLASSES_ROOT, extKeyValue, "",typeKeyValue, MAX_STRING))
129*b1cdbd2cSJim Jagielski             return StringToWString(typeKeyValue);
130*b1cdbd2cSJim Jagielski 
131*b1cdbd2cSJim Jagielski     return EMPTY_STRING;
132*b1cdbd2cSJim Jagielski }
133*b1cdbd2cSJim Jagielski 
134*b1cdbd2cSJim Jagielski /** get file size.
135*b1cdbd2cSJim Jagielski */
getSizeOfFile(char * FileName)136*b1cdbd2cSJim Jagielski DWORD getSizeOfFile( char* FileName )
137*b1cdbd2cSJim Jagielski {
138*b1cdbd2cSJim Jagielski     HANDLE hFile = CreateFile(StringToWString(FileName).c_str(),            // open file
139*b1cdbd2cSJim Jagielski                         GENERIC_READ,                                       // open for reading
140*b1cdbd2cSJim Jagielski                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, // share for all operations
141*b1cdbd2cSJim Jagielski                         NULL,                                               // no security
142*b1cdbd2cSJim Jagielski                         OPEN_EXISTING,                                      // existing file only
143*b1cdbd2cSJim Jagielski                         FILE_ATTRIBUTE_NORMAL,                              // normal file
144*b1cdbd2cSJim Jagielski                         NULL);                                              // no attr. template
145*b1cdbd2cSJim Jagielski 
146*b1cdbd2cSJim Jagielski     if (hFile != INVALID_HANDLE_VALUE)
147*b1cdbd2cSJim Jagielski     {
148*b1cdbd2cSJim Jagielski         DWORD dwSize = GetFileSize( HANDLE(hFile), NULL );
149*b1cdbd2cSJim Jagielski         CloseHandle( HANDLE(hFile) );
150*b1cdbd2cSJim Jagielski         return dwSize;
151*b1cdbd2cSJim Jagielski     }
152*b1cdbd2cSJim Jagielski 
153*b1cdbd2cSJim Jagielski     return INVALID_FILE_SIZE;
154*b1cdbd2cSJim Jagielski }
155*b1cdbd2cSJim Jagielski 
156*b1cdbd2cSJim Jagielski /** format file size in to be more readable.
157*b1cdbd2cSJim Jagielski */
formatSizeOfFile(DWORD dwSize)158*b1cdbd2cSJim Jagielski std::wstring formatSizeOfFile( DWORD dwSize )
159*b1cdbd2cSJim Jagielski {
160*b1cdbd2cSJim Jagielski 	if ( dwSize < 1000 )
161*b1cdbd2cSJim Jagielski 	{
162*b1cdbd2cSJim Jagielski 		char buffer[3];
163*b1cdbd2cSJim Jagielski 		int dFileSize = dwSize;
164*b1cdbd2cSJim Jagielski 
165*b1cdbd2cSJim Jagielski 		_itoa( dFileSize, buffer, 10 );
166*b1cdbd2cSJim Jagielski 		return StringToWString( buffer ).append(StringToWString(" B"));
167*b1cdbd2cSJim Jagielski 	}
168*b1cdbd2cSJim Jagielski 
169*b1cdbd2cSJim Jagielski     char *buffer=NULL;
170*b1cdbd2cSJim Jagielski     int  decimal, sign;
171*b1cdbd2cSJim Jagielski     double dFileSize = (double)dwSize/(double)KB;
172*b1cdbd2cSJim Jagielski 
173*b1cdbd2cSJim Jagielski 	buffer = _fcvt( dFileSize, 1, &decimal, &sign );
174*b1cdbd2cSJim Jagielski 
175*b1cdbd2cSJim Jagielski     ::std::wstring wsTemp = StringToWString( buffer );
176*b1cdbd2cSJim Jagielski     int  pos=decimal % 3;
177*b1cdbd2cSJim Jagielski     ::std::wstring wsBuffer = wsTemp.substr( 0,pos);
178*b1cdbd2cSJim Jagielski 
179*b1cdbd2cSJim Jagielski     if ( decimal )
180*b1cdbd2cSJim Jagielski         for (;decimal - pos > 2;pos += 3)
181*b1cdbd2cSJim Jagielski         {
182*b1cdbd2cSJim Jagielski             if (pos)
183*b1cdbd2cSJim Jagielski                 wsBuffer.append(StringToWString(","));
184*b1cdbd2cSJim Jagielski             wsBuffer.append( wsTemp.substr( pos, 3) );
185*b1cdbd2cSJim Jagielski         }
186*b1cdbd2cSJim Jagielski     else
187*b1cdbd2cSJim Jagielski         wsBuffer.append(StringToWString("0"));
188*b1cdbd2cSJim Jagielski 
189*b1cdbd2cSJim Jagielski     wsBuffer.append(StringToWString("."));
190*b1cdbd2cSJim Jagielski     wsBuffer.append(wsTemp.substr( decimal, wsTemp.size()-decimal ));
191*b1cdbd2cSJim Jagielski     wsBuffer.append(StringToWString(" KB"));
192*b1cdbd2cSJim Jagielski 
193*b1cdbd2cSJim Jagielski     return wsBuffer;
194*b1cdbd2cSJim Jagielski }
195*b1cdbd2cSJim Jagielski 
196*b1cdbd2cSJim Jagielski 
197*b1cdbd2cSJim Jagielski /** get file size information.
198*b1cdbd2cSJim Jagielski */
getFileSizeInfo(char * FileName)199*b1cdbd2cSJim Jagielski std::wstring getFileSizeInfo(char* FileName)
200*b1cdbd2cSJim Jagielski {
201*b1cdbd2cSJim Jagielski     DWORD dwSize=getSizeOfFile(FileName);
202*b1cdbd2cSJim Jagielski     if (dwSize != INVALID_FILE_SIZE)
203*b1cdbd2cSJim Jagielski         return formatSizeOfFile( dwSize );
204*b1cdbd2cSJim Jagielski 
205*b1cdbd2cSJim Jagielski     return EMPTY_STRING;
206*b1cdbd2cSJim Jagielski }
207*b1cdbd2cSJim Jagielski 
208*b1cdbd2cSJim Jagielski //----------------------------
209*b1cdbd2cSJim Jagielski // IQueryInfo methods
210*b1cdbd2cSJim Jagielski //----------------------------
211*b1cdbd2cSJim Jagielski 
GetInfoTip(DWORD,wchar_t ** ppwszTip)212*b1cdbd2cSJim Jagielski HRESULT STDMETHODCALLTYPE CInfoTip::GetInfoTip(DWORD /*dwFlags*/, wchar_t** ppwszTip)
213*b1cdbd2cSJim Jagielski {
214*b1cdbd2cSJim Jagielski     std::wstring msg;
215*b1cdbd2cSJim Jagielski     const std::wstring CONST_SPACE(SPACE);
216*b1cdbd2cSJim Jagielski 
217*b1cdbd2cSJim Jagielski     //display File Type, no matter other info is loaded successfully or not.
218*b1cdbd2cSJim Jagielski     std::wstring tmpTypeStr = getFileTypeInfo( get_file_name_extension(m_szFileName) );
219*b1cdbd2cSJim Jagielski     if ( tmpTypeStr != EMPTY_STRING )
220*b1cdbd2cSJim Jagielski     {
221*b1cdbd2cSJim Jagielski         msg += GetResString(IDS_TYPE_COLON) + CONST_SPACE;
222*b1cdbd2cSJim Jagielski         msg += tmpTypeStr;
223*b1cdbd2cSJim Jagielski     }
224*b1cdbd2cSJim Jagielski 
225*b1cdbd2cSJim Jagielski     try
226*b1cdbd2cSJim Jagielski     {
227*b1cdbd2cSJim Jagielski         CMetaInfoReader meta_info_accessor(m_szFileName);
228*b1cdbd2cSJim Jagielski 
229*b1cdbd2cSJim Jagielski 		//display document title;
230*b1cdbd2cSJim Jagielski         if ( meta_info_accessor.getTagData( META_INFO_TITLE ).length() > 0)
231*b1cdbd2cSJim Jagielski         {
232*b1cdbd2cSJim Jagielski 			if ( msg != EMPTY_STRING )
233*b1cdbd2cSJim Jagielski 				msg += L"\n";
234*b1cdbd2cSJim Jagielski             msg += GetResString(IDS_TITLE_COLON) + CONST_SPACE;
235*b1cdbd2cSJim Jagielski             msg += meta_info_accessor.getTagData( META_INFO_TITLE );
236*b1cdbd2cSJim Jagielski         }
237*b1cdbd2cSJim Jagielski         else
238*b1cdbd2cSJim Jagielski         {
239*b1cdbd2cSJim Jagielski 			if ( msg != EMPTY_STRING )
240*b1cdbd2cSJim Jagielski 				msg += L"\n";
241*b1cdbd2cSJim Jagielski             msg += GetResString(IDS_TITLE_COLON) + CONST_SPACE;
242*b1cdbd2cSJim Jagielski             msg += m_FileNameOnly;
243*b1cdbd2cSJim Jagielski         }
244*b1cdbd2cSJim Jagielski 
245*b1cdbd2cSJim Jagielski         //display document author;
246*b1cdbd2cSJim Jagielski         if ( meta_info_accessor.getTagData( META_INFO_AUTHOR ).length() > 0)
247*b1cdbd2cSJim Jagielski         {
248*b1cdbd2cSJim Jagielski 			if ( msg != EMPTY_STRING )
249*b1cdbd2cSJim Jagielski 				msg += L"\n";
250*b1cdbd2cSJim Jagielski             msg += GetResString( IDS_AUTHOR_COLON ) + CONST_SPACE;
251*b1cdbd2cSJim Jagielski             msg += meta_info_accessor.getTagData( META_INFO_AUTHOR );
252*b1cdbd2cSJim Jagielski         }
253*b1cdbd2cSJim Jagielski 
254*b1cdbd2cSJim Jagielski         //display document subject;
255*b1cdbd2cSJim Jagielski         if ( meta_info_accessor.getTagData( META_INFO_SUBJECT ).length() > 0)
256*b1cdbd2cSJim Jagielski         {
257*b1cdbd2cSJim Jagielski 			if ( msg != EMPTY_STRING )
258*b1cdbd2cSJim Jagielski 				msg += L"\n";
259*b1cdbd2cSJim Jagielski             msg += GetResString(IDS_SUBJECT_COLON) + CONST_SPACE;
260*b1cdbd2cSJim Jagielski             msg += meta_info_accessor.getTagData( META_INFO_SUBJECT );
261*b1cdbd2cSJim Jagielski         }
262*b1cdbd2cSJim Jagielski 
263*b1cdbd2cSJim Jagielski         //display document description;
264*b1cdbd2cSJim Jagielski         if ( meta_info_accessor.getTagData( META_INFO_DESCRIPTION ).length() > 0)
265*b1cdbd2cSJim Jagielski         {
266*b1cdbd2cSJim Jagielski 			if ( msg != EMPTY_STRING )
267*b1cdbd2cSJim Jagielski 				msg += L"\n";
268*b1cdbd2cSJim Jagielski             msg += GetResString( IDS_COMMENTS_COLON ) + CONST_SPACE;
269*b1cdbd2cSJim Jagielski             msg += meta_info_accessor.getTagData( META_INFO_DESCRIPTION );
270*b1cdbd2cSJim Jagielski         }
271*b1cdbd2cSJim Jagielski 
272*b1cdbd2cSJim Jagielski         //display modified time formatted into locale representation.
273*b1cdbd2cSJim Jagielski         if ( iso8601_date_to_local_date(meta_info_accessor.getTagData(META_INFO_MODIFIED )).length() > 0)
274*b1cdbd2cSJim Jagielski         {
275*b1cdbd2cSJim Jagielski 			if ( msg != EMPTY_STRING )
276*b1cdbd2cSJim Jagielski 				msg += L"\n";
277*b1cdbd2cSJim Jagielski 			msg += GetResString( IDS_MODIFIED_COLON ) + CONST_SPACE;
278*b1cdbd2cSJim Jagielski 			msg += iso8601_date_to_local_date(meta_info_accessor.getTagData(META_INFO_MODIFIED ));
279*b1cdbd2cSJim Jagielski 		}
280*b1cdbd2cSJim Jagielski     }
281*b1cdbd2cSJim Jagielski 
282*b1cdbd2cSJim Jagielski     catch (const std::exception&)
283*b1cdbd2cSJim Jagielski     {
284*b1cdbd2cSJim Jagielski         //return E_FAIL;
285*b1cdbd2cSJim Jagielski     }
286*b1cdbd2cSJim Jagielski 
287*b1cdbd2cSJim Jagielski     //display file size, no matter other information is loaded successfully or not.
288*b1cdbd2cSJim Jagielski     std::wstring tmpSizeStr = getFileSizeInfo( m_szFileName );
289*b1cdbd2cSJim Jagielski     if ( tmpSizeStr != EMPTY_STRING )
290*b1cdbd2cSJim Jagielski     {
291*b1cdbd2cSJim Jagielski         msg += L"\n";
292*b1cdbd2cSJim Jagielski         msg += GetResString( IDS_SIZE_COLON ) + CONST_SPACE;
293*b1cdbd2cSJim Jagielski         msg += tmpSizeStr;
294*b1cdbd2cSJim Jagielski     }
295*b1cdbd2cSJim Jagielski 
296*b1cdbd2cSJim Jagielski 
297*b1cdbd2cSJim Jagielski     //finalize and assign the string.
298*b1cdbd2cSJim Jagielski     LPMALLOC lpMalloc;
299*b1cdbd2cSJim Jagielski     HRESULT hr = SHGetMalloc(&lpMalloc);
300*b1cdbd2cSJim Jagielski 
301*b1cdbd2cSJim Jagielski     if (SUCCEEDED(hr))
302*b1cdbd2cSJim Jagielski     {
303*b1cdbd2cSJim Jagielski         size_t len = sizeof(wchar_t) * msg.length() + sizeof(wchar_t);
304*b1cdbd2cSJim Jagielski         wchar_t* pMem = reinterpret_cast<wchar_t*>(lpMalloc->Alloc(len));
305*b1cdbd2cSJim Jagielski 
306*b1cdbd2cSJim Jagielski         ZeroMemory(pMem, len);
307*b1cdbd2cSJim Jagielski 
308*b1cdbd2cSJim Jagielski         msg.copy(pMem,msg.length());
309*b1cdbd2cSJim Jagielski 
310*b1cdbd2cSJim Jagielski         *ppwszTip = pMem;
311*b1cdbd2cSJim Jagielski         lpMalloc->Release();
312*b1cdbd2cSJim Jagielski 
313*b1cdbd2cSJim Jagielski         return S_OK;
314*b1cdbd2cSJim Jagielski     }
315*b1cdbd2cSJim Jagielski 
316*b1cdbd2cSJim Jagielski     return E_FAIL;
317*b1cdbd2cSJim Jagielski }
318*b1cdbd2cSJim Jagielski 
319*b1cdbd2cSJim Jagielski //----------------------------
320*b1cdbd2cSJim Jagielski //
321*b1cdbd2cSJim Jagielski //----------------------------
322*b1cdbd2cSJim Jagielski 
GetInfoFlags(DWORD *)323*b1cdbd2cSJim Jagielski HRESULT STDMETHODCALLTYPE CInfoTip::GetInfoFlags(DWORD * /*pdwFlags*/ )
324*b1cdbd2cSJim Jagielski {
325*b1cdbd2cSJim Jagielski     return E_NOTIMPL;
326*b1cdbd2cSJim Jagielski }
327*b1cdbd2cSJim Jagielski 
328*b1cdbd2cSJim Jagielski //----------------------------
329*b1cdbd2cSJim Jagielski // IPersist methods
330*b1cdbd2cSJim Jagielski //----------------------------
331*b1cdbd2cSJim Jagielski 
GetClassID(CLSID * pClassID)332*b1cdbd2cSJim Jagielski HRESULT STDMETHODCALLTYPE CInfoTip::GetClassID(CLSID* pClassID)
333*b1cdbd2cSJim Jagielski {
334*b1cdbd2cSJim Jagielski     pClassID = const_cast<CLSID*>(&CLSID_INFOTIP_HANDLER);
335*b1cdbd2cSJim Jagielski     return S_OK;
336*b1cdbd2cSJim Jagielski }
337*b1cdbd2cSJim Jagielski 
338*b1cdbd2cSJim Jagielski //----------------------------
339*b1cdbd2cSJim Jagielski // IPersistFile methods
340*b1cdbd2cSJim Jagielski //----------------------------
341*b1cdbd2cSJim Jagielski 
Load(LPCOLESTR pszFileName,DWORD)342*b1cdbd2cSJim Jagielski HRESULT STDMETHODCALLTYPE CInfoTip::Load(LPCOLESTR pszFileName, DWORD /*dwMode*/)
343*b1cdbd2cSJim Jagielski {
344*b1cdbd2cSJim Jagielski     std::wstring fname = pszFileName;
345*b1cdbd2cSJim Jagielski 
346*b1cdbd2cSJim Jagielski     // there must be a '\' and there must even be an
347*b1cdbd2cSJim Jagielski     // extension, else we would not have been called
348*b1cdbd2cSJim Jagielski     std::wstring::iterator begin = fname.begin() + fname.find_last_of(L"\\") + 1;
349*b1cdbd2cSJim Jagielski     std::wstring::iterator end   = fname.end();
350*b1cdbd2cSJim Jagielski 
351*b1cdbd2cSJim Jagielski     m_FileNameOnly = std::wstring(begin, end);
352*b1cdbd2cSJim Jagielski 
353*b1cdbd2cSJim Jagielski     fname = getShortPathName( fname );
354*b1cdbd2cSJim Jagielski 
355*b1cdbd2cSJim Jagielski     std::string fnameA = WStringToString(fname);
356*b1cdbd2cSJim Jagielski 
357*b1cdbd2cSJim Jagielski     // #115531#
358*b1cdbd2cSJim Jagielski     // ZeroMemory because strncpy doesn't '\0'-terminate the destination
359*b1cdbd2cSJim Jagielski     // string; reserve the last place in the buffer for the final '\0'
360*b1cdbd2cSJim Jagielski     // that's why '(sizeof(m_szFileName) - 1)'
361*b1cdbd2cSJim Jagielski     ZeroMemory(m_szFileName, sizeof(m_szFileName));
362*b1cdbd2cSJim Jagielski     strncpy(m_szFileName, fnameA.c_str(), (sizeof(m_szFileName) - 1));
363*b1cdbd2cSJim Jagielski 
364*b1cdbd2cSJim Jagielski     return S_OK;
365*b1cdbd2cSJim Jagielski }
366*b1cdbd2cSJim Jagielski 
367*b1cdbd2cSJim Jagielski //----------------------------
368*b1cdbd2cSJim Jagielski //
369*b1cdbd2cSJim Jagielski //----------------------------
370*b1cdbd2cSJim Jagielski 
IsDirty(void)371*b1cdbd2cSJim Jagielski HRESULT STDMETHODCALLTYPE CInfoTip::IsDirty(void)
372*b1cdbd2cSJim Jagielski {
373*b1cdbd2cSJim Jagielski     return E_NOTIMPL;
374*b1cdbd2cSJim Jagielski }
375*b1cdbd2cSJim Jagielski 
376*b1cdbd2cSJim Jagielski //----------------------------
377*b1cdbd2cSJim Jagielski //
378*b1cdbd2cSJim Jagielski //----------------------------
379*b1cdbd2cSJim Jagielski 
Save(LPCOLESTR,BOOL)380*b1cdbd2cSJim Jagielski HRESULT STDMETHODCALLTYPE CInfoTip::Save(LPCOLESTR /*pszFileName*/, BOOL /*fRemember*/)
381*b1cdbd2cSJim Jagielski {
382*b1cdbd2cSJim Jagielski     return E_NOTIMPL;
383*b1cdbd2cSJim Jagielski }
384*b1cdbd2cSJim Jagielski 
385*b1cdbd2cSJim Jagielski //----------------------------
386*b1cdbd2cSJim Jagielski //
387*b1cdbd2cSJim Jagielski //----------------------------
388*b1cdbd2cSJim Jagielski 
SaveCompleted(LPCOLESTR)389*b1cdbd2cSJim Jagielski HRESULT STDMETHODCALLTYPE CInfoTip::SaveCompleted(LPCOLESTR /*pszFileName*/)
390*b1cdbd2cSJim Jagielski {
391*b1cdbd2cSJim Jagielski     return E_NOTIMPL;
392*b1cdbd2cSJim Jagielski }
393*b1cdbd2cSJim Jagielski 
394*b1cdbd2cSJim Jagielski //----------------------------
395*b1cdbd2cSJim Jagielski //
396*b1cdbd2cSJim Jagielski //----------------------------
397*b1cdbd2cSJim Jagielski 
GetCurFile(LPOLESTR __RPC_FAR *)398*b1cdbd2cSJim Jagielski HRESULT STDMETHODCALLTYPE CInfoTip::GetCurFile(LPOLESTR __RPC_FAR * /*ppszFileName*/)
399*b1cdbd2cSJim Jagielski {
400*b1cdbd2cSJim Jagielski     return E_NOTIMPL;
401*b1cdbd2cSJim Jagielski }
402*b1cdbd2cSJim Jagielski 
403