Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

239 lines
6.5 KiB

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