~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/dlls/shdocvw/intshcut.c

Version: ~ [ wine-1.1.33 ] ~ [ wine-1.1.32 ] ~ [ wine-1.1.31 ] ~ [ wine-1.1.30 ] ~ [ wine-1.1.29 ] ~ [ wine-1.1.28 ] ~ [ wine-1.1.27 ] ~ [ wine-1.1.26 ] ~ [ wine-1.1.25 ] ~ [ wine-1.1.24 ] ~ [ wine-1.1.23 ] ~ [ wine-1.1.22 ] ~ [ wine-1.1.21 ] ~ [ wine-1.1.20 ] ~ [ wine-1.1.19 ] ~ [ wine-1.1.18 ] ~ [ wine-1.1.17 ] ~ [ wine-1.1.16 ] ~ [ wine-1.1.15 ] ~ [ wine-1.1.14 ] ~ [ wine-1.1.13 ] ~ [ wine-1.1.12 ] ~ [ wine-1.1.11 ] ~ [ wine-1.1.10 ] ~ [ wine-1.1.9 ] ~ [ wine-1.1.8 ] ~ [ wine-1.1.7 ] ~ [ wine-1.0.1 ] ~ [ wine-1.1.6 ] ~ [ wine-1.1.5 ] ~ [ wine-1.1.4 ] ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~

  1 /*
  2  * Copyright 2008 Damjan Jovanovic
  3  *
  4  * ShellLink's barely documented cousin that handles URLs.
  5  *
  6  * This library is free software; you can redistribute it and/or
  7  * modify it under the terms of the GNU Lesser General Public
  8  * License as published by the Free Software Foundation; either
  9  * version 2.1 of the License, or (at your option) any later version.
 10  *
 11  * This library is distributed in the hope that it will be useful,
 12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 14  * Lesser General Public License for more details.
 15  *
 16  * You should have received a copy of the GNU Lesser General Public
 17  * License along with this library; if not, write to the Free Software
 18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 19  */
 20 
 21 /*
 22  * TODO:
 23  * fd.o desktop and menu integration
 24  * Implement the IShellLinkA/W interfaces
 25  * Handle the SetURL flags
 26  * Loading .url files
 27  * Implement any other interfaces? Does any software actually use them?
 28  *
 29  * The installer for the Zuma Deluxe Popcap game is good for testing.
 30  */
 31 
 32 #include "wine/debug.h"
 33 #include "shdocvw.h"
 34 #include "objidl.h"
 35 #include "shobjidl.h"
 36 #include "intshcut.h"
 37 
 38 WINE_DEFAULT_DEBUG_CHANNEL(shdocvw);
 39 
 40 typedef struct
 41 {
 42     IUniformResourceLocatorA uniformResourceLocatorA;
 43     IUniformResourceLocatorW uniformResourceLocatorW;
 44     IPersistFile persistFile;
 45 
 46     LONG refCount;
 47 
 48     WCHAR *url;
 49     BOOLEAN isDirty;
 50     LPOLESTR currentFile;
 51 } InternetShortcut;
 52 
 53 /* utility functions */
 54 
 55 static inline InternetShortcut* impl_from_IUniformResourceLocatorA(IUniformResourceLocatorA *iface)
 56 {
 57     return (InternetShortcut*)((char*)iface - FIELD_OFFSET(InternetShortcut, uniformResourceLocatorA));
 58 }
 59 
 60 static inline InternetShortcut* impl_from_IUniformResourceLocatorW(IUniformResourceLocatorW *iface)
 61 {
 62     return (InternetShortcut*)((char*)iface - FIELD_OFFSET(InternetShortcut, uniformResourceLocatorW));
 63 }
 64 
 65 static inline InternetShortcut* impl_from_IPersistFile(IPersistFile *iface)
 66 {
 67     return (InternetShortcut*)((char*)iface - FIELD_OFFSET(InternetShortcut, persistFile));
 68 }
 69 
 70 /* interface functions */
 71 
 72 static HRESULT WINAPI Unknown_QueryInterface(InternetShortcut *This, REFIID riid, PVOID *ppvObject)
 73 {
 74     TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppvObject);
 75     *ppvObject = NULL;
 76     if (IsEqualGUID(&IID_IUnknown, riid))
 77         *ppvObject = &This->uniformResourceLocatorA;
 78     else if (IsEqualGUID(&IID_IUniformResourceLocatorA, riid))
 79         *ppvObject = &This->uniformResourceLocatorA;
 80     else if (IsEqualGUID(&IID_IUniformResourceLocatorW, riid))
 81         *ppvObject = &This->uniformResourceLocatorW;
 82     else if (IsEqualGUID(&IID_IPersistFile, riid))
 83         *ppvObject = &This->persistFile;
 84     else if (IsEqualGUID(&IID_IShellLinkA, riid))
 85     {
 86         FIXME("The IShellLinkA interface is not yet supported by InternetShortcut\n");
 87         return E_NOINTERFACE;
 88     }
 89     else if (IsEqualGUID(&IID_IShellLinkW, riid))
 90     {
 91         FIXME("The IShellLinkW interface is not yet supported by InternetShortcut\n");
 92         return E_NOINTERFACE;
 93     }
 94     else
 95     {
 96         FIXME("Interface with GUID %s not yet implemented by InternetShortcut\n", debugstr_guid(riid));
 97         return E_NOINTERFACE;
 98     }
 99     IUnknown_AddRef((IUnknown*)*ppvObject);
