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