ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

intshcut.c
Go to the documentation of this file.
00001 /*
00002  * Copyright 2008 Damjan Jovanovic
00003  *
00004  * ShellLink's barely documented cousin that handles URLs.
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2.1 of the License, or (at your option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this library; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00019  */
00020 
00021 /*
00022  * TODO:
00023  * Implement the IShellLinkA/W interfaces
00024  * Handle the SetURL flags
00025  * Implement any other interfaces? Does any software actually use them?
00026  *
00027  * The installer for the Zuma Deluxe Popcap game is good for testing.
00028  */
00029 
00030 #include <stdarg.h>
00031 #include <stdio.h>
00032 
00033 #include "wine/debug.h"
00034 #include "shdocvw.h"
00035 #include "objidl.h"
00036 #include "shobjidl.h"
00037 #include "intshcut.h"
00038 #include "shellapi.h"
00039 #include "winreg.h"
00040 #include "shlwapi.h"
00041 
00042 WINE_DEFAULT_DEBUG_CHANNEL(shdocvw);
00043 
00044 typedef struct
00045 {
00046     IUniformResourceLocatorA uniformResourceLocatorA;
00047     IUniformResourceLocatorW uniformResourceLocatorW;
00048     IPersistFile persistFile;
00049 
00050     LONG refCount;
00051 
00052     WCHAR *url;
00053     BOOLEAN isDirty;
00054     LPOLESTR currentFile;
00055 } InternetShortcut;
00056 
00057 /* utility functions */
00058 
00059 static inline InternetShortcut* impl_from_IUniformResourceLocatorA(IUniformResourceLocatorA *iface)
00060 {
00061     return (InternetShortcut*)((char*)iface - FIELD_OFFSET(InternetShortcut, uniformResourceLocatorA));
00062 }
00063 
00064 static inline InternetShortcut* impl_from_IUniformResourceLocatorW(IUniformResourceLocatorW *iface)
00065 {
00066     return (InternetShortcut*)((char*)iface - FIELD_OFFSET(InternetShortcut, uniformResourceLocatorW));
00067 }
00068 
00069 static inline InternetShortcut* impl_from_IPersistFile(IPersistFile *iface)
00070 {
00071     return (InternetShortcut*)((char*)iface - FIELD_OFFSET(InternetShortcut, persistFile));
00072 }
00073 
00074 static BOOL run_winemenubuilder( const WCHAR *args )
00075 {
00076     static const WCHAR menubuilder[] = {'\\','w','i','n','e','m','e','n','u','b','u','i','l','d','e','r','.','e','x','e',0};
00077     LONG len;
00078     LPWSTR buffer;
00079     STARTUPINFOW si;
00080     PROCESS_INFORMATION pi;
00081     BOOL ret;
00082     WCHAR app[MAX_PATH];
00083     void *redir;
00084 
00085     GetSystemDirectoryW( app, MAX_PATH - sizeof(menubuilder)/sizeof(WCHAR) );
00086     strcatW( app, menubuilder );
00087 
00088     len = (strlenW( app ) + strlenW( args ) + 1) * sizeof(WCHAR);
00089     buffer = heap_alloc( len );
00090     if( !buffer )
00091         return FALSE;
00092 
00093     strcpyW( buffer, app );
00094     strcatW( buffer, args );
00095 
00096     TRACE("starting %s\n",debugstr_w(buffer));
00097 
00098     memset(&si, 0, sizeof(si));
00099     si.cb = sizeof(si);
00100 
00101     Wow64DisableWow64FsRedirection( &redir );
00102     ret = CreateProcessW( app, buffer, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi );
00103     Wow64RevertWow64FsRedirection( redir );
00104 
00105     heap_free( buffer );
00106 
00107     if (ret)
00108     {
00109         CloseHandle( pi.hProcess );
00110         CloseHandle( pi.hThread );
00111     }
00112 
00113     return ret;
00114 }
00115 
00116 static BOOL StartLinkProcessor( LPCOLESTR szLink )
00117 {
00118     static const WCHAR szFormat[] = { ' ','-','w',' ','-','u',' ','"','%','s','"',0 };
00119     LONG len;
00120     LPWSTR buffer;
00121     BOOL ret;
00122 
00123     len = sizeof(szFormat) + lstrlenW( szLink ) * sizeof(WCHAR);
00124     buffer = heap_alloc( len );
00125     if( !buffer )
00126         return FALSE;
00127 
00128     wsprintfW( buffer, szFormat, szLink );
00129     ret = run_winemenubuilder( buffer );
00130     heap_free( buffer );
00131     return ret;
00132 }
00133 
00134 /* interface functions */
00135 
00136 static HRESULT Unknown_QueryInterface(InternetShortcut *This, REFIID riid, PVOID *ppvObject)
00137 {
00138     TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppvObject);
00139     *ppvObject = NULL;
00140     if (IsEqualGUID(&IID_IUnknown, riid))
00141         *ppvObject = &This->uniformResourceLocatorA;
00142     else if (IsEqualGUID(&IID_IUniformResourceLocatorA, riid))
00143         *ppvObject = &This->uniformResourceLocatorA;
00144     else if (IsEqualGUID(&IID_IUniformResourceLocatorW, riid))
00145         *ppvObject = &This->uniformResourceLocatorW;
00146     else if (IsEqualGUID(&IID_IPersistFile, riid))
00147         *ppvObject = &This->persistFile;
00148     else if (IsEqualGUID(&IID_IShellLinkA, riid))
00149     {
00150         FIXME("The IShellLinkA interface is not yet supported by InternetShortcut\n");
00151         return E_NOINTERFACE;
00152     }
00153     else if (IsEqualGUID(&IID_IShellLinkW, riid))
00154     {
00155         FIXME("The IShellLinkW interface is not yet supported by InternetShortcut\n");
00156         return E_NOINTERFACE;
00157     }
00158     else
00159     {
00160         FIXME("Interface with GUID %s not yet implemented by InternetShortcut\n", debugstr_guid(riid));
00161         return E_NOINTERFACE;
00162     }
00163     IUnknown_AddRef((IUnknown*)*ppvObject);
00164     return S_OK;
00165 }
00166 
00167 static ULONG Unknown_AddRef(InternetShortcut *This)
00168 {
00169     TRACE("(%p)\n", This);
00170     return InterlockedIncrement(&This->refCount);
00171 }
00172 
00173 static ULONG Unknown_Release(InternetShortcut *This)
00174 {
00175     ULONG count;
00176     TRACE("(%p)\n", This);
00177     count = InterlockedDecrement(&This->refCount);
00178     if (count == 0)
00179     {
00180         CoTaskMemFree(This->url);
00181         CoTaskMemFree(This->currentFile);
00182         heap_free(This);
00183         SHDOCVW_UnlockModule();
00184     }
00185     return count;
00186 }
00187 
00188 static HRESULT WINAPI UniformResourceLocatorW_QueryInterface(IUniformResourceLocatorW *url, REFIID riid, PVOID *ppvObject)
00189 {
00190     InternetShortcut *This = impl_from_IUniformResourceLocatorW(url);
00191     TRACE("(%p, %s, %p)\n", url, debugstr_guid(riid), ppvObject);
00192     return Unknown_QueryInterface(This, riid, ppvObject);
00193 }
00194 
00195 static ULONG WINAPI UniformResourceLocatorW_AddRef(IUniformResourceLocatorW *url)
00196 {
00197     InternetShortcut *This = impl_from_IUniformResourceLocatorW(url);
00198     TRACE("(%p)\n", url);
00199     return Unknown_AddRef(This);
00200 }
00201 
00202 static ULONG WINAPI UniformResourceLocatorW_Release(IUniformResourceLocatorW *url)
00203 {
00204     InternetShortcut *This = impl_from_IUniformResourceLocatorW(url);
00205     TRACE("(%p)\n", url);
00206     return Unknown_Release(This);
00207 }
00208 
00209 static HRESULT WINAPI UniformResourceLocatorW_SetUrl(IUniformResourceLocatorW *url, LPCWSTR pcszURL, DWORD dwInFlags)
00210 {
00211     WCHAR *newURL = NULL;
00212     InternetShortcut *This = impl_from_IUniformResourceLocatorW(url);
00213     TRACE("(%p, %s, 0x%x)\n", url, debugstr_w(pcszURL), dwInFlags);
00214     if (dwInFlags != 0)
00215         FIXME("ignoring unsupported flags 0x%x\n", dwInFlags);
00216     if (pcszURL != NULL)
00217     {
00218         newURL = co_strdupW(pcszURL);
00219         if (newURL == NULL)
00220             return E_OUTOFMEMORY;
00221     }
00222     CoTaskMemFree(This->url);
00223     This->url = newURL;
00224     This->isDirty = TRUE;
00225     return S_OK;
00226 }
00227 
00228 static HRESULT WINAPI UniformResourceLocatorW_GetUrl(IUniformResourceLocatorW *url, LPWSTR *ppszURL)
00229 {
00230     HRESULT hr = S_OK;
00231     InternetShortcut *This = impl_from_IUniformResourceLocatorW(url);
00232     TRACE("(%p, %p)\n", url, ppszURL);
00233     if (This->url == NULL)
00234         *ppszURL = NULL;
00235     else
00236     {
00237         *ppszURL = co_strdupW(This->url);
00238         if (*ppszURL == NULL)
00239             hr = E_OUTOFMEMORY;
00240     }
00241     return hr;
00242 }
00243 
00244 static HRESULT WINAPI UniformResourceLocatorW_InvokeCommand(IUniformResourceLocatorW *url, PURLINVOKECOMMANDINFOW pCommandInfo)
00245 {
00246     InternetShortcut *This = impl_from_IUniformResourceLocatorW(url);
00247     WCHAR app[64];
00248     HKEY hkey;
00249     static const WCHAR wszURLProtocol[] = {'U','R','L',' ','P','r','o','t','o','c','o','l',0};
00250     SHELLEXECUTEINFOW sei;
00251     DWORD res, type;
00252     HRESULT hres;
00253 
00254     TRACE("%p %p\n", This, pCommandInfo );
00255 
00256     if (pCommandInfo->dwcbSize < sizeof (URLINVOKECOMMANDINFOW))
00257         return E_INVALIDARG;
00258 
00259     if (pCommandInfo->dwFlags != IURL_INVOKECOMMAND_FL_USE_DEFAULT_VERB)
00260     {
00261         FIXME("(%p, %p): non-default verbs not implemented\n", url, pCommandInfo);
00262         return E_NOTIMPL;
00263     }
00264 
00265     hres = CoInternetParseUrl(This->url, PARSE_SCHEMA, 0, app, sizeof(app)/sizeof(WCHAR), NULL, 0);
00266     if(FAILED(hres))
00267         return E_FAIL;
00268 
00269     res = RegOpenKeyW(HKEY_CLASSES_ROOT, app, &hkey);
00270     if(res != ERROR_SUCCESS)
00271         return E_FAIL;
00272 
00273     res = RegQueryValueExW(hkey, wszURLProtocol, NULL, &type, NULL, NULL);
00274     RegCloseKey(hkey);
00275     if(res != ERROR_SUCCESS || type != REG_SZ)
00276         return E_FAIL;
00277 
00278     memset(&sei, 0, sizeof(sei));
00279     sei.cbSize = sizeof(sei);
00280     sei.lpFile = This->url;
00281     sei.nShow = SW_SHOW;
00282 
00283     if( ShellExecuteExW(&sei) )
00284         return S_OK;
00285     else
00286         return E_FAIL;
00287 }
00288 
00289 static HRESULT WINAPI UniformResourceLocatorA_QueryInterface(IUniformResourceLocatorA *url, REFIID riid, PVOID *ppvObject)
00290 {
00291     InternetShortcut *This = impl_from_IUniformResourceLocatorA(url);
00292     TRACE("(%p, %s, %p)\n", url, debugstr_guid(riid), ppvObject);
00293     return Unknown_QueryInterface(This, riid, ppvObject);
00294 }
00295 
00296 static ULONG WINAPI UniformResourceLocatorA_AddRef(IUniformResourceLocatorA *url)
00297 {
00298     InternetShortcut *This = impl_from_IUniformResourceLocatorA(url);
00299     TRACE("(%p)\n", url);
00300     return Unknown_AddRef(This);
00301 }
00302 
00303 static ULONG WINAPI UniformResourceLocatorA_Release(IUniformResourceLocatorA *url)
00304 {
00305     InternetShortcut *This = impl_from_IUniformResourceLocatorA(url);
00306     TRACE("(%p)\n", url);
00307     return Unknown_Release(This);
00308 }
00309 
00310 static HRESULT WINAPI UniformResourceLocatorA_SetUrl(IUniformResourceLocatorA *url, LPCSTR pcszURL, DWORD dwInFlags)
00311 {
00312     WCHAR *newURL = NULL;
00313     InternetShortcut *This = impl_from_IUniformResourceLocatorA(url);
00314     TRACE("(%p, %s, 0x%x)\n", url, debugstr_a(pcszURL), dwInFlags);
00315     if (dwInFlags != 0)
00316         FIXME("ignoring unsupported flags 0x%x\n", dwInFlags);
00317     if (pcszURL != NULL)
00318     {
00319         newURL = co_strdupAtoW(pcszURL);
00320         if (newURL == NULL)
00321             return E_OUTOFMEMORY;
00322     }
00323     CoTaskMemFree(This->url);
00324     This->url = newURL;
00325     This->isDirty = TRUE;
00326     return S_OK;
00327 }
00328 
00329 static HRESULT WINAPI UniformResourceLocatorA_GetUrl(IUniformResourceLocatorA *url, LPSTR *ppszURL)
00330 {
00331     HRESULT hr = S_OK;
00332     InternetShortcut *This = impl_from_IUniformResourceLocatorA(url);
00333     TRACE("(%p, %p)\n", url, ppszURL);
00334     if (This->url == NULL)
00335         *ppszURL = NULL;
00336     else
00337     {
00338         *ppszURL = co_strdupWtoA(This->url);
00339         if (*ppszURL == NULL)
00340             hr = E_OUTOFMEMORY;
00341     }
00342     return hr;
00343 }
00344 
00345 static HRESULT WINAPI UniformResourceLocatorA_InvokeCommand(IUniformResourceLocatorA *url, PURLINVOKECOMMANDINFOA pCommandInfo)
00346 {
00347     URLINVOKECOMMANDINFOW wideCommandInfo;
00348     int len;
00349     WCHAR *wideVerb;
00350     HRESULT res;
00351     InternetShortcut *This = impl_from_IUniformResourceLocatorA(url);
00352 
00353     wideCommandInfo.dwcbSize = sizeof wideCommandInfo;
00354     wideCommandInfo.dwFlags = pCommandInfo->dwFlags;
00355     wideCommandInfo.hwndParent = pCommandInfo->hwndParent;
00356 
00357     len = MultiByteToWideChar(CP_ACP, 0, pCommandInfo->pcszVerb, -1, NULL, 0);
00358     wideVerb = heap_alloc(len * sizeof(WCHAR));
00359     MultiByteToWideChar(CP_ACP, 0, pCommandInfo->pcszVerb, -1, wideVerb, len);
00360 
00361     wideCommandInfo.pcszVerb = wideVerb;
00362 
00363     res = UniformResourceLocatorW_InvokeCommand(&This->uniformResourceLocatorW, &wideCommandInfo);
00364     heap_free(wideVerb);
00365 
00366     return res;
00367 }
00368 
00369 static HRESULT WINAPI PersistFile_QueryInterface(IPersistFile *pFile, REFIID riid, PVOID *ppvObject)
00370 {
00371     InternetShortcut *This = impl_from_IPersistFile(pFile);
00372     TRACE("(%p, %s, %p)\n", pFile, debugstr_guid(riid), ppvObject);
00373     return Unknown_QueryInterface(This, riid, ppvObject);
00374 }
00375 
00376 static ULONG WINAPI PersistFile_AddRef(IPersistFile *pFile)
00377 {
00378     InternetShortcut *This = impl_from_IPersistFile(pFile);
00379     TRACE("(%p)\n", pFile);
00380     return Unknown_AddRef(This);
00381 }
00382 
00383 static ULONG WINAPI PersistFile_Release(IPersistFile *pFile)
00384 {
00385     InternetShortcut *This = impl_from_IPersistFile(pFile);
00386     TRACE("(%p)\n", pFile);
00387     return Unknown_Release(This);
00388 }
00389 
00390 static HRESULT WINAPI PersistFile_GetClassID(IPersistFile *pFile, CLSID *pClassID)
00391 {
00392     TRACE("(%p, %p)\n", pFile, pClassID);
00393     *pClassID = CLSID_InternetShortcut;
00394     return S_OK;
00395 }
00396 
00397 static HRESULT WINAPI PersistFile_IsDirty(IPersistFile *pFile)
00398 {
00399     InternetShortcut *This = impl_from_IPersistFile(pFile);
00400     TRACE("(%p)\n", pFile);
00401     return This->isDirty ? S_OK : S_FALSE;
00402 }
00403 
00404 static HRESULT WINAPI PersistFile_Load(IPersistFile *pFile, LPCOLESTR pszFileName, DWORD dwMode)
00405 {
00406     WCHAR str_header[] = {'I','n','t','e','r','n','e','t','S','h','o','r','t','c','u','t',0};
00407     WCHAR str_URL[] = {'U','R','L',0};
00408     WCHAR *filename = NULL;
00409     HRESULT hr;
00410     InternetShortcut *This = impl_from_IPersistFile(pFile);
00411     TRACE("(%p, %s, 0x%x)\n", pFile, debugstr_w(pszFileName), dwMode);
00412     if (dwMode != 0)
00413         FIXME("ignoring unimplemented mode 0x%x\n", dwMode);
00414     filename = co_strdupW(pszFileName);
00415     if (filename != NULL)
00416     {
00417         DWORD len = 128;
00418         DWORD r;
00419         WCHAR *url = CoTaskMemAlloc(len*sizeof(WCHAR));
00420         if (url != NULL)
00421         {
00422             r = GetPrivateProfileStringW(str_header, str_URL, NULL, url, len, pszFileName);
00423             while (r == len-1)
00424             {
00425                 CoTaskMemFree(url);
00426                 len *= 2;
00427                 url = CoTaskMemAlloc(len*sizeof(WCHAR));
00428                 if (url == NULL)
00429                     break;
00430                 r = GetPrivateProfileStringW(str_header, str_URL, NULL, url, len, pszFileName);
00431             }
00432             if (r == 0)
00433                 hr = E_FAIL;
00434             else if (url != NULL)
00435             {
00436                 CoTaskMemFree(This->currentFile);
00437                 This->currentFile = filename;
00438                 CoTaskMemFree(This->url);
00439                 This->url = url;
00440                 This->isDirty = FALSE;
00441                 return S_OK;
00442             }
00443             else
00444                 hr = E_OUTOFMEMORY;
00445             CoTaskMemFree(url);
00446         }
00447         else
00448             hr = E_OUTOFMEMORY;
00449         CoTaskMemFree(filename);
00450     }
00451     else
00452         hr = E_OUTOFMEMORY;
00453     return hr;
00454 }
00455 
00456 static HRESULT WINAPI PersistFile_Save(IPersistFile *pFile, LPCOLESTR pszFileName, BOOL fRemember)
00457 {
00458     HRESULT hr = S_OK;
00459     INT len;
00460     CHAR *url;
00461     InternetShortcut *This = impl_from_IPersistFile(pFile);
00462 
00463     TRACE("(%p, %s, %d)\n", pFile, debugstr_w(pszFileName), fRemember);
00464 
00465     if (pszFileName != NULL && fRemember)
00466     {
00467         LPOLESTR oldFile = This->currentFile;
00468         This->currentFile = co_strdupW(pszFileName);
00469         if (This->currentFile == NULL)
00470         {
00471             This->currentFile = oldFile;
00472             return E_OUTOFMEMORY;
00473         }
00474         CoTaskMemFree(oldFile);
00475     }
00476     if (This->url == NULL)
00477         return E_FAIL;
00478 
00479     /* Windows seems to always write:
00480      *   ASCII "[InternetShortcut]" headers
00481      *   ASCII names in "name=value" pairs
00482      *   An ASCII (probably UTF8?) value in "URL=..."
00483      */
00484     len = WideCharToMultiByte(CP_UTF8, 0, This->url, -1, NULL, 0, 0, 0);
00485     url = heap_alloc(len);
00486     if (url != NULL)
00487     {
00488         HANDLE file;
00489         WideCharToMultiByte(CP_UTF8, 0, This->url, -1, url, len, 0, 0);
00490         file = CreateFileW(pszFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
00491         if (file != INVALID_HANDLE_VALUE)
00492         {
00493             DWORD bytesWritten;
00494             char str_header[] = "[InternetShortcut]";
00495             char str_URL[] = "URL=";
00496             char str_eol[] = "\r\n";
00497 
00498             WriteFile(file, str_header, lstrlenA(str_header), &bytesWritten, NULL);
00499             WriteFile(file, str_eol, lstrlenA(str_eol), &bytesWritten, NULL);
00500             WriteFile(file, str_URL, lstrlenA(str_URL), &bytesWritten, NULL);
00501             WriteFile(file, url, lstrlenA(url), &bytesWritten, NULL);
00502             WriteFile(file, str_eol, lstrlenA(str_eol), &bytesWritten, NULL);
00503             CloseHandle(file);
00504             if (pszFileName == NULL || fRemember)
00505                 This->isDirty = FALSE;
00506             StartLinkProcessor(pszFileName);
00507         }
00508         else
00509             hr = E_FAIL;
00510         heap_free(url);
00511     }
00512     else
00513         hr = E_OUTOFMEMORY;
00514 
00515     return hr;
00516 }
00517 
00518 static HRESULT WINAPI PersistFile_SaveCompleted(IPersistFile *pFile, LPCOLESTR pszFileName)
00519 {
00520     FIXME("(%p, %p): stub\n", pFile, pszFileName);
00521     return E_NOTIMPL;
00522 }
00523 
00524 static HRESULT WINAPI PersistFile_GetCurFile(IPersistFile *pFile, LPOLESTR *ppszFileName)
00525 {
00526     HRESULT hr = S_OK;
00527     InternetShortcut *This = impl_from_IPersistFile(pFile);
00528     TRACE("(%p, %p)\n", pFile, ppszFileName);
00529     if (This->currentFile == NULL)
00530         *ppszFileName = NULL;
00531     else
00532     {
00533         *ppszFileName = co_strdupW(This->currentFile);
00534         if (*ppszFileName == NULL)
00535             hr = E_OUTOFMEMORY;
00536     }
00537     return hr;
00538 }
00539 
00540 
00541 
00542 static const IUniformResourceLocatorWVtbl uniformResourceLocatorWVtbl = {
00543     UniformResourceLocatorW_QueryInterface,
00544     UniformResourceLocatorW_AddRef,
00545     UniformResourceLocatorW_Release,
00546     UniformResourceLocatorW_SetUrl,
00547     UniformResourceLocatorW_GetUrl,
00548     UniformResourceLocatorW_InvokeCommand
00549 };
00550 
00551 static const IUniformResourceLocatorAVtbl uniformResourceLocatorAVtbl = {
00552     UniformResourceLocatorA_QueryInterface,
00553     UniformResourceLocatorA_AddRef,
00554     UniformResourceLocatorA_Release,
00555     UniformResourceLocatorA_SetUrl,
00556     UniformResourceLocatorA_GetUrl,
00557     UniformResourceLocatorA_InvokeCommand
00558 };
00559 
00560 static const IPersistFileVtbl persistFileVtbl = {
00561     PersistFile_QueryInterface,
00562     PersistFile_AddRef,
00563     PersistFile_Release,
00564     PersistFile_GetClassID,
00565     PersistFile_IsDirty,
00566     PersistFile_Load,
00567     PersistFile_Save,
00568     PersistFile_SaveCompleted,
00569     PersistFile_GetCurFile
00570 };
00571 
00572 static InternetShortcut *create_shortcut(void)
00573 {
00574     InternetShortcut *newshortcut;
00575 
00576     newshortcut = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(InternetShortcut));
00577     if (newshortcut)
00578     {
00579         newshortcut->uniformResourceLocatorA.lpVtbl = &uniformResourceLocatorAVtbl;
00580         newshortcut->uniformResourceLocatorW.lpVtbl = &uniformResourceLocatorWVtbl;
00581         newshortcut->persistFile.lpVtbl = &persistFileVtbl;
00582         newshortcut->refCount = 0;
00583     }
00584 
00585     return newshortcut;
00586 }
00587 
00588 HRESULT InternetShortcut_Create(IUnknown *pOuter, REFIID riid, void **ppv)
00589 {
00590     InternetShortcut *This;
00591     HRESULT hr;
00592 
00593     TRACE("(%p, %s, %p)\n", pOuter, debugstr_guid(riid), ppv);
00594 
00595     *ppv = NULL;
00596 
00597     if(pOuter)
00598         return CLASS_E_NOAGGREGATION;
00599 
00600     This = create_shortcut();
00601     if (This)
00602     {
00603         hr = Unknown_QueryInterface(This, riid, ppv);
00604         if (SUCCEEDED(hr))
00605             SHDOCVW_LockModule();
00606         else
00607             heap_free(This);
00608         return hr;
00609     }
00610     else
00611         return E_OUTOFMEMORY;
00612 }
00613 
00614 
00615 /**********************************************************************
00616  * OpenURL  (SHDOCVW.@)
00617  */
00618 void WINAPI OpenURL(HWND hWnd, HINSTANCE hInst, LPCSTR lpcstrUrl, int nShowCmd)
00619 {
00620     InternetShortcut *shortcut;
00621     WCHAR* urlfilepath = NULL;
00622     shortcut = create_shortcut();
00623 
00624     if (shortcut)
00625     {
00626         int len;
00627 
00628         len = MultiByteToWideChar(CP_ACP, 0, lpcstrUrl, -1, NULL, 0);
00629         urlfilepath = heap_alloc(len * sizeof(WCHAR));
00630         MultiByteToWideChar(CP_ACP, 0, lpcstrUrl, -1, urlfilepath, len);
00631 
00632         if(SUCCEEDED(IPersistFile_Load(&shortcut->persistFile, urlfilepath, 0)))
00633         {
00634             URLINVOKECOMMANDINFOW ici;
00635 
00636             memset( &ici, 0, sizeof ici );
00637             ici.dwcbSize = sizeof ici;
00638             ici.dwFlags = IURL_INVOKECOMMAND_FL_USE_DEFAULT_VERB;
00639             ici.hwndParent = hWnd;
00640 
00641             if FAILED(UniformResourceLocatorW_InvokeCommand(&shortcut->uniformResourceLocatorW, (PURLINVOKECOMMANDINFOW) &ici))
00642                     TRACE("failed to open URL: %s\n.",debugstr_a(lpcstrUrl));
00643         }
00644 
00645         heap_free(shortcut);
00646         heap_free(urlfilepath);
00647     }
00648 }

Generated on Sun May 27 2012 04:26:15 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.