Source code of Windows XP (NT5)
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.

466 lines
15 KiB

  1. //**********************************************************************
  2. // File name: desktop.cpp
  3. //
  4. // Desktop manipulation functions
  5. //
  6. // Functions:
  7. //
  8. // Copyright (c) 1992 - 1998 Microsoft Corporation. All rights reserved.
  9. //**********************************************************************
  10. #include "pre.h"
  11. #include "regstr.h"
  12. #include "inetreg.h"
  13. #include <shlobj.h>
  14. #include <shfolder.h> // latest platform SDK has this
  15. #define MAX_USER_NAME 255
  16. #define REGSTR_PATH_SETUPKEY REGSTR_PATH_SETUP REGSTR_KEY_SETUP
  17. #define REGSTR_PATH_IEONDESKTOP REGSTR_PATH_IEXPLORER TEXT("\\AdvancedOptions\\BROWSE\\IEONDESKTOP")
  18. #define InternetConnectionWiz "Internet Connection Wizard"
  19. #define NOICWICON "NoICWIcon"
  20. static const TCHAR g_szRegPathWelcomeICW[] = TEXT("Welcome\\ICW");
  21. static const TCHAR g_szAllUsers[] = TEXT("All Users");
  22. static const TCHAR g_szConnectApp[] = TEXT("ICWCONN1.EXE");
  23. static const TCHAR g_szConnectLink[] = TEXT("Connect to the Internet");
  24. static const TCHAR g_szOEApp[] = TEXT("MSINM.EXE");
  25. static const TCHAR g_szOELink[] = TEXT("Outlook Express");
  26. static const TCHAR g_szRegPathICWSettings[] = TEXT("Software\\Microsoft\\Internet Connection Wizard");
  27. static const TCHAR g_szRegValICWCompleted[] = TEXT("Completed");
  28. static const TCHAR g_szRegValNoIcon[] = TEXT("NoIcon");
  29. extern BOOL MyIsSmartStartEx(LPTSTR lpszConnectionName, DWORD dwBufLen);
  30. extern BOOL IsNT();
  31. extern BOOL IsNT5();
  32. void QuickCompleteSignup()
  33. {
  34. // Set the welcome state
  35. UpdateWelcomeRegSetting(TRUE);
  36. // Restore the desktop
  37. UndoDesktopChanges(g_hInstance);
  38. // Mark the ICW as being complete
  39. SetICWComplete();
  40. }
  41. void UpdateWelcomeRegSetting
  42. (
  43. BOOL bSetBit
  44. )
  45. {
  46. HKEY hkey;
  47. HKEY hkeyCurVer;
  48. DWORD dwValue = bSetBit;
  49. if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  50. REGSTR_PATH_SETUP, // ...\Windows\CurrentVersion
  51. 0,
  52. KEY_ALL_ACCESS,
  53. &hkeyCurVer) == ERROR_SUCCESS)
  54. {
  55. DWORD dwDisposition;
  56. if (ERROR_SUCCESS == RegCreateKeyEx(hkeyCurVer,
  57. g_szRegPathWelcomeICW,
  58. 0,
  59. NULL,
  60. REG_OPTION_NON_VOLATILE,
  61. KEY_ALL_ACCESS,
  62. NULL,
  63. &hkey,
  64. &dwDisposition))
  65. {
  66. RegSetValueEx(hkey,
  67. TEXT("@"),
  68. 0,
  69. REG_DWORD,
  70. (LPBYTE) &dwValue,
  71. sizeof(DWORD));
  72. RegCloseKey(hkey);
  73. }
  74. RegCloseKey(hkeyCurVer);
  75. }
  76. }
  77. BOOL GetCompletedBit( )
  78. {
  79. HKEY hkey;
  80. DWORD dwValue;
  81. DWORD dwRet = ERROR_GEN_FAILURE;
  82. DWORD dwType = REG_DWORD;
  83. BOOL bBit = FALSE;
  84. if (RegOpenKeyEx(HKEY_CURRENT_USER,
  85. g_szRegPathICWSettings, // ...Software\\Microsoft\\Internet Connection Wizard
  86. 0,
  87. KEY_ALL_ACCESS,
  88. &hkey) == ERROR_SUCCESS)
  89. {
  90. DWORD dwDataSize = sizeof (dwValue);
  91. if (ERROR_SUCCESS == RegQueryValueEx(hkey, g_szRegValICWCompleted, NULL, &dwType, (LPBYTE) &dwValue, &dwDataSize))
  92. {
  93. bBit = (1 == dwValue);
  94. }
  95. RegCloseKey(hkey);
  96. }
  97. return bBit;
  98. }
  99. void GetDesktopDirectory(TCHAR* pszPath)
  100. {
  101. LPITEMIDLIST lpItemDList = NULL;
  102. IMalloc* pMalloc = NULL;
  103. HRESULT hr = E_FAIL;
  104. if(IsNT5()) // Bug 81444 in IE DB
  105. hr = SHGetSpecialFolderLocation(NULL, CSIDL_DESKTOPDIRECTORY, &lpItemDList);
  106. else if (IsNT())
  107. hr = SHGetSpecialFolderLocation(NULL, CSIDL_COMMON_DESKTOPDIRECTORY, &lpItemDList);
  108. else
  109. {
  110. TCHAR pszFolder[MAX_PATH];
  111. *pszFolder = 0;
  112. HRESULT hRet = S_FALSE;
  113. HMODULE hmod = LoadLibrary(TEXT("shfolder.dll"));
  114. PFNSHGETFOLDERPATH pfn = NULL;
  115. if (hmod)
  116. {
  117. pfn = (PFNSHGETFOLDERPATH)GetProcAddress(hmod, "SHGetFolderPathA"); // or W if you are unicode
  118. if (pfn)
  119. {
  120. hRet = pfn(NULL, CSIDL_COMMON_DESKTOPDIRECTORY, NULL, 0, pszFolder);
  121. if (S_OK != hRet)
  122. hRet = pfn(NULL, CSIDL_DESKTOPDIRECTORY, NULL, 0, pszFolder);
  123. if (S_OK == hRet)
  124. lstrcpy(pszPath ,pszFolder);
  125. }
  126. FreeLibrary(hmod);
  127. }
  128. if (S_OK != hRet)
  129. {
  130. FARPROC hShell32VersionProc = NULL;
  131. HMODULE hShell32Mod = (HMODULE)LoadLibrary(TEXT("shell32.dll"));
  132. if (hShell32Mod)
  133. hShell32VersionProc = GetProcAddress(hShell32Mod, "DllGetVersion");
  134. if(hShell32VersionProc)
  135. {
  136. TCHAR szDir [MAX_PATH] = TEXT("\0");
  137. //ok, we're not NT, but we may be multiuser windows.
  138. GetWindowsDirectory(szDir, MAX_PATH);
  139. if (szDir)
  140. {
  141. lstrcat(szDir, TEXT("\\"));
  142. lstrcat(szDir, g_szAllUsers);
  143. TCHAR szTemp [MAX_MESSAGE_LEN] = TEXT("\0");
  144. LoadString(g_hInstance, IDS_DESKTOP, szTemp, MAX_MESSAGE_LEN);
  145. if (szTemp)
  146. {
  147. lstrcat(szDir, TEXT("\\"));
  148. lstrcat(szDir, szTemp);
  149. lstrcpy(pszPath ,szDir);
  150. }
  151. }
  152. }
  153. else
  154. hr = SHGetSpecialFolderLocation(NULL, CSIDL_DESKTOPDIRECTORY, &lpItemDList);
  155. }
  156. }
  157. if (SUCCEEDED(hr))
  158. {
  159. SHGetPathFromIDList(lpItemDList, pszPath);
  160. if (SUCCEEDED(SHGetMalloc (&pMalloc)))
  161. {
  162. pMalloc->Free (lpItemDList);
  163. pMalloc->Release ();
  164. }
  165. }
  166. }
  167. void RemoveDesktopShortCut
  168. (
  169. LPTSTR lpszShortcutName
  170. )
  171. {
  172. TCHAR szShortcutPath[MAX_PATH] = TEXT("\0");
  173. GetDesktopDirectory(szShortcutPath);
  174. if(szShortcutPath[0] != TEXT('\0'))
  175. {
  176. lstrcat(szShortcutPath, TEXT("\\"));
  177. lstrcat(szShortcutPath, lpszShortcutName);
  178. lstrcat(szShortcutPath, TEXT(".LNK"));
  179. DeleteFile(szShortcutPath);
  180. }
  181. }
  182. // This function will add a desktop shortcut
  183. void AddDesktopShortCut
  184. (
  185. LPTSTR lpszAppName,
  186. LPTSTR lpszLinkName
  187. )
  188. {
  189. TCHAR szConnectPath [MAX_PATH] = TEXT("\0");
  190. TCHAR szAppPath [MAX_PATH] = TEXT("\0");
  191. TCHAR szConnectLinkPath [MAX_PATH] = TEXT("\0"); // Path the where the Shortcut file will livE
  192. TCHAR szdrive [_MAX_DRIVE] = TEXT("\0");
  193. TCHAR szdir [_MAX_DIR] = TEXT("\0");
  194. TCHAR szfname [_MAX_FNAME] = TEXT("\0");
  195. TCHAR szext [_MAX_EXT] = TEXT("\0");
  196. TCHAR szRegPath [MAX_PATH] = TEXT("\0");
  197. HRESULT hres = E_FAIL;
  198. IShellLink* psl = NULL;
  199. HKEY hkey = NULL;
  200. // first get the app path
  201. lstrcpy(szRegPath, REGSTR_PATH_APPPATHS);
  202. lstrcat(szRegPath, TEXT("\\"));
  203. lstrcat(szRegPath, lpszAppName);
  204. if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  205. szRegPath,
  206. 0,
  207. IsNT5()? KEY_QUERY_VALUE : KEY_ALL_ACCESS,
  208. &hkey) == ERROR_SUCCESS)
  209. {
  210. DWORD dwTmp = sizeof(szConnectPath);
  211. DWORD dwType = 0;
  212. if(RegQueryValueEx(hkey,
  213. NULL,
  214. NULL,
  215. &dwType,
  216. (LPBYTE) szConnectPath,
  217. &dwTmp) != ERROR_SUCCESS)
  218. {
  219. RegCloseKey(hkey);
  220. return;
  221. }
  222. RegQueryValueEx(hkey,
  223. TEXT("Path"),
  224. NULL,
  225. &dwType,
  226. (LPBYTE) szAppPath,
  227. &dwTmp);
  228. RegCloseKey(hkey);
  229. }
  230. else
  231. {
  232. return;
  233. }
  234. GetDesktopDirectory(szConnectLinkPath);
  235. if(szConnectLinkPath[0] != TEXT('\0'))
  236. {
  237. // Append on the connect EXE name
  238. lstrcat(szConnectLinkPath, TEXT("\\"));
  239. lstrcat(szConnectLinkPath, lpszAppName);
  240. //
  241. int nLastChar = lstrlen(szAppPath)-1;
  242. if ((nLastChar > 0) && (';' == szAppPath[nLastChar]))
  243. szAppPath[nLastChar] = 0;
  244. // Split the path, and the reassemble with the .LNK extension
  245. _tsplitpath( szConnectLinkPath, szdrive, szdir, szfname, szext );
  246. _tmakepath(szConnectLinkPath, szdrive, szdir, lpszLinkName, TEXT(".LNK"));
  247. // Create an IShellLink object and get a pointer to the IShellLink
  248. // interface (returned from CoCreateInstance).
  249. hres = CoCreateInstance (CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
  250. IID_IShellLink, (void **)&psl);
  251. if (SUCCEEDED (hres))
  252. {
  253. IPersistFile *ppf;
  254. // Query IShellLink for the IPersistFile interface for
  255. // saving the shortcut in persistent storage.
  256. hres = psl->QueryInterface (IID_IPersistFile, (void **)&ppf);
  257. if (SUCCEEDED (hres))
  258. {
  259. WORD wsz [MAX_PATH]; // buffer for Unicode string
  260. do
  261. {
  262. // Set the path to the shortcut target.
  263. if (!SUCCEEDED(psl->SetPath (szConnectPath)))
  264. break;
  265. // Set the working dir to the shortcut target.
  266. if (!SUCCEEDED(psl->SetWorkingDirectory (szAppPath)))
  267. break;
  268. // Set the args.
  269. if (!SUCCEEDED(psl->SetArguments (SHORTCUTENTRY_CMD)))
  270. break;
  271. // Set the description of the shortcut.
  272. TCHAR szDescription[MAX_MESSAGE_LEN];
  273. if (!LoadString(g_hInstance, IDS_SHORTCUT_DESC, szDescription, MAX_MESSAGE_LEN))
  274. lstrcpy(szDescription, lpszLinkName);
  275. if (!SUCCEEDED(psl->SetDescription (szDescription)))
  276. break;
  277. // Ensure that the string consists of ANSI TCHARacters.
  278. #ifdef UNICODE
  279. lstrcpy(wsz, szConnectLinkPath);
  280. #else
  281. MultiByteToWideChar (CP_ACP, 0, szConnectLinkPath, -1, wsz, MAX_PATH);
  282. #endif
  283. // Save the shortcut via the IPersistFile::Save member function.
  284. if (!SUCCEEDED(ppf->Save (wsz, TRUE)))
  285. break;
  286. // Release the pointer to IPersistFile.
  287. ppf->Release ();
  288. break;
  289. } while (1);
  290. }
  291. // Release the pointer to IShellLink.
  292. psl->Release ();
  293. }
  294. }
  295. }
  296. // This function will apply the appropriate desktop changes based on the following
  297. // algorithm. This code below assumes that the machine is NOT internet capable.
  298. // If the machine was upgraded from a previous OS, then
  299. // Add the connect to the internet ICON
  300. // ELSE (clean install or OEM pre install)
  301. // Add the connect to the internet ICON
  302. //
  303. void DoDesktopChanges
  304. (
  305. HINSTANCE hAppInst
  306. )
  307. {
  308. TCHAR szAppName[MAX_PATH];
  309. TCHAR szLinkName[MAX_PATH];
  310. HKEY hkey;
  311. if (!LoadString(hAppInst, IDS_CONNECT_FNAME, szAppName, sizeof(szAppName)))
  312. lstrcpy(szAppName, g_szConnectApp);
  313. if (!LoadString(hAppInst, IDS_CONNECT_DESKTOP_TITLE, szLinkName, sizeof(szLinkName)))
  314. lstrcpy(szLinkName, g_szConnectLink);
  315. // We always add the connect shortcut
  316. AddDesktopShortCut(szAppName, szLinkName);
  317. // Set a registry value indicating that we messed with the desktop
  318. DWORD dwDisposition;
  319. if (ERROR_SUCCESS == RegCreateKeyEx(HKEY_CURRENT_USER,
  320. ICWSETTINGSPATH,
  321. 0,
  322. NULL,
  323. REG_OPTION_NON_VOLATILE,
  324. KEY_ALL_ACCESS,
  325. NULL,
  326. &hkey,
  327. &dwDisposition))
  328. {
  329. DWORD dwDesktopChanged = 1;
  330. RegSetValueEx(hkey,
  331. ICWDESKTOPCHANGED,
  332. 0,
  333. REG_DWORD,
  334. (LPBYTE)&dwDesktopChanged,
  335. sizeof(DWORD));
  336. RegCloseKey(hkey);
  337. }
  338. }
  339. // This undoes what DoDesktopChanges did
  340. void UndoDesktopChanges
  341. (
  342. HINSTANCE hAppInst
  343. )
  344. {
  345. TCHAR szConnectTotheInternetTitle[MAX_PATH];
  346. HKEY hkey;
  347. // Verify that we really changed the desktop
  348. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER,
  349. ICWSETTINGSPATH,
  350. 0,
  351. KEY_ALL_ACCESS,
  352. &hkey))
  353. {
  354. DWORD dwDesktopChanged = 0;
  355. DWORD dwTmp = sizeof(DWORD);
  356. DWORD dwType = 0;
  357. RegQueryValueEx(hkey,
  358. ICWDESKTOPCHANGED,
  359. NULL,
  360. &dwType,
  361. (LPBYTE)&dwDesktopChanged,
  362. &dwTmp);
  363. RegCloseKey(hkey);
  364. // Bail if the desktop was not changed by us
  365. if(!dwDesktopChanged)
  366. return;
  367. }
  368. // Always nuke the Connect to the internet icon
  369. if (!LoadString(hAppInst,
  370. IDS_CONNECT_DESKTOP_TITLE,
  371. szConnectTotheInternetTitle,
  372. sizeof(szConnectTotheInternetTitle)))
  373. {
  374. lstrcpy(szConnectTotheInternetTitle, g_szConnectLink);
  375. }
  376. RemoveDesktopShortCut(szConnectTotheInternetTitle);
  377. }
  378. void UpdateDesktop
  379. (
  380. HINSTANCE hAppInst
  381. )
  382. {
  383. if(MyIsSmartStartEx(NULL, 0))
  384. {
  385. // VYUNG NT5 bug See if IEAK wants to stop GETCONN icon creation
  386. //if (!SHGetRestriction(NULL, TEXT("Internet Connection Wizard"), TEXT("NoICWIcon")))
  387. // CHUNHOC NT5.1 bug Don't create icon at desktop in any case.
  388. /*
  389. if (!SHGetRestriction(NULL, L"Internet Connection Wizard", L"NoICWIcon"))
  390. DoDesktopChanges(hAppInst);
  391. */
  392. }
  393. else
  394. {
  395. // We are internet ready, so set the appropriate Welcome show bit
  396. // and replace the IE and OE links
  397. UpdateWelcomeRegSetting(TRUE);
  398. }
  399. }