Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenintshcut.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
1.7.6.1
|