link.c
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 7k
Category:

Windows Kernel

Development Platform:

Visual C++

  1. //
  2. //  Link.C
  3. //
  4. //  Copyright (C) Microsoft, 1994,1995 All Rights Reserved.
  5. //
  6. //  History:
  7. //  ral 6/23/94 - First pass
  8. //  3/20/95  [stevecat] - NT port & real clean up, unicode, etc.
  9. //
  10. //
  11. #include "priv.h"
  12. #include "appwiz.h"
  13. const static TCHAR szExplorer[] = TEXT("Explorer");
  14. const static TCHAR szExpSelParams[] = TEXT("/Select,");
  15. //
  16. //  Returns the fully-qualified path name of the link.
  17. //
  18. BOOL GetLinkName(LPTSTR lpszLinkName, LPWIZDATA lpwd)
  19. {
  20.     if( PathCombine(lpszLinkName, lpwd->lpszFolder, lpwd->szProgDesc) == NULL )
  21.         return( FALSE );
  22. #ifdef NO_NEW_SHORTCUT_HOOK
  23.     lstrcat(lpszLinkName, (lpwd->dwFlags & WDFLAG_DOSAPP) ? c_szPIF : c_szLNK);
  24. #else
  25.     if ((lstrlen(lpszLinkName) + lstrlen(lpwd->szExt)) >= MAX_PATH)
  26.         return FALSE;
  27.     lstrcat(lpszLinkName, lpwd->szExt);
  28. #endif
  29.     return( TRUE );
  30. }
  31. //
  32. //  Opens the folder of the newly created link.
  33. //
  34. // BUGBUG -- Need to select the item we just created!!!
  35. //  SET ei.lpParameters =- lpwd->szExeName;
  36. //
  37. BOOL OpenLinkFolder(LPWIZDATA lpwd, LPTSTR lpszLinkName)
  38. {
  39.     SHELLEXECUTEINFO ei;
  40.     TCHAR szParams[MAX_PATH];
  41.     lstrcpy(szParams, szExpSelParams);
  42.     lstrcat(szParams, lpszLinkName);
  43.     ei.cbSize = sizeof(ei);
  44.     ei.hwnd = lpwd->hwnd;
  45.     ei.fMask = 0;
  46.     ei.lpVerb = NULL;
  47.     ei.lpFile = szExplorer;
  48.     ei.lpParameters = szParams;
  49.     ei.lpDirectory = NULL;
  50.     ei.lpClass = NULL;
  51.     ei.nShow = SW_SHOWDEFAULT;
  52.     ei.hInstApp = g_hinst;
  53.     return(ShellExecuteEx(&ei));
  54. }
  55. //
  56. //  Cretates a link.
  57. //
  58. BOOL CreateLink(LPWIZDATA lpwd)
  59. {
  60.     BOOL          bWorked = FALSE;
  61.     IShellLink   *psl;
  62.     HCURSOR       hcurOld = SetCursor(LoadCursor(NULL, IDC_WAIT));
  63.     IPersistFile *ppf;
  64.     TCHAR         szLinkName[MAX_PATH];
  65.     WCHAR         wszPath[MAX_PATH];
  66.     GetLinkName(szLinkName, lpwd);
  67.     if (lpwd->lpszOriginalName)
  68.     {
  69.         if (PathFileExists(szLinkName))
  70.         {
  71.             DeleteFile(lpwd->lpszOriginalName);
  72.             SHChangeNotify(SHCNE_DELETE, SHCNF_FLUSH | SHCNF_PATH,
  73.                         lpwd->lpszOriginalName, NULL);
  74.         }
  75.         else
  76.         {
  77.             // we use full pidls here since simple net pidls fail to compare to full net pidls,
  78.             // and thus the changenotify will never make it to the client and it will not update.
  79.             LPITEMIDLIST pidlOriginal = ILCreateFromPath(lpwd->lpszOriginalName);   // need to do this before the move!
  80.             LPITEMIDLIST pidlLink = NULL;
  81.             if (MoveFile(lpwd->lpszOriginalName, szLinkName))
  82.             {
  83.                 pidlLink = ILCreateFromPath(szLinkName);    // need to do this after the move (or it won't exist)!
  84.                 if (pidlOriginal && pidlLink)
  85.                 {
  86.                     SHChangeNotify(SHCNE_RENAMEITEM, SHCNF_FLUSH | SHCNF_IDLIST, pidlOriginal, pidlLink);
  87.                 }
  88.                 else
  89.                 {
  90.                     WIZERROR(TEXT("Unable to generate pidls for rename notify"));
  91.                     SHChangeNotify(SHCNE_RENAMEITEM, SHCNF_FLUSH | SHCNF_PATH, lpwd->lpszOriginalName, szLinkName);
  92.                 }
  93.             }
  94.             else
  95.             {
  96.                 WIZERROR(TEXT("Unable to rename link -- Will end up with two"));
  97.                 WIZERROR(szLinkName);
  98.             }
  99.             
  100.             if (pidlOriginal)
  101.                 ILFree(pidlOriginal);
  102.             if (pidlLink)
  103.                 ILFree(pidlLink);
  104.         }
  105.         //
  106.         // Now get rid of this in case we fail later and then re-enter
  107.         // this routine later.
  108.         //
  109.         lpwd->lpszOriginalName = NULL;
  110.     }
  111.     //
  112.     //    If we're just supposed to copy it, it's simple!
  113.     //
  114.     if (lpwd->dwFlags & WDFLAG_COPYLINK)
  115.     {
  116.         bWorked = CopyFile(lpwd->szExeName, szLinkName, FALSE);
  117.         goto ExitNoFree;
  118.     }
  119. #ifndef NO_NEW_SHORTCUT_HOOK
  120.     if (lpwd->pnshhk)
  121.     {
  122.         //
  123.         // The object is ready to be saved to a file.
  124.         //
  125.         if (FAILED(lpwd->pnshhk->lpVtbl->QueryInterface(lpwd->pnshhk, &IID_IPersistFile, &ppf)))
  126.             goto ExitFreePSL;
  127.     }
  128.     else
  129. #ifdef UNICODE
  130.         if (lpwd->pnshhkA)
  131.         {
  132.             //
  133.             // The object is ready to be saved to a file.
  134.             //
  135.             if (FAILED(lpwd->pnshhkA->lpVtbl->QueryInterface(lpwd->pnshhkA, &IID_IPersistFile, &ppf)))
  136.                 goto ExitFreePSL;
  137.         }
  138.         else
  139. #endif
  140.     {
  141. #endif
  142.         //
  143.         //    We didn't do a simple copy.  Now do the full-blown create.
  144.         //
  145.         if (FAILED(CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, &IID_IShellLink, (void **)&psl)))
  146.         {
  147.             WIZERROR(TEXT("Could not create instance of IShellLink"));
  148.             goto ExitNoFree;
  149.         }
  150.         if (FAILED(psl->lpVtbl->QueryInterface(psl, &IID_IPersistFile, &ppf)))
  151.         {
  152.             goto ExitFreePSL;
  153.         }
  154.         psl->lpVtbl->SetPath(psl, lpwd->szExeName);
  155.         psl->lpVtbl->SetArguments(psl, lpwd->szParams);
  156.         psl->lpVtbl->SetWorkingDirectory(psl, lpwd->szWorkingDir);
  157.         if (lpwd->dwFlags & WDFLAG_DOSAPP)
  158.         {
  159. #ifdef UNICODE
  160.             MultiByteToWideChar(CP_ACP, 0, lpwd->PropPrg.achIconFile, -1, wszPath, ARRAYSIZE(wszPath));
  161.             psl->lpVtbl->SetIconLocation(psl, wszPath, (int)(lpwd->PropPrg.wIconIndex));
  162. #else
  163.             psl->lpVtbl->SetIconLocation(psl, lpwd->PropPrg.achIconFile, (int)(lpwd->PropPrg.wIconIndex));
  164. #endif  //  UNICODE
  165.         }
  166. #ifndef NO_NEW_SHORTCUT_HOOK
  167.     }
  168. #endif
  169. #ifdef UNICODE
  170.     bWorked = SUCCEEDED(ppf->lpVtbl->Save(ppf, szLinkName, TRUE));
  171. #else
  172.     if (MultiByteToWideChar(CP_ACP, 0, szLinkName, -1, wszPath, ARRAYSIZE(wszPath)))
  173.     {
  174.         bWorked = SUCCEEDED(ppf->lpVtbl->Save(ppf, wszPath, TRUE));
  175.     }
  176. #endif  //  UNICODE
  177.     ppf->lpVtbl->Release(ppf);
  178. ExitFreePSL:
  179. #ifndef NO_NEW_SHORTCUT_HOOK
  180.     if (lpwd->pnshhk)
  181.     {
  182.         lpwd->pnshhk->lpVtbl->Release(lpwd->pnshhk);
  183.         lpwd->pnshhk = NULL;
  184.     }
  185.     else
  186. #ifdef UNICODE
  187.           if (lpwd->pnshhkA)
  188.           {
  189.               lpwd->pnshhkA->lpVtbl->Release(lpwd->pnshhkA);
  190.               lpwd->pnshhkA = NULL;
  191.           }
  192.           else
  193. #endif
  194. #endif
  195.         psl->lpVtbl->Release(psl);
  196. ExitNoFree:
  197.     if (bWorked)
  198.     {
  199.         SHChangeNotify(SHCNE_UPDATEITEM, SHCNF_FLUSH | SHCNF_PATH,
  200.                        szLinkName, NULL);
  201.     }
  202.     SetCursor(hcurOld);
  203.     if (bWorked)
  204.     {
  205.         if (!(lpwd->dwFlags & WDFLAG_DONTOPENFLDR))
  206.         {
  207.             OpenLinkFolder(lpwd, szLinkName);
  208.         }
  209.     }
  210.     else
  211.     {
  212.         ShellMessageBox(g_hinst, lpwd->hwnd, MAKEINTRESOURCE(IDS_NOSHORTCUT),
  213.                         0, MB_OK | MB_ICONEXCLAMATION);
  214.     }
  215.     return(bWorked);
  216. }