100     return S_OK;
101 }
102 
103 static ULONG WINAPI Unknown_AddRef(InternetShortcut *This)
104 {
105     TRACE("(%p)\n", This);
106     return InterlockedIncrement(&This->refCount);
107 }
108 
109 static ULONG WINAPI Unknown_Release(InternetShortcut *This)
110 {
111     ULONG count;
112     TRACE("(%p)\n", This);
113     count = InterlockedDecrement(&This->refCount);
114     if (count == 0)
115     {
116         CoTaskMemFree(This->url);
117         CoTaskMemFree(This->currentFile);
118         heap_free(This);
119         SHDOCVW_UnlockModule();
120     }
121     return count;
122 }
123 
124 static HRESULT WINAPI UniformResourceLocatorW_QueryInterface(IUniformResourceLocatorW *url, REFIID riid, PVOID *ppvObject)
125 {
126     InternetShortcut *This = impl_from_IUniformResourceLocatorW(url);
127     TRACE("(%p, %s, %p)\n", url, debugstr_guid(riid), ppvObject);
128     return Unknown_QueryInterface(This, riid, ppvObject);
129 }
130 
131 static ULONG WINAPI UniformResourceLocatorW_AddRef(IUniformResourceLocatorW *url)
132 {
133     InternetShortcut *This = impl_from_IUniformResourceLocatorW(url);
134     TRACE("(%p)\n", url);
135     return Unknown_AddRef(This);
136 }
137 
138 static ULONG WINAPI UniformResourceLocatorW_Release(IUniformResourceLocatorW *url)
139 {
140     InternetShortcut *This = impl_from_IUniformResourceLocatorW(url);
141     TRACE("(%p)\n", url);
142     return Unknown_Release(This);
143 }
144 
145 static HRESULT WINAPI UniformResourceLocatorW_SetUrl(IUniformResourceLocatorW *url, LPCWSTR pcszURL, DWORD dwInFlags)
146 {
147     WCHAR *newURL = NULL;
148     InternetShortcut *This = impl_from_IUniformResourceLocatorW(url);
149     TRACE("(%p, %s, 0x%x)\n", url, debugstr_w(pcszURL), dwInFlags);
150     if (dwInFlags != 0)
151         FIXME("ignoring unsupported flags 0x%x\n", dwInFlags);
152     if (pcszURL != NULL)
153     {
154         newURL = co_strdupW(pcszURL);
155         if (newURL == NULL)
156             return E_OUTOFMEMORY;
157     }
158     CoTaskMemFree(This->url);
159     This->url = newURL;
160     This->isDirty = TRUE;
161     return S_OK;
162 }
163 
164 static HRESULT WINAPI UniformResourceLocatorW_GetUrl(IUniformResourceLocatorW *url, LPWSTR *ppszURL)
165 {
166     HRESULT hr = S_OK;
167     InternetShortcut *This = impl_from_IUniformResourceLocatorW(url);
168     TRACE("(%p, %p)\n", url, ppszURL);
169     if (This->url == NULL)
170         *ppszURL = NULL;
171     else
172     {
173         *ppszURL = co_strdupW(This->url);
174         if (*ppszURL == NULL)
175             hr = E_OUTOFMEMORY;
176     }
177     return hr;
178 }
179 
180 static HRESULT WINAPI UniformResourceLocatorW_InvokeCommand(IUniformResourceLocatorW *url, PURLINVOKECOMMANDINFOW pCommandInfo)
181 {
182     FIXME("(%p, %p): stub\n", url, pCommandInfo);
183     return E_NOTIMPL;
184 }
185 
186 static HRESULT WINAPI UniformResourceLocatorA_QueryInterface(IUniformResourceLocatorA *url, REFIID riid, PVOID *ppvObject)
187 {
188     InternetShortcut *This = impl_from_IUniformResourceLocatorA(url);
189     TRACE("(%p, %s, %p)\n", url, debugstr_guid(riid), ppvObject);
190     return Unknown_QueryInterface(This, riid, ppvObject);
191 }
192 
193 static ULONG WINAPI UniformResourceLocatorA_AddRef(IUniformResourceLocatorA *url)
194 {
195     InternetShortcut *This = impl_from_IUniformResourceLocatorA(url);
196     TRACE("(%p)\n", url);
197     return Unknown_AddRef(This);
198 }
199 
200 static ULONG WINAPI UniformResourceLocatorA_Release(IUniformResourceLocatorA *url)
201 {
202     InternetShortcut *This = impl_from_IUniformResourceLocatorA(url);
203     TRACE("(%p)\n", url);
204     return Unknown_Release(This);
205 }
206 
207 static HRESULT WINAPI UniformResourceLocatorA_SetUrl(IUniformResourceLocatorA *url, LPCSTR pcszURL, DWORD dwInFlags)
208 {
209     WCHAR *newURL = NULL;
210     InternetShortcut *This = impl_from_IUniformResourceLocatorA(url);
211     TRACE("(%p, %s, 0x%x)\n", url, debugstr_a(pcszURL), dwInFlags);
212     if (dwInFlags != 0)
213         FIXME("ignoring unsupported flags 0x%x\n", dwInFlags);
214     if (pcszURL != NULL)
215     {
216         newURL = co_strdupAtoW(pcszURL);
217         if (newURL == NULL)
218             return E_OUTOFMEMORY;
219     }
220     CoTaskMemFree(This->url);
221     This->url = newURL;
222     This->isDirty = TRUE;
223     return S_OK;
224 }
225 
226 static HRESULT WINAPI UniformResourceLocatorA_GetUrl(IUniformResourceLocatorA *url, LPSTR *ppszURL)
227 {
228     HRESULT hr = S_OK;
229     InternetShortcut *This = impl_from_IUniformResourceLocatorA(url);
230     TRACE("(%p, %p)\n", url, ppszURL);
231     if (This->url == NULL)
232         *ppszURL = NULL;
233     else
234     {
235         *ppszURL = co_strdupWtoA(This->url);
236         if (*ppszURL == NULL)
237             hr = E_OUTOFMEMORY;
238     }
239     return hr;
240 }
241 
242 static HRESULT WINAPI UniformResourceLocatorA_InvokeCommand(IUniformResourceLocatorA *url, PURLINVOKECOMMANDINFOA pCommandInfo)
243 {
244     FIXME("(%p, %p): stub\n", url, pCommandInfo);
245     return E_NOTIMPL;
246 }
247 
248 static HRESULT WINAPI PersistFile_QueryInterface(IPersistFile *pFile, REFIID riid, PVOID *ppvObject)
249 {
250     InternetShortcut *This = impl_from_IPersistFile(pFile);
251     TRACE("(%p, %s, %p)\n", pFile, debugstr_guid(riid), ppvObject);
252     return Unknown_QueryInterface(This, riid, ppvObject);
253 }
254 
255 static ULONG WINAPI PersistFile_AddRef(IPersistFile *pFile)
256 {
257     InternetShortcut *This = impl_from_IPersistFile(pFile);
258     TRACE("(%p)\n", pFile);
259     return Unknown_AddRef(This);
260 }
261 
262 static ULONG WINAPI PersistFile_Release(IPersistFile *pFile)
263 {
264     InternetShortcut *This = impl_from_IPersistFile(pFile);
265     TRACE("(%p)\n", pFile);
266     return Unknown_Release(This);
267 }
268 
269 static HRESULT WINAPI PersistFile_GetClassID(IPersistFile *pFile, CLSID *pClassID)
270 {
271     TRACE("(%p, %p)\n", pFile, pClassID);
272     *pClassID = CLSID_InternetShortcut;
273     return S_OK;
274 }
275 
276 static HRESULT WINAPI PersistFile_IsDirty(IPersistFile *pFile)
277 {
278     InternetShortcut *This = impl_from_IPersistFile(pFile);
279     TRACE("(%p)\n", pFile);
280     return This->isDirty ? S_OK : S_FALSE;
281 }
282 
283 static HRESULT WINAPI PersistFile_Load(IPersistFile *pFile, LPCOLESTR pszFileName, DWORD dwMode)
284 {
285     FIXME("(%p, %p, 0x%x): stub\n", pFile, pszFileName, dwMode);
286     return E_NOTIMPL;
287 }
288 
289 static HRESULT WINAPI PersistFile_Save(IPersistFile *pFile, LPCOLESTR pszFileName, BOOL fRemember)
290 {
291     HRESULT hr = S_OK;
292     INT len;
293     CHAR *url;
294     InternetShortcut *This = impl_from_IPersistFile(pFile);
295 
296     TRACE("(%p, %s, %d)\n", pFile, debugstr_w(pszFileName), fRemember);
297 
298     if (pszFileName != NULL && fRemember)
299     {
300         LPOLESTR oldFile = This->currentFile;
301         This->currentFile = co_strdupW(pszFileName);
302         if (This->currentFile == NULL)
303         {
304             This->currentFile = oldFile;
305             return E_OUTOFMEMORY;
306         }
307         CoTaskMemFree(oldFile);
308     }
309     if (This->url == NULL)
310         return E_FAIL;
311 
312     /* Windows seems to always write:
313      *   ASCII "[InternetShortcut]" headers
314      *   ASCII names in "name=value" pairs
315      *   An ASCII (probably UTF8?) value in "URL=..."
316      */
317     len = WideCharToMultiByte(CP_UTF8, 0, This->url, -1, NULL, 0, 0, 0);
318     url = heap_alloc(len);
319     if (url != NULL)
320     {
321         HANDLE file;
322         WideCharToMultiByte(CP_UTF8, 0, This->url, -1, url, len, 0, 0);
323         file = CreateFileW(pszFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
324         if (file != INVALID_HANDLE_VALUE)
325         {
326             DWORD bytesWritten;
327             char str_header[] = "[InternetShortcut]";
328             char str_URL[] = "URL=";
329             char str_eol[] = "\r\n";
330 
331             WriteFile(file, str_header, lstrlenA(str_header), &bytesWritten, NULL);
332             WriteFile(file, str_eol, lstrlenA(str_eol), &bytesWritten, NULL);
333             WriteFile(file, str_URL, lstrlenA(str_URL), &bytesWritten, NULL);
334             WriteFile(file, url, lstrlenA(url), &bytesWritten, NULL);
335             WriteFile(file, str_eol, lstrlenA(str_eol), &bytesWritten, NULL);
336             CloseHandle(file);
337             if (pszFileName == NULL || fRemember)
338                 This->isDirty = FALSE;
339         }
340         else
341             hr = E_FAIL;
342         heap_free(url);
343     }
344     else
345         hr = E_OUTOFMEMORY;
346 
347     return hr;
348 }
349 
350 static HRESULT WINAPI PersistFile_SaveCompleted(IPersistFile *pFile, LPCOLESTR pszFileName)
351 {
352     FIXME("(%p, %p): stub\n", pFile, pszFileName);
353     return E_NOTIMPL;
354 }
355 
356 static HRESULT WINAPI PersistFile_GetCurFile(IPersistFile *pFile, LPOLESTR *ppszFileName)
357 {
358     HRESULT hr = S_OK;
359     InternetShortcut *This = impl_from_IPersistFile(pFile);
360     TRACE("(%p, %p)\n", pFile, ppszFileName);
361     if (This->currentFile == NULL)
362         *ppszFileName = NULL;
363     else
364     {
365         *ppszFileName = co_strdupW(This->currentFile);
366         if (*ppszFileName == NULL)
367             hr = E_OUTOFMEMORY;
368     }
369     return hr;
370 }
371 
372 
373 
374 static const IUniformResourceLocatorWVtbl uniformResourceLocatorWVtbl = {
375     UniformResourceLocatorW_QueryInterface,
376     UniformResourceLocatorW_AddRef,
377     UniformResourceLocatorW_Release,
378     UniformResourceLocatorW_SetUrl,
379     UniformResourceLocatorW_GetUrl,
380     UniformResourceLocatorW_InvokeCommand
381 };
382 
383 static const IUniformResourceLocatorAVtbl uniformResourceLocatorAVtbl = {
384     UniformResourceLocatorA_QueryInterface,
385     UniformResourceLocatorA_AddRef,
386     UniformResourceLocatorA_Release,
387     UniformResourceLocatorA_SetUrl,
388     UniformResourceLocatorA_GetUrl,
389     UniformResourceLocatorA_InvokeCommand
390 };
391 
392 static const IPersistFileVtbl persistFileVtbl = {
393     PersistFile_QueryInterface,
394     PersistFile_AddRef,
395     PersistFile_Release,
396     PersistFile_GetClassID,
397     PersistFile_IsDirty,
398     PersistFile_Load,
399     PersistFile_Save,
400     PersistFile_SaveCompleted,
401     PersistFile_GetCurFile
402 };
403 
404 HRESULT InternetShortcut_Create(IUnknown *pOuter, REFIID riid, void **ppv)
405 {
406     InternetShortcut *This;
407     HRESULT hr;
408 
409     TRACE("(%p, %s, %p)\n", pOuter, debugstr_guid(riid), ppv);
410 
411     *ppv = NULL;
412 
413     if(pOuter)
414         return CLASS_E_NOAGGREGATION;
415 
416     This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(InternetShortcut));
417     if (This)
418     {
419         This->uniformResourceLocatorA.lpVtbl = &uniformResourceLocatorAVtbl;
420         This->uniformResourceLocatorW.lpVtbl = &uniformResourceLocatorWVtbl;
421         This->persistFile.lpVtbl = &persistFileVtbl;
422         This->refCount = 0;
423         hr = Unknown_QueryInterface(This, riid, ppv);
424         if (SUCCEEDED(hr))
425             SHDOCVW_LockModule();
426         else
427             heap_free(This);
428         return hr;
429     }
430     else
431         return E_OUTOFMEMORY;
432 }
433 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.