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