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.

486 lines
16 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. // shlwapi!StrCatBuff is not be available in Win95/NT without IE5. Not sure
  100. // if ICW has to run in these environment or not.
  101. //
  102. // return pszDestination. always NULL terminated.
  103. void MyStrCatBuff(
  104. LPTSTR pszDestination, // in/out. null terminated string
  105. LPCTSTR pszSource, // in. null terminated string
  106. int cchDestBuffSize // in. size of pzDestination in TCHAR
  107. )
  108. {
  109. int nDestLen = lstrlen(pszDestination);
  110. int nRemainLen = cchDestBuffSize - nDestLen;
  111. if (nRemainLen > 1)
  112. {
  113. // has room in additional to '\0'
  114. lstrcpyn(&(pszDestination[nDestLen]), pszSource, nRemainLen);
  115. }
  116. }
  117. void GetDesktopDirectory(TCHAR* pszPath)
  118. {
  119. LPITEMIDLIST lpItemDList = NULL;
  120. IMalloc* pMalloc = NULL;
  121. HRESULT hr = E_FAIL;
  122. if(IsNT5()) // Bug 81444 in IE DB
  123. hr = SHGetSpecialFolderLocation(NULL, CSIDL_DESKTOPDIRECTORY, &lpItemDList);
  124. else if (IsNT())
  125. hr = SHGetSpecialFolderLocation(NULL, CSIDL_COMMON_DESKTOPDIRECTORY, &lpItemDList);
  126. else
  127. {
  128. TCHAR pszFolder[MAX_PATH];
  129. *pszFolder = 0;
  130. HRESULT hRet = S_FALSE;
  131. HMODULE hmod = LoadLibrary(TEXT("shfolder.dll"));
  132. PFNSHGETFOLDERPATH pfn = NULL;
  133. if (hmod)
  134. {
  135. pfn = (PFNSHGETFOLDERPATH)GetProcAddress(hmod, "SHGetFolderPathA"); // or W if you are unicode
  136. if (pfn)
  137. {
  138. hRet = pfn(NULL, CSIDL_COMMON_DESKTOPDIRECTORY, NULL, 0, pszFolder);
  139. if (S_OK != hRet)
  140. hRet = pfn(NULL, CSIDL_DESKTOPDIRECTORY, NULL, 0, pszFolder);
  141. if (S_OK == hRet)
  142. lstrcpy(pszPath ,pszFolder);
  143. }
  144. FreeLibrary(hmod);
  145. }
  146. if (S_OK != hRet)
  147. {
  148. FARPROC hShell32VersionProc = NULL;
  149. HMODULE hShell32Mod = (HMODULE)LoadLibrary(TEXT("shell32.dll"));
  150. if (hShell32Mod)
  151. hShell32VersionProc = GetProcAddress(hShell32Mod, "DllGetVersion");
  152. if(hShell32VersionProc)
  153. {
  154. TCHAR szDir [MAX_PATH] = TEXT("\0");
  155. //ok, we're not NT, but we may be multiuser windows.
  156. GetWindowsDirectory(szDir, MAX_PATH);
  157. if (szDir)
  158. {
  159. MyStrCatBuff(szDir, TEXT("\\"), MAX_PATH);
  160. MyStrCatBuff(szDir, g_szAllUsers, MAX_PATH);
  161. TCHAR szTemp [MAX_MESSAGE_LEN] = TEXT("\0");
  162. LoadString(g_hInstance, IDS_DESKTOP, szTemp, MAX_MESSAGE_LEN);
  163. if (szTemp)
  164. {
  165. MyStrCatBuff(szDir, TEXT("\\"), MAX_PATH);
  166. MyStrCatBuff(szDir, szTemp, MAX_PATH);
  167. lstrcpy(pszPath ,szDir);
  168. }
  169. }
  170. }
  171. else
  172. hr = SHGetSpecialFolderLocation(NULL, CSIDL_DESKTOPDIRECTORY, &lpItemDList);
  173. }
  174. }
  175. if (SUCCEEDED(hr))
  176. {
  177. SHGetPathFromIDList(lpItemDList, pszPath);
  178. if (SUCCEEDED(SHGetMalloc (&pMalloc)))
  179. {
  180. pMalloc->Free (lpItemDList);
  181. pMalloc->Release ();
  182. }
  183. }
  184. }
  185. void RemoveDesktopShortCut
  186. (
  187. LPTSTR lpszShortcutName
  188. )
  189. {
  190. TCHAR szShortcutPath[MAX_PATH] = TEXT("\0");
  191. GetDesktopDirectory(szShortcutPath);
  192. if(szShortcutPath[0] != TEXT('\0'))
  193. {
  194. lstrcat(szShortcutPath, TEXT("\\"));
  195. lstrcat(szShortcutPath, lpszShortcutName);
  196. lstrcat(szShortcutPath, TEXT(".LNK"));
  197. DeleteFile(szShortcutPath);
  198. }
  199. }
  200. // This function will add a desktop shortcut
  201. void AddDesktopShortCut
  202. (
  203. LPTSTR lpszAppName,
  204. LPTSTR lpszLinkName
  205. )
  206. {
  207. TCHAR szConnectPath [MAX_PATH] = TEXT("\0");
  208. TCHAR szAppPath [MAX_PATH] = TEXT("\0");
  209. TCHAR szConnectLinkPath [MAX_PATH] = TEXT("\0"); // Path the where the Shortcut file will livE
  210. TCHAR szdrive [_MAX_DRIVE] = TEXT("\0");
  211. TCHAR szdir [_MAX_DIR] = TEXT("\0");
  212. TCHAR szfname [_MAX_FNAME] = TEXT("\0");
  213. TCHAR szext [_MAX_EXT] = TEXT("\0");
  214. TCHAR szRegPath [MAX_PATH] = TEXT("\0");
  215. HRESULT hres = E_FAIL;
  216. IShellLink* psl = NULL;
  217. HKEY hkey = NULL;
  218. // first get the app path
  219. lstrcpy(szRegPath, REGSTR_PATH_APPPATHS);
  220. lstrcat(szRegPath, TEXT("\\"));
  221. lstrcat(szRegPath, lpszAppName);
  222. if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  223. szRegPath,
  224. 0,
  225. IsNT5()? KEY_QUERY_VALUE : KEY_ALL_ACCESS,
  226. &hkey) == ERROR_SUCCESS)
  227. {
  228. DWORD dwTmp = sizeof(szConnectPath);
  229. DWORD dwType = 0;
  230. if(RegQueryValueEx(hkey,
  231. NULL,
  232. NULL,
  233. &dwType,
  234. (LPBYTE) szConnectPath,
  235. &dwTmp) != ERROR_SUCCESS)
  236. {
  237. RegCloseKey(hkey);
  238. return;
  239. }
  240. RegQueryValueEx(hkey,
  241. TEXT("Path"),
  242. NULL,
  243. &dwType,
  244. (LPBYTE) szAppPath,
  245. &dwTmp);
  246. RegCloseKey(hkey);
  247. }
  248. else
  249. {
  250. return;
  251. }
  252. GetDesktopDirectory(szConnectLinkPath);
  253. if(szConnectLinkPath[0] != TEXT('\0'))
  254. {
  255. // Append on the connect EXE name
  256. lstrcat(szConnectLinkPath, TEXT("\\"));
  257. lstrcat(szConnectLinkPath, lpszAppName);
  258. //
  259. int nLastChar = lstrlen(szAppPath)-1;
  260. if ((nLastChar > 0) && (';' == szAppPath[nLastChar]))
  261. szAppPath[nLastChar] = 0;
  262. // Split the path, and the reassemble with the .LNK extension
  263. _tsplitpath( szConnectLinkPath, szdrive, szdir, szfname, szext );
  264. _tmakepath(szConnectLinkPath, szdrive, szdir, lpszLinkName, TEXT(".LNK"));
  265. // Create an IShellLink object and get a pointer to the IShellLink
  266. // interface (returned from CoCreateInstance).
  267. hres = CoCreateInstance (CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
  268. IID_IShellLink, (void **)&psl);
  269. if (SUCCEEDED (hres))
  270. {
  271. IPersistFile *ppf;
  272. // Query IShellLink for the IPersistFile interface for
  273. // saving the shortcut in persistent storage.
  274. hres = psl->QueryInterface (IID_IPersistFile, (void **)&ppf);
  275. if (SUCCEEDED (hres))
  276. {
  277. WORD wsz [MAX_PATH]; // buffer for Unicode string
  278. do
  279. {
  280. // Set the path to the shortcut target.
  281. if (!SUCCEEDED(psl->SetPath (szConnectPath)))
  282. break;
  283. // Set the working dir to the shortcut target.
  284. if (!SUCCEEDED(psl->SetWorkingDirectory (szAppPath)))
  285. break;
  286. // Set the args.
  287. if (!SUCCEEDED(psl->SetArguments (SHORTCUTENTRY_CMD)))
  288. break;
  289. // Set the description of the shortcut.
  290. TCHAR szDescription[MAX_MESSAGE_LEN];
  291. if (!LoadString(g_hInstance, IDS_SHORTCUT_DESC, szDescription, MAX_MESSAGE_LEN))
  292. lstrcpy(szDescription, lpszLinkName);
  293. if (!SUCCEEDED(psl->SetDescription (szDescription)))
  294. break;
  295. // Ensure that the string consists of ANSI TCHARacters.
  296. #ifdef UNICODE
  297. lstrcpy(wsz, szConnectLinkPath);
  298. #else
  299. MultiByteToWideChar (CP_ACP, 0, szConnectLinkPath, -1, wsz, MAX_PATH);
  300. #endif
  301. // Save the shortcut via the IPersistFile::Save member function.
  302. if (!SUCCEEDED(ppf->Save (wsz, TRUE)))
  303. break;
  304. // Release the pointer to IPersistFile.
  305. ppf->Release ();
  306. break;
  307. } while (1);
  308. }
  309. // Release the pointer to IShellLink.
  310. psl->Release ();
  311. }
  312. }
  313. }
  314. // This function will apply the appropriate desktop changes based on the following
  315. // algorithm. This code below assumes that the machine is NOT internet capable.
  316. // If the machine was upgraded from a previous OS, then
  317. // Add the connect to the internet ICON
  318. // ELSE (clean install or OEM pre install)
  319. // Add the connect to the internet ICON
  320. //
  321. void DoDesktopChanges
  322. (
  323. HINSTANCE hAppInst
  324. )
  325. {
  326. TCHAR szAppName[MAX_PATH];
  327. TCHAR szLinkName[MAX_PATH];
  328. HKEY hkey;
  329. if (!LoadString(hAppInst, IDS_CONNECT_FNAME, szAppName, ARRAYSIZE(szAppName)))
  330. lstrcpy(szAppName, g_szConnectApp);
  331. if (!LoadString(hAppInst, IDS_CONNECT_DESKTOP_TITLE, szLinkName, ARRAYSIZE(szLinkName)))
  332. lstrcpy(szLinkName, g_szConnectLink);
  333. // We always add the connect shortcut
  334. AddDesktopShortCut(szAppName, szLinkName);
  335. // Set a registry value indicating that we messed with the desktop
  336. DWORD dwDisposition;
  337. if (ERROR_SUCCESS == RegCreateKeyEx(HKEY_CURRENT_USER,
  338. ICWSETTINGSPATH,
  339. 0,
  340. NULL,
  341. REG_OPTION_NON_VOLATILE,
  342. KEY_ALL_ACCESS,
  343. NULL,
  344. &hkey,
  345. &dwDisposition))
  346. {
  347. DWORD dwDesktopChanged = 1;
  348. RegSetValueEx(hkey,
  349. ICWDESKTOPCHANGED,
  350. 0,
  351. REG_DWORD,
  352. (LPBYTE)&dwDesktopChanged,
  353. sizeof(DWORD));
  354. RegCloseKey(hkey);
  355. }
  356. }
  357. // This undoes what DoDesktopChanges did
  358. void UndoDesktopChanges
  359. (
  360. HINSTANCE hAppInst
  361. )
  362. {
  363. TCHAR szConnectTotheInternetTitle[MAX_PATH];
  364. HKEY hkey;
  365. // Verify that we really changed the desktop
  366. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER,
  367. ICWSETTINGSPATH,
  368. 0,
  369. KEY_ALL_ACCESS,
  370. &hkey))
  371. {
  372. DWORD dwDesktopChanged = 0;
  373. DWORD dwTmp = sizeof(DWORD);
  374. DWORD dwType = 0;
  375. RegQueryValueEx(hkey,
  376. ICWDESKTOPCHANGED,
  377. NULL,
  378. &dwType,
  379. (LPBYTE)&dwDesktopChanged,
  380. &dwTmp);
  381. RegCloseKey(hkey);
  382. // Bail if the desktop was not changed by us
  383. if(!dwDesktopChanged)
  384. return;
  385. }
  386. // Always nuke the Connect to the internet icon
  387. if (!LoadString(hAppInst,
  388. IDS_CONNECT_DESKTOP_TITLE,
  389. szConnectTotheInternetTitle,
  390. ARRAYSIZE(szConnectTotheInternetTitle)))
  391. {
  392. lstrcpy(szConnectTotheInternetTitle, g_szConnectLink);
  393. }
  394. RemoveDesktopShortCut(szConnectTotheInternetTitle);
  395. }
  396. void UpdateDesktop
  397. (
  398. HINSTANCE hAppInst
  399. )
  400. {
  401. if(MyIsSmartStartEx(NULL, 0))
  402. {
  403. // VYUNG NT5 bug See if IEAK wants to stop GETCONN icon creation
  404. //if (!SHGetRestriction(NULL, TEXT("Internet Connection Wizard"), TEXT("NoICWIcon")))
  405. // CHUNHOC NT5.1 bug Don't create icon at desktop in any case.
  406. /*
  407. if (!SHGetRestriction(NULL, L"Internet Connection Wizard", L"NoICWIcon"))
  408. DoDesktopChanges(hAppInst);
  409. */
  410. }
  411. else
  412. {
  413. // We are internet ready, so set the appropriate Welcome show bit
  414. // and replace the IE and OE links
  415. UpdateWelcomeRegSetting(TRUE);
  416. }
  417. }