Author: janderwald Date: Tue Sep 15 00:55:44 2009 New Revision: 43051
URL: http://svn.reactos.org/svn/reactos?rev=43051&view=rev Log: - Check if a shortcut to shortcut is made and resolve it in that case - Fixes bug 4720
Modified: trunk/reactos/dll/cpl/appwiz/createlink.c
Modified: trunk/reactos/dll/cpl/appwiz/createlink.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/cpl/appwiz/createlink.c... ============================================================================== --- trunk/reactos/dll/cpl/appwiz/createlink.c [iso-8859-1] (original) +++ trunk/reactos/dll/cpl/appwiz/createlink.c [iso-8859-1] Tue Sep 15 00:55:44 2009 @@ -12,13 +12,109 @@
#include "appwiz.h"
+BOOL +IsShortcut(HKEY hKey) +{ + WCHAR Value[10]; + DWORD Size; + DWORD Type; + + Size = sizeof(Value); + if (RegQueryValueExW(hKey, L"IsShortcut", NULL, &Type, (LPBYTE)Value, &Size) != ERROR_SUCCESS) + return FALSE; + + if (Type != REG_SZ) + return FALSE; + + return (wcsicmp(Value, L"yes") == 0); +} + +BOOL +IsExtensionAShortcut(LPWSTR lpExtension) +{ + HKEY hKey; + WCHAR Buffer[100]; + DWORD Size; + DWORD Type; + + if (RegOpenKeyExW(HKEY_CLASSES_ROOT, lpExtension, 0, KEY_READ, &hKey) != ERROR_SUCCESS) + return FALSE; + + if (IsShortcut(hKey)) + { + RegCloseKey(hKey); + return TRUE; + } + + Size = sizeof(Buffer); + if (RegQueryValueEx(hKey, NULL, NULL, &Type, (LPBYTE)Buffer, &Size) != ERROR_SUCCESS || Type != REG_SZ) + { + RegCloseKey(hKey); + return FALSE; + } + + RegCloseKey(hKey); + + if (RegOpenKeyExW(HKEY_CLASSES_ROOT, Buffer, 0, KEY_READ, &hKey) != ERROR_SUCCESS) + return FALSE; + + if (IsShortcut(hKey)) + { + RegCloseKey(hKey); + return TRUE; + } + + RegCloseKey(hKey); + return FALSE; +}
BOOL CreateShortcut(PCREATE_LINK_CONTEXT pContext) { - IShellLinkW *pShellLink; + IShellLinkW *pShellLink, *pSourceShellLink; IPersistFile *pPersistFile; HRESULT hr; + WCHAR Path[MAX_PATH]; + LPWSTR lpExtension; + + /* get the extension */ + lpExtension = wcsrchr(pContext->szTarget, '.'); + + if (IsExtensionAShortcut(lpExtension)) + { + hr = CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_ALL, &IID_IShellLink, (void**)&pSourceShellLink); + + if (hr != S_OK) + return FALSE; + + hr = pSourceShellLink->lpVtbl->QueryInterface(pSourceShellLink, &IID_IPersistFile, (void**)&pPersistFile); + if (hr != S_OK) + { + pSourceShellLink->lpVtbl->Release(pSourceShellLink); + return FALSE; + } + + hr = pPersistFile->lpVtbl->Load(pPersistFile, (LPCOLESTR)pContext->szTarget, STGM_READ); + pPersistFile->lpVtbl->Release(pPersistFile); + + if (hr != S_OK) + { + pSourceShellLink->lpVtbl->Release(pSourceShellLink); + return FALSE; + } + + hr = pSourceShellLink->lpVtbl->GetPath(pSourceShellLink, Path, sizeof(Path) / sizeof(WCHAR), NULL, 0); + pSourceShellLink->lpVtbl->Release(pSourceShellLink); + + if (hr != S_OK) + { + return FALSE; + } + } + else + { + wcscpy(Path, pContext->szTarget); + }
hr = CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_ALL, &IID_IShellLink, (void**)&pShellLink); @@ -27,7 +123,7 @@ return FALSE;
- pShellLink->lpVtbl->SetPath(pShellLink, pContext->szTarget); + pShellLink->lpVtbl->SetPath(pShellLink, Path); pShellLink->lpVtbl->SetDescription(pShellLink, pContext->szDescription); pShellLink->lpVtbl->SetWorkingDirectory(pShellLink, pContext->szWorkingDirectory);