|
|
//**********************************************************************
// File name: desktop.cpp
//
// Desktop manipulation functions
//
// Functions:
//
// Copyright (c) 1992 - 1998 Microsoft Corporation. All rights reserved.
//**********************************************************************
#include "pre.h"
#include "regstr.h"
#include "inetreg.h"
#include <shlobj.h>
#include <shfolder.h> // latest platform SDK has this
#define MAX_USER_NAME 255
#define REGSTR_PATH_SETUPKEY REGSTR_PATH_SETUP REGSTR_KEY_SETUP
#define REGSTR_PATH_IEONDESKTOP REGSTR_PATH_IEXPLORER TEXT("\\AdvancedOptions\\BROWSE\\IEONDESKTOP")
#define InternetConnectionWiz "Internet Connection Wizard"
#define NOICWICON "NoICWIcon"
static const TCHAR g_szRegPathWelcomeICW[] = TEXT("Welcome\\ICW"); static const TCHAR g_szAllUsers[] = TEXT("All Users"); static const TCHAR g_szConnectApp[] = TEXT("ICWCONN1.EXE"); static const TCHAR g_szConnectLink[] = TEXT("Connect to the Internet"); static const TCHAR g_szOEApp[] = TEXT("MSINM.EXE"); static const TCHAR g_szOELink[] = TEXT("Outlook Express"); static const TCHAR g_szRegPathICWSettings[] = TEXT("Software\\Microsoft\\Internet Connection Wizard"); static const TCHAR g_szRegValICWCompleted[] = TEXT("Completed"); static const TCHAR g_szRegValNoIcon[] = TEXT("NoIcon");
extern BOOL MyIsSmartStartEx(LPTSTR lpszConnectionName, DWORD dwBufLen); extern BOOL IsNT(); extern BOOL IsNT5();
void QuickCompleteSignup() { // Set the welcome state
UpdateWelcomeRegSetting(TRUE);
// Restore the desktop
UndoDesktopChanges(g_hInstance);
// Mark the ICW as being complete
SetICWComplete(); }
void UpdateWelcomeRegSetting ( BOOL bSetBit ) { HKEY hkey; HKEY hkeyCurVer; DWORD dwValue = bSetBit; if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, REGSTR_PATH_SETUP, // ...\Windows\CurrentVersion
0, KEY_ALL_ACCESS, &hkeyCurVer) == ERROR_SUCCESS) { DWORD dwDisposition; if (ERROR_SUCCESS == RegCreateKeyEx(hkeyCurVer, g_szRegPathWelcomeICW, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, &dwDisposition)) { RegSetValueEx(hkey, TEXT("@"), 0, REG_DWORD, (LPBYTE) &dwValue, sizeof(DWORD));
RegCloseKey(hkey); } RegCloseKey(hkeyCurVer); } }
BOOL GetCompletedBit( ) { HKEY hkey; DWORD dwValue; DWORD dwRet = ERROR_GEN_FAILURE; DWORD dwType = REG_DWORD; BOOL bBit = FALSE;
if (RegOpenKeyEx(HKEY_CURRENT_USER, g_szRegPathICWSettings, // ...Software\\Microsoft\\Internet Connection Wizard
0, KEY_ALL_ACCESS, &hkey) == ERROR_SUCCESS) { DWORD dwDataSize = sizeof (dwValue); if (ERROR_SUCCESS == RegQueryValueEx(hkey, g_szRegValICWCompleted, NULL, &dwType, (LPBYTE) &dwValue, &dwDataSize)) { bBit = (1 == dwValue); } RegCloseKey(hkey); } return bBit; }
// shlwapi!StrCatBuff is not be available in Win95/NT without IE5. Not sure
// if ICW has to run in these environment or not.
//
// return pszDestination. always NULL terminated.
void MyStrCatBuff( LPTSTR pszDestination, // in/out. null terminated string
LPCTSTR pszSource, // in. null terminated string
int cchDestBuffSize // in. size of pzDestination in TCHAR
) { int nDestLen = lstrlen(pszDestination); int nRemainLen = cchDestBuffSize - nDestLen;
if (nRemainLen > 1) { // has room in additional to '\0'
lstrcpyn(&(pszDestination[nDestLen]), pszSource, nRemainLen); } }
void GetDesktopDirectory(TCHAR* pszPath) { LPITEMIDLIST lpItemDList = NULL; IMalloc* pMalloc = NULL; HRESULT hr = E_FAIL; if(IsNT5()) // Bug 81444 in IE DB
hr = SHGetSpecialFolderLocation(NULL, CSIDL_DESKTOPDIRECTORY, &lpItemDList); else if (IsNT()) hr = SHGetSpecialFolderLocation(NULL, CSIDL_COMMON_DESKTOPDIRECTORY, &lpItemDList); else {
TCHAR pszFolder[MAX_PATH]; *pszFolder = 0; HRESULT hRet = S_FALSE;
HMODULE hmod = LoadLibrary(TEXT("shfolder.dll")); PFNSHGETFOLDERPATH pfn = NULL; if (hmod) { pfn = (PFNSHGETFOLDERPATH)GetProcAddress(hmod, "SHGetFolderPathA"); // or W if you are unicode
if (pfn) { hRet = pfn(NULL, CSIDL_COMMON_DESKTOPDIRECTORY, NULL, 0, pszFolder); if (S_OK != hRet) hRet = pfn(NULL, CSIDL_DESKTOPDIRECTORY, NULL, 0, pszFolder); if (S_OK == hRet) lstrcpy(pszPath ,pszFolder); } FreeLibrary(hmod); }
if (S_OK != hRet) {
FARPROC hShell32VersionProc = NULL; HMODULE hShell32Mod = (HMODULE)LoadLibrary(TEXT("shell32.dll")); if (hShell32Mod) hShell32VersionProc = GetProcAddress(hShell32Mod, "DllGetVersion");
if(hShell32VersionProc) { TCHAR szDir [MAX_PATH] = TEXT("\0");
//ok, we're not NT, but we may be multiuser windows.
GetWindowsDirectory(szDir, MAX_PATH); if (szDir) { MyStrCatBuff(szDir, TEXT("\\"), MAX_PATH); MyStrCatBuff(szDir, g_szAllUsers, MAX_PATH); TCHAR szTemp [MAX_MESSAGE_LEN] = TEXT("\0"); LoadString(g_hInstance, IDS_DESKTOP, szTemp, MAX_MESSAGE_LEN); if (szTemp) { MyStrCatBuff(szDir, TEXT("\\"), MAX_PATH); MyStrCatBuff(szDir, szTemp, MAX_PATH); lstrcpy(pszPath ,szDir); } } } else hr = SHGetSpecialFolderLocation(NULL, CSIDL_DESKTOPDIRECTORY, &lpItemDList); } }
if (SUCCEEDED(hr)) { SHGetPathFromIDList(lpItemDList, pszPath); if (SUCCEEDED(SHGetMalloc (&pMalloc))) { pMalloc->Free (lpItemDList); pMalloc->Release (); } } }
void RemoveDesktopShortCut ( LPTSTR lpszShortcutName ) { TCHAR szShortcutPath[MAX_PATH] = TEXT("\0"); GetDesktopDirectory(szShortcutPath); if(szShortcutPath[0] != TEXT('\0')) { lstrcat(szShortcutPath, TEXT("\\")); lstrcat(szShortcutPath, lpszShortcutName); lstrcat(szShortcutPath, TEXT(".LNK")); DeleteFile(szShortcutPath); } }
// This function will add a desktop shortcut
void AddDesktopShortCut ( LPTSTR lpszAppName, LPTSTR lpszLinkName ) { TCHAR szConnectPath [MAX_PATH] = TEXT("\0"); TCHAR szAppPath [MAX_PATH] = TEXT("\0"); TCHAR szConnectLinkPath [MAX_PATH] = TEXT("\0"); // Path the where the Shortcut file will livE
TCHAR szdrive [_MAX_DRIVE] = TEXT("\0"); TCHAR szdir [_MAX_DIR] = TEXT("\0"); TCHAR szfname [_MAX_FNAME] = TEXT("\0"); TCHAR szext [_MAX_EXT] = TEXT("\0"); TCHAR szRegPath [MAX_PATH] = TEXT("\0"); HRESULT hres = E_FAIL; IShellLink* psl = NULL; HKEY hkey = NULL; // first get the app path
lstrcpy(szRegPath, REGSTR_PATH_APPPATHS); lstrcat(szRegPath, TEXT("\\")); lstrcat(szRegPath, lpszAppName); if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, szRegPath, 0, IsNT5()? KEY_QUERY_VALUE : KEY_ALL_ACCESS, &hkey) == ERROR_SUCCESS) { DWORD dwTmp = sizeof(szConnectPath); DWORD dwType = 0; if(RegQueryValueEx(hkey, NULL, NULL, &dwType, (LPBYTE) szConnectPath, &dwTmp) != ERROR_SUCCESS) { RegCloseKey(hkey); return; } RegQueryValueEx(hkey, TEXT("Path"), NULL, &dwType, (LPBYTE) szAppPath, &dwTmp);
RegCloseKey(hkey); } else { return; }
GetDesktopDirectory(szConnectLinkPath); if(szConnectLinkPath[0] != TEXT('\0')) { // Append on the connect EXE name
lstrcat(szConnectLinkPath, TEXT("\\")); lstrcat(szConnectLinkPath, lpszAppName);
//
int nLastChar = lstrlen(szAppPath)-1; if ((nLastChar > 0) && (';' == szAppPath[nLastChar])) szAppPath[nLastChar] = 0;
// Split the path, and the reassemble with the .LNK extension
_tsplitpath( szConnectLinkPath, szdrive, szdir, szfname, szext ); _tmakepath(szConnectLinkPath, szdrive, szdir, lpszLinkName, TEXT(".LNK"));
// Create an IShellLink object and get a pointer to the IShellLink
// interface (returned from CoCreateInstance).
hres = CoCreateInstance (CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void **)&psl); if (SUCCEEDED (hres)) { IPersistFile *ppf;
// Query IShellLink for the IPersistFile interface for
// saving the shortcut in persistent storage.
hres = psl->QueryInterface (IID_IPersistFile, (void **)&ppf); if (SUCCEEDED (hres)) { WORD wsz [MAX_PATH]; // buffer for Unicode string
do {
// Set the path to the shortcut target.
if (!SUCCEEDED(psl->SetPath (szConnectPath))) break;
// Set the working dir to the shortcut target.
if (!SUCCEEDED(psl->SetWorkingDirectory (szAppPath))) break;
// Set the args.
if (!SUCCEEDED(psl->SetArguments (SHORTCUTENTRY_CMD))) break;
// Set the description of the shortcut.
TCHAR szDescription[MAX_MESSAGE_LEN]; if (!LoadString(g_hInstance, IDS_SHORTCUT_DESC, szDescription, MAX_MESSAGE_LEN)) lstrcpy(szDescription, lpszLinkName);
if (!SUCCEEDED(psl->SetDescription (szDescription))) break; // Ensure that the string consists of ANSI TCHARacters.
#ifdef UNICODE
lstrcpy(wsz, szConnectLinkPath); #else
MultiByteToWideChar (CP_ACP, 0, szConnectLinkPath, -1, wsz, MAX_PATH); #endif
// Save the shortcut via the IPersistFile::Save member function.
if (!SUCCEEDED(ppf->Save (wsz, TRUE))) break; // Release the pointer to IPersistFile.
ppf->Release (); break; } while (1); } // Release the pointer to IShellLink.
psl->Release (); } } }
// This function will apply the appropriate desktop changes based on the following
// algorithm. This code below assumes that the machine is NOT internet capable.
// If the machine was upgraded from a previous OS, then
// Add the connect to the internet ICON
// ELSE (clean install or OEM pre install)
// Add the connect to the internet ICON
//
void DoDesktopChanges ( HINSTANCE hAppInst ) { TCHAR szAppName[MAX_PATH]; TCHAR szLinkName[MAX_PATH]; HKEY hkey;
if (!LoadString(hAppInst, IDS_CONNECT_FNAME, szAppName, ARRAYSIZE(szAppName))) lstrcpy(szAppName, g_szConnectApp); if (!LoadString(hAppInst, IDS_CONNECT_DESKTOP_TITLE, szLinkName, ARRAYSIZE(szLinkName))) lstrcpy(szLinkName, g_szConnectLink);
// We always add the connect shortcut
AddDesktopShortCut(szAppName, szLinkName); // Set a registry value indicating that we messed with the desktop
DWORD dwDisposition; if (ERROR_SUCCESS == RegCreateKeyEx(HKEY_CURRENT_USER, ICWSETTINGSPATH, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, &dwDisposition)) { DWORD dwDesktopChanged = 1; RegSetValueEx(hkey, ICWDESKTOPCHANGED, 0, REG_DWORD, (LPBYTE)&dwDesktopChanged, sizeof(DWORD)); RegCloseKey(hkey); } }
// This undoes what DoDesktopChanges did
void UndoDesktopChanges ( HINSTANCE hAppInst ) {
TCHAR szConnectTotheInternetTitle[MAX_PATH]; HKEY hkey;
// Verify that we really changed the desktop
if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER, ICWSETTINGSPATH, 0, KEY_ALL_ACCESS, &hkey)) { DWORD dwDesktopChanged = 0; DWORD dwTmp = sizeof(DWORD); DWORD dwType = 0; RegQueryValueEx(hkey, ICWDESKTOPCHANGED, NULL, &dwType, (LPBYTE)&dwDesktopChanged, &dwTmp); RegCloseKey(hkey); // Bail if the desktop was not changed by us
if(!dwDesktopChanged) return; } // Always nuke the Connect to the internet icon
if (!LoadString(hAppInst, IDS_CONNECT_DESKTOP_TITLE, szConnectTotheInternetTitle, ARRAYSIZE(szConnectTotheInternetTitle))) { lstrcpy(szConnectTotheInternetTitle, g_szConnectLink); } RemoveDesktopShortCut(szConnectTotheInternetTitle); }
void UpdateDesktop ( HINSTANCE hAppInst ) { if(MyIsSmartStartEx(NULL, 0)) { // VYUNG NT5 bug See if IEAK wants to stop GETCONN icon creation
//if (!SHGetRestriction(NULL, TEXT("Internet Connection Wizard"), TEXT("NoICWIcon")))
// CHUNHOC NT5.1 bug Don't create icon at desktop in any case.
/*
if (!SHGetRestriction(NULL, L"Internet Connection Wizard", L"NoICWIcon")) DoDesktopChanges(hAppInst); */ } else { // We are internet ready, so set the appropriate Welcome show bit
// and replace the IE and OE links
UpdateWelcomeRegSetting(TRUE); } }
|