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

Windows Kernel

Development Platform:

Visual C++

  1. /*
  2.  * link - The Rundll that turns off "Shortcut to"
  3.  *
  4.  * This works around a bug in Shell32, where an off-by-one prevented
  5.  * the restore of the setting from working.
  6.  */
  7. #include "tweakui.h"
  8. #pragma BEGIN_CONST_DATA
  9. KL c_klLink = { &g_hkCUSMWCV, c_tszExplorer, c_tszLink };
  10. #pragma END_CONST_DATA
  11. /*****************************************************************************
  12.  *
  13.  *  Link_GetShortcutTo
  14.  *
  15.  *  Determine whether the "Shortcut to" prefix is enabled.
  16.  *
  17.  *****************************************************************************/
  18. BOOL PASCAL
  19. Link_GetShortcutTo(void)
  20. {
  21.     return GetDwordPkl(&c_klLink, 1) > 0;
  22. }
  23. /*****************************************************************************
  24.  *
  25.  *  fCreateNil
  26.  *
  27.  * Create a zero-length file.
  28.  *
  29.  *****************************************************************************/
  30. BOOL PASCAL
  31. fCreateNil(LPCTSTR cqn)
  32. {
  33.     HFILE hf = _lcreat(cqn, 0);
  34.     if (hf != -1) {
  35. _lclose(hf);
  36. return 1;
  37.     } else {
  38. return 0;
  39.     }
  40. }
  41. /*****************************************************************************
  42.  *
  43.  *  Link_Drop -- Create a temp directory, then...
  44.  *  Link_DropCqn -- create a pidl for the directory, then...
  45.  *  Link_DropPidlCqn -- bind to the pidl, then...
  46.  *  Link_DropPsfCqn -- try 20 times to...
  47.  *  Link_RenameToBang -- rename a scratch pidl to "!"
  48.  *
  49.  * (Welcome to lisp.)
  50.  *
  51.  * Keep renaming a file, losing the "Shortcut to", until the shell
  52.  * finally gets the point, or we've tried 20 times and give up.
  53.  * If the shell doesn't get the point after 20 tries, it'll never
  54.  * learn...
  55.  *
  56.  * Returns 0 if we couldn't do it.
  57.  *
  58.  * We do this by creating a temporary directory within the temp
  59.  * directory.  In this temp-temp directory, create a file called
  60.  * "Shortcut to !.lnk", then keep renaming it to "!".
  61.  *
  62.  * By creating it in a brand new temp dir, we are sure we won't
  63.  * conflict with any other files.
  64.  *
  65.  *****************************************************************************/
  66. BOOL PASCAL
  67. Link_RenameToBang(PIDL pidl, LPVOID pv)
  68. {
  69.     PSF psf = pv;
  70.     DeleteFile(c_tszBangLnk); /* So the rename will work */
  71.     return SetNameOfPidl(pv, pidl, c_tszBang);
  72. }
  73. BOOL PASCAL
  74. Link_DropPsfCqn(PSF psf, LPCTSTR cqn)
  75. {
  76.     if (fCreateNil(c_tszBang)) {
  77. BOOL fRc;
  78. TCH tszLinkToBang[MAX_PATH];
  79. if (mit.SHGetNewLinkInfo(c_tszBang, cqn, tszLinkToBang, &fRc,
  80.  SHGNLI_PREFIXNAME)) {
  81.     int iter;
  82.     for (iter = 0; iter < 20 && Link_GetShortcutTo(); iter++) {
  83. fCreateNil(tszLinkToBang);
  84. WithPidl(psf, ptszFilenameCqn(tszLinkToBang),
  85.  Link_RenameToBang, psf);
  86.     }
  87. }
  88.     }
  89.     return !Link_GetShortcutTo();
  90. }
  91. BOOL PASCAL
  92. Link_DropPidlCqn(PIDL pidl, LPVOID cqn)
  93. {
  94.     return WithPsf(psfDesktop, pidl, Link_DropPsfCqn, cqn);
  95. }
  96. BOOL PASCAL
  97. Link_DropCqn(LPCTSTR cqn, LPVOID pv)
  98. {
  99.     return WithPidl(psfDesktop, cqn, Link_DropPidlCqn, (LPVOID)cqn);
  100. }
  101. Link_Drop(void)
  102. {
  103.     return WithTempDirectory(Link_DropCqn, 0);
  104. }
  105. /*****************************************************************************
  106.  *
  107.  *  Link_SetShortcutTo
  108.  *
  109.  * Set or clear the "prepend "Shortcut to" to new shortcuts" flag.
  110.  *
  111.  * If we need to set it, then set the registry key and ask the user
  112.  * to log off and back on.  There is no way to make the count go up.
  113.  *
  114.  * If we need to clear it, then keep renaming "Shortcut to frob" to
  115.  * "frob" until the link count goes to zero.
  116.  *
  117.  * Returns 0 if the user must log off and back on for the change
  118.  * to take effect.
  119.  *
  120.  *****************************************************************************/
  121. BOOL PASCAL
  122. Link_SetShortcutTo(BOOL fPrefix)
  123. {
  124.     if (fPrefix != Link_GetShortcutTo()) {
  125. if (fPrefix) {
  126.     DelPkl(&c_klLink);
  127.     return 0; /* Must log off and back on */
  128. } else { /* Make the count drop to zero */
  129.     if (Link_Drop()) {
  130. return 1;
  131.     } else {
  132. SetDwordPkl(&c_klLink, fPrefix);
  133. /* Oh well */
  134. return 0;
  135.     }
  136. }
  137.     } else {
  138. return 1;
  139.     }
  140. }