|
|
#include "priv.h"
#include "advpub.h"
#include "sdsutils.h"
#include "utils.h"
#include "convert.h"
#include "regstr.h"
const TCHAR c_szAppName[] = TEXT("ie4uinit"); const TCHAR c_szProfRecKey[] = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\ProfileReconciliation"); const TCHAR c_szHomeDirValue[] = TEXT("ProfileDirectory"); const TCHAR c_szExplorerKey[] = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders"); const TCHAR c_szIExploreMain[] = TEXT( "Software\\microsoft\\Internet Explorer\\Main" ); const TCHAR c_szIExplorerSearchUrl[] = TEXT( "Software\\microsoft\\Internet Explorer\\SearchUrl" ); const TCHAR c_szIExplorer[] = TEXT( "Software\\microsoft\\Internet Explorer" );
const TCHAR c_szCentralFile[] = TEXT("CentralFile"); const TCHAR c_szLocalFile[] = TEXT("LocalFile"); const TCHAR c_szName[] = TEXT("Name"); const TCHAR c_szRegKey[] = TEXT("RegKey"); const TCHAR c_szRegValue[] = TEXT("RegValue"); const TCHAR c_szMustBeRelative[] = TEXT("MustBeRelative"); const TCHAR c_szDefault[] = TEXT("Default"); const TCHAR c_szDefaultDir[] = TEXT("DefaultDir"); const TCHAR c_szIExploreLnk[] = TEXT("Internet Explorer.lnk" ); const TCHAR c_szIExploreBackLnk[] = TEXT("Internet Explorer Lnk.bak" ); const TCHAR c_szIExploreBackLnkIni[] = TEXT("IELnkbak.ini" ); const TCHAR c_szIESetupPath[] = TEXT( "software\\microsoft\\IE Setup\\setup" ); const TCHAR c_szIE4Path[] = TEXT( "software\\microsoft\\IE4" ); const TCHAR c_szAdvINFSetup[] = TEXT( "software\\microsoft\\Advanced INF Setup" ); const TCHAR c_szIEModRollback[] = TEXT( "IE CompList" ); const TCHAR c_szRegBackup[] = TEXT( "RegBackup" ); const TCHAR c_szInstallMode[] = TEXT("InstallMode"); const TCHAR c_szStarDotStar[] = "*.*"; const TCHAR c_szSearchUrl[] = TEXT("CleanSearchUrl");
const TCHAR c_szPrevStubINF[] = TEXT("ie4uinit.inf"); const TCHAR c_szStubINFFile[] = TEXT("ieuinit.inf"); const TCHAR c_szActInstalledIEGUID[] = TEXT( "SOFTWARE\\Microsoft\\Active Setup\\Installed Components\\{89820200-ECBD-11cf-8B85-00AA005B4383}"); const TCHAR c_szActInstalledIEGUIDRestore[] = TEXT( "SOFTWARE\\Microsoft\\Active Setup\\Installed Components\\{89820200-ECBD-11cf-8B85-00AA005B4383}.Restore"); const TCHAR c_szMyDocsDLL[] = TEXT("\\mydocs.dll");
const TCHAR c_szIE4Setup[]= TEXT("Software\\Microsoft\\IE Setup\\Setup"); const TCHAR c_szPreIEVer[]= TEXT("PreviousIESysFile"); const TCHAR c_szPreShellVer[]= TEXT("PreviousShellFile");
typedef VOID (*LPFNMYDOCSINIT)(VOID);
// used only at install stub time
BOOL IsPrevIE4(); BOOL IsPrevIE4WebShell(); UINT CheckIEVersion(); void RemoveOldMouseException(); void ProcessMouseException();
// used at uninstall stub time
UINT CheckUninstIEVersion();
//
//====== DllGetVersion =======================================================
//
typedef struct _DllVersionInfo { DWORD cbSize; DWORD dwMajorVersion; // Major version
DWORD dwMinorVersion; // Minor version
DWORD dwBuildNumber; // Build number
DWORD dwPlatformID; // DLLVER_PLATFORM_*
} DLLVERSIONINFO;
// Platform IDs for DLLVERSIONINFO
//#define DLLVER_PLATFORM_WINDOWS 0x00000001 // Windows 95
//#define DLLVER_PLATFORM_NT 0x00000002 // Windows NT
//
// The caller should always GetProcAddress("DllGetVersion"), not
// implicitly link to it.
//
typedef HRESULT (CALLBACK* DLLGETVERSIONPROC)(DLLVERSIONINFO *); //
//====== DllGetVersion =from shlwapi.h==========================================
//
HINSTANCE g_hinst;
BOOL g_fRunningOnNT = FALSE; BOOL g_fRunningOnNT5 = FALSE; BOOL g_fRunningOnWinXP = FALSE; BOOL g_fRunningOnWin95 = FALSE;
// shlwapi.dll api
typedef void (* PFNSHFLUSHSFCACHEWRAP)(); PFNSHFLUSHSFCACHEWRAP pfnSHFlushSFCacheWrap = NULL;
// old shell32.dll api
typedef void (* PFNSHFLUSHSFCACHE)(); PFNSHFLUSHSFCACHE pfnSHFlushSFCache = NULL;
struct FolderDescriptor; typedef void (* PFNINITFOLDER)(FolderDescriptor *pFolder, LPTSTR pszBaseName, LPTSTR pszUserDirectory);
void InitFolderFromDefault(FolderDescriptor *pFolder, LPTSTR pszBaseName, LPTSTR pszUserDirectory); void InitFolderMyDocs(FolderDescriptor *pFolder, LPTSTR pszBaseName, LPTSTR pszUserDirectory);
struct FolderDescriptor { UINT idsDirName; /* Resource ID for directory name */ LPCTSTR pszRegKey; /* Name of reg key under which to set path */ LPCTSTR pszRegValue; /* Name of reg value to set path in */ LPCTSTR pszStaticName; /* Static name for ProfileReconciliation subkey */ LPCTSTR pszFiles; /* Spec for which files should roam */ PFNINITFOLDER InitFolder; /* Function to init contents */ DWORD dwAttribs; /* Desired directory attributes */ BOOL fIntShellOnly : 1; /* TRUE if should not do this in browser only mode */ BOOL fMustBePerUser : 1; /* TRUE if should always be forced per-user on all platforms */ BOOL fDefaultInRoot : 1; /* TRUE if default location is root of drive, not windows dir */ BOOL fWriteToUSF : 1; /* TRUE if we should write to User Shell Folders to work around Win95 bug */ } aFolders[] = { { IDS_CSIDL_DESKTOP_L, c_szExplorerKey, TEXT("Desktop"), TEXT("Desktop"), c_szStarDotStar, InitFolderFromDefault, FILE_ATTRIBUTE_DIRECTORY, TRUE, FALSE, FALSE, FALSE } , { IDS_CSIDL_RECENT_L, c_szExplorerKey, TEXT("Recent"), TEXT("Recent"), c_szStarDotStar, InitFolderFromDefault, FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_DIRECTORY, TRUE, FALSE, FALSE, FALSE } , { IDS_CSIDL_NETHOOD_L, c_szExplorerKey, TEXT("NetHood"), TEXT("NetHood"), c_szStarDotStar, InitFolderFromDefault, FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_DIRECTORY, TRUE, FALSE, FALSE, FALSE } , { IDS_CSIDL_PERSONAL_L, c_szExplorerKey, TEXT("Personal"), TEXT("Personal"), c_szStarDotStar, InitFolderMyDocs, FILE_ATTRIBUTE_DIRECTORY, TRUE, FALSE, TRUE, FALSE } , { IDS_CSIDL_FAVORITES_L, c_szExplorerKey, TEXT("Favorites"), TEXT("Favorites"), c_szStarDotStar, InitFolderFromDefault, FILE_ATTRIBUTE_DIRECTORY, FALSE, FALSE, FALSE, TRUE }, { IDS_CSIDL_APPDATA_L, c_szExplorerKey, TEXT("AppData"), TEXT("AppData"), c_szStarDotStar, InitFolderFromDefault, FILE_ATTRIBUTE_DIRECTORY, FALSE, TRUE, FALSE, FALSE }, { IDS_CSIDL_CACHE_L, c_szExplorerKey, TEXT("Cache"), TEXT("Cache"), TEXT(""), NULL, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_DIRECTORY, FALSE, FALSE, FALSE, FALSE }, { IDS_CSIDL_COOKIES_L, c_szExplorerKey, TEXT("Cookies"), TEXT("Cookies"), c_szStarDotStar, NULL, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_DIRECTORY, FALSE, TRUE, FALSE, FALSE }, { IDS_CSIDL_HISTORY_L, c_szExplorerKey, TEXT("History"), TEXT("History"), c_szStarDotStar, NULL, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_DIRECTORY, FALSE, TRUE, FALSE, FALSE }, };
// Verion number 4.71
#define IE_4_MS_VERSION 0x00040047
// Build number 1712.0 (IE4.0 RTW)
#define IE_4_LS_VERSION 0x06B00000
// IE5 Major version
#define IE_5_MS_VERSION 0x00050000
// IE5.5 Major version
#define IE_55_MS_VERSION 0x00050032
// IE6 (Whistler) Major version
#define IE_6_MS_VERSION 0x00060000
// check IE version return code
#define LESSIE4 0
#define IE4 1
#define IE5 2
#define IE55 3
#define IE6 4 // Whistler
BOOL CheckWebViewShell(UINT *puiShell32) { HINSTANCE hInstShell32; DLLGETVERSIONPROC fpGetDllVersion; char szShell32[MAX_PATH]; BOOL bRet = FALSE;
GetSystemDirectory(szShell32, sizeof(szShell32)); AddPath(szShell32,"Shell32.dll"); hInstShell32 = LoadLibrary(szShell32); if ( hInstShell32 ) { DLLVERSIONINFO dllinfo;
fpGetDllVersion = (DLLGETVERSIONPROC)GetProcAddress(hInstShell32, "DllGetVersion"); bRet = (fpGetDllVersion != NULL); if (puiShell32 && fpGetDllVersion) { dllinfo.cbSize = sizeof(DLLVERSIONINFO); if ( fpGetDllVersion(&dllinfo) == NOERROR ) *puiShell32 = dllinfo.dwMajorVersion; else *puiShell32 = 0; // error case, should never be here
} FreeLibrary(hInstShell32); }
return bRet; }
// this code need to be updated whenever the new major version is released!!
UINT CheckIEVersion() { char szIE[MAX_PATH] = { 0 }; DWORD dwMSVer, dwLSVer;
GetSystemDirectory(szIE, sizeof(szIE)); AddPath(szIE, "shdocvw.dll"); GetVersionFromFile(szIE, &dwMSVer, &dwLSVer, TRUE);
if (dwMSVer < IE_4_MS_VERSION) { return LESSIE4; }
if ((dwMSVer >= IE_4_MS_VERSION) && (dwMSVer < IE_5_MS_VERSION)) { return IE4; }
if ((dwMSVer >= IE_5_MS_VERSION) && (dwMSVer < IE_55_MS_VERSION)) { return IE5; }
if ((dwMSVer >= IE_55_MS_VERSION) && (dwMSVer < IE_6_MS_VERSION)) { return IE55; }
if (dwMSVer == IE_6_MS_VERSION) { return IE6; }
#ifdef DEBUG
OutputDebugStringA("CheckIEVersion - unknown shdocvw.dll version# ! Need to add new IE_XX_MS_VERSION id\n"); DebugBreak(); #endif
return IE6; }
void InitFolderFromDefault(FolderDescriptor *pFolder, LPTSTR pszBaseName, LPTSTR pszUserDirectory) { SHFILEOPSTRUCT fos; TCHAR szFrom[MAX_PATH];
lstrcpy(szFrom, pszBaseName);
/* Before we build the complete source filespec, check to see if the
* directory exists. In the case of lesser-used folders such as * "Application Data", the default may not have ever been created. * In that case, we have no contents to copy. */ DWORD dwAttr = GetFileAttributes(szFrom); if (dwAttr == 0xffffffff || !(dwAttr & FILE_ATTRIBUTE_DIRECTORY)) return;
AddPath(szFrom,""); lstrcat(szFrom, pFolder->pszFiles); szFrom[lstrlen(szFrom)+1] = '\0'; /* double null terminate from string */ pszUserDirectory[lstrlen(pszUserDirectory)+1] = '\0'; /* and to string */
fos.hwnd = NULL; fos.wFunc = FO_COPY; fos.pFrom = szFrom; fos.pTo = pszUserDirectory; fos.fFlags = FOF_NOCONFIRMATION | FOF_NOCONFIRMMKDIR | FOF_NOERRORUI; fos.fAnyOperationsAborted = FALSE; fos.hNameMappings = NULL; fos.lpszProgressTitle = NULL;
SHFileOperation(&fos); }
void InitFolderMyDocs(FolderDescriptor *pFolder, LPTSTR pszBaseName, LPTSTR pszUserDirectory) { HRESULT hres = E_FAIL; TCHAR szFrom[MAX_PATH]; TCHAR szPathDest[MAX_PATH]; BOOL fCopyLnk;
lstrcpy(szFrom, pszBaseName);
/* Before we build the complete source filespec, check to see if the
* directory exists. In the case of lesser-used folders such as * "Application Data", the default may not have ever been created. * In that case, we have no contents to copy. */ DWORD dwAttr = GetFileAttributes(szFrom); if (dwAttr == 0xffffffff || !(dwAttr & FILE_ATTRIBUTE_DIRECTORY)) return;
IShellLink *psl; if (FAILED(CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void **)&psl))) return;
if (SHGetNewLinkInfo(szFrom, pszUserDirectory, szPathDest, &fCopyLnk, SHGNLI_PREFIXNAME)) {
if (fCopyLnk) { if (GetFileAttributes(szPathDest) == 0xffffffff && CopyFile(szFrom, szPathDest, TRUE)) { hres = S_OK; SHChangeNotify(SHCNE_CREATE, SHCNF_PATH, szPathDest, NULL); SHChangeNotify(SHCNE_FREESPACE, SHCNF_PATH, szPathDest, NULL); } else { // DebugMsg(TF_ERROR, TEXT("****copy failed (%d)"),GetLastError());
} } else { IPersistFile *ppf;
psl->SetPath(szFrom);
//
// make sure the working directory is set to the same
// directory as the app (or document).
//
// dont do this for non-FS pidls (ie control panel)
//
// what about a UNC directory? we go ahead and set
// it, wont work for a WIn16 app.
//
if (!PathIsDirectory(szFrom)) { PathRemoveFileSpec(szFrom); psl->SetWorkingDirectory(szFrom); }
/* We only did the SHGetNewLinkInfo for the fCopyLnk flag;
* load a resource string to get a more descriptive name * for the shortcut. */ LPTSTR pszPathEnd = PathFindFileName(szPathDest); LoadString(g_hinst, IDS_MYDOCS_SHORTCUT, pszPathEnd, ARRAYSIZE(szPathDest) - (int)(pszPathEnd - szPathDest));
if (GetFileAttributes(szPathDest) == 0xffffffff) { hres = psl->QueryInterface(IID_IPersistFile, (void **)&ppf); if (SUCCEEDED(hres)) { #ifdef UNICODE
hres = ppf->Save(szPathDest, TRUE); #else
WCHAR wszPath[MAX_PATH]; MultiByteToWideChar(CP_ACP, 0, szPathDest, -1, wszPath, ARRAYSIZE(wszPath)); hres = ppf->Save(wszPath, TRUE); #endif
ppf->Release(); } } } }
psl->Release();
}
HRESULT SetupFolder(HKEY hkeyProfRec, LPTSTR pszHomeDir, LPTSTR pszHomeDirEnd, int cchHomeDir, FolderDescriptor *pFolder, BOOL fDefaultProfile, HKEY hkeyFolderPolicies) { DWORD dwType, cbData; BOOL fMakeFolderPerUser; BOOL fGotFromPolicy = FALSE;
/* Figure out whether to make this folder be per-user or not. On NT we
* make everything per-user. Some folders (notably Application Data) * are also always per-user. The default for everything else is to not * make it per-user here unless a policy is set to force it. If we do * not want to make it per-user here, we'll just leave it the way it is; * of course, the folder could have already been made per-user by some * other means. * * "Make per-user" means set a profile-relative path if we're not operating * on the default profile, plus adding a ProfileReconciliation key on win95 * (any profile, including default). */ if (hkeyFolderPolicies != NULL) { DWORD dwFlag; cbData = sizeof(dwFlag); if (RegQueryValueEx(hkeyFolderPolicies, pFolder->pszStaticName, NULL, &dwType, (LPBYTE)&dwFlag, &cbData) == ERROR_SUCCESS && (dwType == REG_DWORD || (dwType == REG_BINARY && cbData == sizeof(dwFlag)))) { fMakeFolderPerUser = dwFlag; fGotFromPolicy = TRUE; } } if (!fGotFromPolicy) fMakeFolderPerUser = (g_fRunningOnNT || pFolder->fMustBePerUser);
TCHAR szUserHomeDir[MAX_PATH];
*pszHomeDirEnd = '\0'; /* strip off dir name from last time through */ lstrcpy(szUserHomeDir, pszHomeDir); PathRemoveBackslash(szUserHomeDir);
/* Get the localized name for the directory, as it should appear in
* the file system. */ int cchDir = LoadString(g_hinst, pFolder->idsDirName, pszHomeDirEnd, cchHomeDir); if (!cchDir) return HRESULT_FROM_WIN32(GetLastError()); cchDir++; /* count null character */
/* Create the reg key where a pointer to the new directory is supposed to
* be stored, and write the path there. */ HKEY hkeyFolder;
LONG err = RegCreateKeyEx(HKEY_CURRENT_USER, pFolder->pszRegKey,0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ|KEY_WRITE, NULL, &hkeyFolder, NULL);
if (err != ERROR_SUCCESS) return HRESULT_FROM_WIN32(err);
/* Build the default location for this directory (usually just under the
* Windows directory, except for My Documents). We'll use this as the * location to create if nothing is in the registry, and also to compare * the registry-set location to see if we should move it or leave it * alone. */
TCHAR szDefaultDir[MAX_PATH]; GetWindowsDirectory(szDefaultDir, ARRAYSIZE(szDefaultDir));
if (pFolder->fDefaultInRoot) { LPTSTR pszRoot; if (PathIsUNC(szDefaultDir)) { pszRoot = ANSIStrChr(szDefaultDir, (WORD)'\\'); if (pszRoot != NULL) pszRoot = ANSIStrChr(pszRoot+1, (WORD)'\\'); if (pszRoot != NULL) *(pszRoot+1) = '\0'; } else { pszRoot = CharNext(szDefaultDir); if (*pszRoot == ':') pszRoot++; if (*pszRoot == '\\') pszRoot++; *pszRoot = '\0'; } } else { AddPath(szDefaultDir, ""); } lstrcat(szDefaultDir, pszHomeDirEnd);
/* Get the path that was recorded for this folder before we ran. We will
* use it as the default for migrating contents, unless it's not there or * it's already set to the new directory. In either of those cases we use * the localized name, relative to the Windows directory. */ TCHAR szOldDir[MAX_PATH]; BOOL fDefaultLocation = FALSE; cbData = sizeof(szOldDir); szOldDir[0] = '\0'; err = SDSQueryValueExA(hkeyFolder, pFolder->pszRegValue, 0, &dwType, (LPBYTE)szOldDir, &cbData);
BOOL fGotPathFromRegistry = (err == ERROR_SUCCESS);
if (!fGotPathFromRegistry) { lstrcpy(szOldDir, szDefaultDir); if (!pFolder->fDefaultInRoot) fDefaultLocation = TRUE; } else { /* Previous path is present in the registry. If it's a net path,
* it's probably been set by system policies and we want to leave * it the way it is. */ BOOL fIsNet = FALSE; if (PathIsUNC(szOldDir)) fIsNet = TRUE; else { int nDriveNumber = PathGetDriveNumber(szOldDir); if (nDriveNumber != -1) { TCHAR szRootPath[4] = TEXT("X:\\"); szRootPath[0] = nDriveNumber + TEXT('A'); if (::GetDriveType(szRootPath) == DRIVE_REMOTE) fIsNet = TRUE; } } if (fIsNet) { RegCloseKey(hkeyFolder); return S_OK; } }
LPSTR pszDirToCreate; BOOL fInit = TRUE;
if (fDefaultProfile || !fMakeFolderPerUser) { /* On the default profile, the directory path we want is the one we
* read from the registry (or the default windir-based path we built). * Also, most folders we want to keep as the user has them already * configured. In either case, we do not initialize the contents * because there's no place to initialize them from in the first case, * and we want the contents undisturbed in the second case. */ pszDirToCreate = szOldDir; fInit = FALSE; } else { /* We want to give this user a profile-relative path for this folder.
* However, if they already have an explicit non-default path set for * this folder, we don't bother initializing it since they already have * it set up someplace where they want it. */ if (fGotPathFromRegistry && ::GetFileAttributes(szOldDir) != 0xffffffff && lstrcmpi(szOldDir, szDefaultDir)) { pszDirToCreate = szOldDir; fInit = FALSE; } else { pszDirToCreate = pszHomeDir; } }
/* Only write the path out to the registry if we didn't originally get it
* from the registry. */ if (!fGotPathFromRegistry) { /* If we're writing to the User Shell Folders key, only write non-
* default paths there. */ /* There are some applications (German Corel Office 7) which
* depend on the entry being in User Shell Folders for some shell * folders. This dependency is due to the fact that the entry use * to be created always by down level browsers (IE30). * * We do not do this generically because no value under * USF is supposed to mean "use the one in the Windows * directory", whereas an absolute path means "use that * path"; if there's a path under USF, it will be used * literally, which is a problem if the folder is set up * to use the shared folder location but roams to a machine * with Windows installed in a different directory. */ if ((pFolder->pszRegKey != c_szExplorerKey) || pszDirToCreate != szOldDir || !fDefaultLocation || pFolder->fWriteToUSF) {
if (g_fRunningOnNT) { TCHAR szRegPath[MAX_PATH];
lstrcpy(szRegPath, TEXT("%USERPROFILE%\\")); lstrcat(szRegPath, pszHomeDirEnd); RegSetValueEx( hkeyFolder, pFolder->pszRegValue, 0, REG_EXPAND_SZ, (LPBYTE)szRegPath, (lstrlen(szRegPath)+1) * sizeof(TCHAR)); } else { if (!pFolder->fWriteToUSF || g_fRunningOnWin95) { RegSetValueEx(hkeyFolder, pFolder->pszRegValue, 0, REG_SZ, (LPBYTE)pszDirToCreate, (lstrlen(pszDirToCreate)+1) * sizeof(TCHAR)); } else {
// 98/12/30 #238093 (IE#50598 / Office#188177) vtan: There exists a
// case where HKCU\..\Explorer\User Shell Folders\Favorites does NOT
// exist on Win98 (unknown cause). This case simulates a Windows95
// bug which the fWriteToUSF flag is designed to get around. In the
// German Win9x this replaces the Favorites folder in User Shell
// Folders key with the english name and this is propogated below to
// Shell Folders which destroys the localization.
// In this case we want to write the value of the key in Shell Folders
// (if that points to a valid directory) to the User Shell Folders key
// and just let the code below write the same value back to the Shell
// Folders key. A little bit of wasted effort.
HKEY hkeySF;
if (RegCreateKeyEx(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ, NULL, &hkeySF, NULL) == ERROR_SUCCESS) { DWORD dwRegDataType, dwRegDataSize; TCHAR szRegValue[MAX_PATH];
dwRegDataSize = sizeof(szRegValue); if (RegQueryValueEx(hkeySF, pFolder->pszRegValue, 0, &dwRegDataType, reinterpret_cast<LPBYTE>(szRegValue), &dwRegDataSize) == ERROR_SUCCESS) { if (GetFileAttributes(szRegValue) != 0xFFFFFFFF) { lstrcpy(pszDirToCreate, szRegValue); RegSetValueEx(hkeyFolder, pFolder->pszRegValue, 0, REG_SZ, (LPBYTE)pszDirToCreate, (lstrlen(pszDirToCreate)+1) * sizeof(TCHAR)); } } RegCloseKey(hkeySF); } } } }
/* The User Shell Folders key has a near-twin: Shell Folders, which
* (a) should always contain the path to a folder, even if the folder * is in its default location, and (b) should contain the expanded * path on NT. */ if (pFolder->pszRegKey == c_szExplorerKey) { HKEY hkeySF; if (RegCreateKeyEx(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ|KEY_WRITE, NULL, &hkeySF, NULL) == ERROR_SUCCESS) { RegSetValueEx(hkeySF, pFolder->pszRegValue, 0, REG_SZ, (LPBYTE)pszDirToCreate, (lstrlen(pszDirToCreate)+1) * sizeof(TCHAR)); RegCloseKey(hkeySF); } }
/* Initialize default contents of the folder.
*/ if (fInit && pFolder->InitFolder != NULL) pFolder->InitFolder(pFolder, szOldDir, pszHomeDir); }
/* Always try to create the directory we want, if it doesn't already
* exist. */
if (::GetFileAttributes(pszDirToCreate) == 0xffffffff) { CreateDirectory(pszDirToCreate, NULL); if (pFolder->dwAttribs != FILE_ATTRIBUTE_DIRECTORY) SetFileAttributes(pszDirToCreate, pFolder->dwAttribs); }
RegCloseKey(hkeyFolder);
/*
* If it's the My Documents folder, there is some per-user initialization * to do regardless of whether we set the values or they already existed. */ if (pFolder->InitFolder == InitFolderMyDocs) { TCHAR szMyDocs[ MAX_PATH ];
if (GetSystemDirectory( szMyDocs, ARRAYSIZE(szMyDocs) )) { HINSTANCE hMyDocs;
lstrcat( szMyDocs, c_szMyDocsDLL );
hMyDocs = LoadLibrary( szMyDocs );
if (hMyDocs) {
LPFNMYDOCSINIT pMyDocsInit = (LPFNMYDOCSINIT)GetProcAddress( hMyDocs, "PerUserInit" );
if (pMyDocsInit) { pMyDocsInit(); }
FreeLibrary( hMyDocs ); } } }
/* Now, for Windows 95 systems, create a ProfileReconciliation subkey
* which will make this folder roam. Only if we want to make this folder * per-user, of course. */ if (fMakeFolderPerUser && !g_fRunningOnNT) { TCHAR szDefaultPath[MAX_PATH]; lstrcpy(szDefaultPath, TEXT("*windir\\")); lstrcat(szDefaultPath, pszHomeDirEnd);
HKEY hSubKey;
LONG err = RegCreateKeyEx(hkeyProfRec, pFolder->pszStaticName, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hSubKey, NULL); if (err == ERROR_SUCCESS) err = RegSetValueEx(hSubKey, c_szCentralFile, 0, REG_SZ, (LPBYTE)pszHomeDirEnd, cchDir); if (err == ERROR_SUCCESS) err = RegSetValueEx(hSubKey, c_szLocalFile, 0, REG_SZ, (LPBYTE)pszHomeDirEnd, cchDir); if (err == ERROR_SUCCESS) err = RegSetValueEx(hSubKey, c_szName, 0, REG_SZ, (LPBYTE)pFolder->pszFiles, lstrlen(pFolder->pszFiles) + 1); if (err == ERROR_SUCCESS) err = RegSetValueEx(hSubKey, c_szDefaultDir, 0, REG_SZ, (LPBYTE)szDefaultPath, lstrlen(szDefaultPath) + 1);
DWORD dwOne = 1; if (err == ERROR_SUCCESS) err = RegSetValueEx(hSubKey, c_szMustBeRelative, 0, REG_DWORD, (LPBYTE)&dwOne, sizeof(dwOne)); if (err == ERROR_SUCCESS) err = RegSetValueEx(hSubKey, c_szDefault, 0, REG_DWORD, (LPBYTE)&dwOne, sizeof(dwOne));
if (err == ERROR_SUCCESS) err = RegSetValueEx(hSubKey, c_szRegKey, 0, REG_SZ, (LPBYTE)pFolder->pszRegKey, lstrlen(pFolder->pszRegKey) + 1); if (err == ERROR_SUCCESS) err = RegSetValueEx(hSubKey, c_szRegValue, 0, REG_SZ, (LPBYTE)pFolder->pszRegValue, lstrlen(pFolder->pszRegValue) + 1);
RegCloseKey(hSubKey);
if (err != ERROR_SUCCESS) return HRESULT_FROM_WIN32(err); } return S_OK; }
BOOL GetModulePath( LPTSTR szPath, UINT cbPath ) { PSTR pszTmp;
if (GetModuleFileName(g_hinst, szPath, cbPath ) == 0) { szPath[0] = '\0'; return FALSE; } else { pszTmp = ANSIStrRChr( szPath, '\\' ); if ( pszTmp ) *pszTmp = '\0'; } return TRUE ; }
int DoMsgBoxParam(HWND hwnd, UINT TextString, UINT TitleString, UINT style, PTSTR param ) { TCHAR szTitle[MAX_PATH]; TCHAR szMsg[2*MAX_PATH];
if (!LoadString(g_hinst, TextString, szMsg, sizeof(szMsg))) szMsg[0] = '\0';
if ( param ) { TCHAR szBuf[2*MAX_PATH];
wsprintf( szBuf, szMsg, param ); lstrcpy( szMsg, szBuf ); }
if (!LoadString(g_hinst, TitleString, szTitle, sizeof(szTitle))) szTitle[0] = '\0';
return MessageBox(hwnd, szMsg, szTitle, style); }
void InstINFFile( LPCTSTR pcszInf, LPTSTR pszSec, BOOL bInstall, BOOL bSaveRollback, DWORD dwFlag ) { TCHAR szPath[MAX_PATH]; CABINFO cabInfo;
if ( GetModulePath( szPath, sizeof(szPath) ) ) { if ( bSaveRollback ) { ZeroMemory( &cabInfo, sizeof(CABINFO) ); // install IE4Uinit.INF
lstrcpy( cabInfo.szSrcPath, szPath ); AddPath( szPath, pcszInf );
if ( FileExists( szPath ) ) { cabInfo.pszInf = szPath; cabInfo.pszSection = pszSec; cabInfo.dwFlags = (bInstall ? ALINF_BKINSTALL : ALINF_ROLLBACK); cabInfo.dwFlags |= ALINF_QUIET; ExecuteCab( NULL, &cabInfo, NULL ); } else if (!(dwFlag & RSC_FLAG_QUIET)) { DoMsgBoxParam( NULL, IDS_ERR_NOFOUNDINF, IDS_APPNAME, MB_OK|MB_ICONINFORMATION, szPath ); } } else { char szInfFile[MAX_PATH];
lstrcpy( szInfFile, szPath); AddPath( szInfFile, pcszInf); RunSetupCommand(NULL, szInfFile, pszSec, szPath, NULL, NULL, dwFlag, NULL); }
} }
void DoRollback() { HKEY hLMkey; HKEY hSubkey1, hSubkey2; TCHAR szBuf[MAX_PATH]; DWORD dwSize; DWORD dwIndex = 0; int ilen;
// rollback all the components listed in c_szIEModRollback key
//
if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, c_szAdvINFSetup, 0, KEY_READ , &hLMkey) == ERROR_SUCCESS ) { if ( RegOpenKeyEx(hLMkey, c_szIEModRollback, 0, KEY_READ , &hSubkey1) == ERROR_SUCCESS ) { lstrcpy( szBuf, c_szAdvINFSetup ); AddPath( szBuf, "" ); ilen = lstrlen(szBuf); dwSize = ARRAYSIZE(szBuf) - ilen; while ( RegEnumValue( hSubkey1, dwIndex, &szBuf[ilen], &dwSize, NULL, NULL, NULL, NULL ) == ERROR_SUCCESS ) { if ( RegOpenKeyEx(hLMkey, &szBuf[ilen], 0, KEY_READ | KEY_WRITE, &hSubkey2) == ERROR_SUCCESS ) { RegSetValueEx( hSubkey2, TEXT("BackupRegistry"), 0, REG_SZ, (LPBYTE)TEXT("n"), (lstrlen(TEXT("n"))+1)*sizeof(TCHAR) ); RegCloseKey( hSubkey2 ); }
AddPath( szBuf, c_szRegBackup );
///////////////////////////////////////////////////////////////////////////
// ShabbirS - 8/17/98
// Bug# 26774 : Found that this restoring of backup reg data undoes our
// dll registering done during the RunOnceEx phase.
///////////////////////////////////////////////////////////////////////////
// restore HKLM if there
//if ( RegOpenKeyEx(hLMkey, &szBuf[ilen], 0, KEY_READ | KEY_WRITE, &hSubkey2) == ERROR_SUCCESS )
//{
// RegRestoreAll( NULL, NULL, hSubkey2 );
// RegCloseKey( hSubkey2 );
//}
// restore HKCU if there
if ( RegOpenKeyEx( HKEY_CURRENT_USER, szBuf, 0, KEY_READ | KEY_WRITE, &hSubkey2) == ERROR_SUCCESS ) { RegRestoreAll( NULL, NULL, hSubkey2 ); RegCloseKey( hSubkey2 ); }
dwIndex++; dwSize = ARRAYSIZE( szBuf ) - ilen; }
RegCloseKey( hSubkey1 ); }
RegCloseKey( hLMkey ); } }
#define NT_MEMORYLIMIT 0x03f00000
#define WIN9X_MEMORYLIMIT 0x01f00000
void DoINFWork( BOOL bInstall, LPCTSTR pcszInfFile, LPTSTR pszInfSec, DWORD dwFlag ) { HKEY hkey; TCHAR szBuf[MAX_PATH] = { 0 }; DWORD dwSize; DWORD dwRedist = 0; BOOL bRedistMode = FALSE;
// check the InstallMode and determin if make the desktop icon and StartMenu item.
if ( bInstall && (RegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szIESetupPath, 0, KEY_READ, &hkey) == ERROR_SUCCESS) ) { dwSize = sizeof(dwRedist); // If we can read the Installmode and bit 0 is set, assume redist (Remove short cuts)
if ( (RegQueryValueEx( hkey, c_szInstallMode, 0, NULL, (LPBYTE)&dwRedist, &dwSize) == ERROR_SUCCESS) && (dwRedist & 1) ) { bRedistMode = TRUE; } RegCloseKey( hkey ); }
// if not installed over SP4 level crypto, then backup/restore the crypto keys.
// NOTE that bInstall is passed in the 4th argument, so during install bSaveRollback is TRUE. During
// uninstall, the reg backup data should be restored when the DefaultInstall section is processed, so
// set bSaveRollback to FALSE
if (!FSP4LevelCryptoInstalled()) InstINFFile( pcszInfFile, bInstall ? "BackupCryptoKeys" : "DelCryptoKeys", bInstall, bInstall, dwFlag ); else { // BUGBUG: if bInstall is FALSE, need to delete the reg backup data for the crypto keys
}
// install the WinXP specific section
if(g_fRunningOnWinXP && !pszInfSec ) { InstINFFile( pcszInfFile, TEXT("DefaultInstall.WinXP"), bInstall, TRUE, dwFlag); } else { // install the current shortcut and HKCU settings by stub INF
InstINFFile( pcszInfFile, pszInfSec, bInstall, TRUE, dwFlag ); }
// Even though IE5.0 does not install channelband, if the channelband exists on IE4.0, it should works in
// IE5.0. Therefore if there is channelbar link exists(PrevIE Version is IE4.0 browser only), IE5 will update
// the channelbar link to the current browser. Otherwise, do nothing.
if (bInstall && IsPrevIE4() && !IsPrevIE4WebShell()) { InstINFFile( pcszInfFile, TEXT("Shell.UserStub.Uninstall"), bInstall, FALSE, RSC_FLAG_INF | RSC_FLAG_QUIET ); }
if ( bRedistMode ) { LPTSTR lpszSection;
if ( g_fRunningOnNT ) lpszSection = TEXT("RedistIE.NT"); else lpszSection = TEXT("RedistIE.Win");
InstINFFile( pcszInfFile, lpszSection, bInstall, TRUE, dwFlag ); }
// On uninstall, check what the current browser version and determin if we need to cleanup the
// Channel and quick launch folders
if ( !bInstall && ( CheckIEVersion() == LESSIE4)) { LPTSTR lpszSection;
if ( g_fRunningOnNT ) lpszSection = TEXT("CleanFolders.NT"); else lpszSection = TEXT("CleanFolders.Win");
InstINFFile( pcszInfFile, lpszSection, bInstall, FALSE, RSC_FLAG_INF | RSC_FLAG_QUIET | RSC_FLAG_NGCONV ); }
// Enable sounds if user has a big enough machine
// NT - 64MB, Win9x - 32MB
if(bInstall) { LPTSTR lpszSection = NULL; MEMORYSTATUS ms;
ms.dwLength = sizeof(MEMORYSTATUS); GlobalMemoryStatus(&ms);
if ( g_fRunningOnNT) { if(ms.dwTotalPhys >= NT_MEMORYLIMIT) { lpszSection = TEXT("SoundInstall.NT"); } } else { if(ms.dwTotalPhys >= WIN9X_MEMORYLIMIT) { lpszSection = TEXT("SoundInstall"); } }
if(lpszSection) InstINFFile( pcszInfFile, lpszSection, bInstall, TRUE, RSC_FLAG_INF | RSC_FLAG_QUIET | RSC_FLAG_NGCONV ); }
if (bInstall) { // in fact this is only true for IE5 install inf, but IE4 inf is called ok too since there is no
// such section in IE4 stub inf.
if (CheckWebViewShell(NULL)) { LPSTR lpszSection = NULL; if(g_fRunningOnWinXP) lpszSection = TEXT("IE5onIE4Shell.WinXP"); else lpszSection = TEXT("IE5onIE4Shell"); InstINFFile( pcszInfFile, lpszSection, bInstall, FALSE, RSC_FLAG_INF | RSC_FLAG_QUIET ); } }
// check if the user's home page is bogus one
if ( bInstall && (RegOpenKeyEx( HKEY_CURRENT_USER, c_szIExploreMain, 0, KEY_READ, &hkey ) == ERROR_SUCCESS) ) { DWORD dwSize;
dwSize = sizeof(szBuf); if ( RegQueryValueEx( hkey, TEXT("Start Page"), NULL, NULL, (LPBYTE)szBuf, &dwSize ) == ERROR_SUCCESS ) { if ( (g_fRunningOnNT && ANSIStrStrI(szBuf, "Plus!") && ANSIStrStrI(szBuf, "File:")) || (!lstrcmpi(szBuf, TEXT("http://home.microsoft.com"))) || (!lstrcmpi(szBuf, TEXT("http://home.microsoft.com/"))) ) { InstINFFile( pcszInfFile, TEXT("OverrideHomePage.NT"), bInstall, TRUE, dwFlag ); } }
RegCloseKey( hkey ); }
if ( !bRedistMode ) { typedef void (*PFSetFirstHomepage)(); PFSetFirstHomepage pfSetFirstHomepage;
HMODULE hMod = LoadLibrary("iesetup.dll"); if (hMod) { pfSetFirstHomepage = (PFSetFirstHomepage)GetProcAddress(hMod, "SetFirstHomepage"); if (pfSetFirstHomepage) { pfSetFirstHomepage(); } FreeLibrary(hMod); } } // DoRollback if needed
if ( !bInstall ) { DoRollback(); } }
/*----------------------------------------------------------
Purpose: Detect if it is run on Russian LangID */
//DWORD dwLangList[] = { 0x0419, 0xFFFF };
#define RUSSIANLANG 0x0419
BOOL IsBrokenLang() { char szTmp[MAX_PATH] = { 0 }; DWORD dwLangKernel32; DWORD dwTmp; BOOL bBadLang = FALSE;
GetSystemDirectory(szTmp, sizeof(szTmp)); AddPath(szTmp,"kernel32.dll" ); GetVersionFromFile(szTmp, &dwLangKernel32, &dwTmp, FALSE);
if ( dwLangKernel32 == RUSSIANLANG ) { bBadLang = TRUE; } return bBadLang; }
BOOL IsPrevStubRun() { HKEY hLMKey, hCUKey; BOOL bRet = FALSE; char szStubVer[50], szPreIEVer[50]; DWORD dwSize; WORD wStubVer[4]={0}, wPreIEVer[4]={0};
// check if the pre-version iestub is run
if ( RegOpenKeyEx( HKEY_CURRENT_USER, c_szActInstalledIEGUID, 0, KEY_READ, &hCUKey ) == ERROR_SUCCESS ) { dwSize = sizeof(szStubVer); if ( RegQueryValueEx( hCUKey, TEXT("Version"), NULL, NULL, (LPBYTE)szStubVer, &dwSize ) == ERROR_SUCCESS ) { ConvertVersionString( szStubVer, wStubVer, ',' ); } RegCloseKey(hCUKey); }
if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, c_szIESetupPath, 0, KEY_READ, &hLMKey ) == ERROR_SUCCESS ) { dwSize = sizeof(szPreIEVer); if ( RegQueryValueEx( hLMKey, TEXT("PreviousIESysFile"), NULL, NULL, (LPBYTE)szPreIEVer, &dwSize ) == ERROR_SUCCESS ) { ConvertVersionString( szPreIEVer, wPreIEVer, '.' );
if ( (MAKELONG(wPreIEVer[1],wPreIEVer[0])<IE_4_MS_VERSION) || (wStubVer[0] > wPreIEVer[0]) || ((wStubVer[0] == wPreIEVer[0]) && (wStubVer[1] >= wPreIEVer[1])) ) { bRet = TRUE; } } else //should never be here. OW
bRet = TRUE; //not forcing rerun the prev-stub
RegCloseKey(hLMKey); } else //should never be here. OW
bRet = TRUE; //not forcing rerun the prev-stub
return bRet; }
/*----------------------------------------------------------
Purpose: Stripping off the trailing spaces for the registry data in the list */
typedef struct _REGDATACHECK { HKEY hRootKey; LPSTR lpszSubKey; LPSTR lpszValueName; } REGDATACHECK;
REGDATACHECK chkList[] = { { HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders", "AppData" }, { HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders", "Start Menu" }, { HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", "AppData" }, { HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", "Start Menu" }, { HKEY_USERS, ".DEFAULT\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders", "AppData" }, { HKEY_USERS, ".DEFAULT\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders", "Start Menu" }, { HKEY_USERS, ".DEFAULT\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", "AppData" }, { HKEY_USERS, ".DEFAULT\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", "Start Menu" }, };
void FixRegData() { int iList, i; LPSTR pszTmp; char szBuf[MAX_PATH]; DWORD dwSize, dwType; HKEY hKey;
iList = ARRAYSIZE( chkList ); for ( i = 0; i < iList; i++ ) { if ( RegOpenKeyEx(chkList[i].hRootKey, chkList[i].lpszSubKey, 0, KEY_READ|KEY_WRITE, &hKey) == ERROR_SUCCESS ) { dwSize = sizeof(szBuf); if ( RegQueryValueEx(hKey, chkList[i].lpszValueName, 0, &dwType, (LPBYTE)szBuf, &dwSize) == ERROR_SUCCESS ) { // strip off the trailing blanks
pszTmp = szBuf; pszTmp += lstrlen(szBuf) - 1;
while ( (pszTmp >= szBuf) && (*pszTmp == ' ') ) { *pszTmp = '\0'; pszTmp--; }
RegSetValueEx( hKey, chkList[i].lpszValueName, 0, dwType, (LPBYTE)szBuf, lstrlen(szBuf)+1 ); } RegCloseKey( hKey ); } } }
void FixSearchUrl() { HKEY hkey, hIEKey; TCHAR szBuf[MAX_PATH]; DWORD dwSize;
// if HKCU, software\microsoft\internet explorer\SearchUrl, "default" value is ""
// Delete the "" default value.
//
if ( RegOpenKeyEx(HKEY_CURRENT_USER, c_szIExplorerSearchUrl, 0, KEY_READ|KEY_WRITE, &hkey) == ERROR_SUCCESS ) { dwSize = 0; if ( RegQueryValueEx( hkey, TEXT(""), 0, NULL, (LPBYTE)szBuf, &dwSize ) != ERROR_SUCCESS ) { dwSize = sizeof(szBuf); if ( (RegQueryValueEx( hkey, TEXT(""), 0, NULL, (LPBYTE)szBuf, &dwSize ) == ERROR_SUCCESS) && (szBuf[0] == TEXT('\0')) ) { // found "" empty string as default value, check if we have cleaned up before.
// If not, clean it now, otherwise do nothing.
if ( RegCreateKeyEx( HKEY_CURRENT_USER, c_szIE4Path,0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ|KEY_WRITE, NULL, &hIEKey, NULL) == ERROR_SUCCESS ) { dwSize = sizeof(szBuf); if ( (RegQueryValueEx( hIEKey, c_szSearchUrl, 0, NULL, (LPBYTE)szBuf, &dwSize ) != ERROR_SUCCESS) || (*CharUpper(szBuf) != TEXT('Y')) ) { RegDeleteValue( hkey, TEXT("") ); lstrcpy( szBuf, TEXT("Y") ); RegSetValueEx( hIEKey, c_szSearchUrl, 0, REG_SZ, (LPBYTE)szBuf, (lstrlen(szBuf)+1)*sizeof(TCHAR) ); }
RegCloseKey( hIEKey ); } } } RegCloseKey( hkey ); } }
/*----------------------------------------------------------
* Helper function to check if the Channels folder exists in * the current user profile. *---------------------------------------------------------- */
// "Channels" resid from CdfView. (Need to use this, b'cos could be localized
#define CHANNEL_FOLDER_RESID 0x1200
// SHGetSpecialFolderPath function from Shell32.dll
typedef BOOL (WINAPI *SH_GSFP_PROC) (HWND, LPTSTR, int, BOOL);
BOOL DoesChannelFolderExist() { char szChannelName[MAX_PATH]; char szSysPath[MAX_PATH] = { 0 }; char szChannelPath[MAX_PATH]; BOOL bRet = FALSE; BOOL bGetRC = TRUE; HMODULE hShell32 = NULL; SH_GSFP_PROC fpSH_GSFP = NULL; DWORD dwAttr = 0; GetSystemDirectory( szSysPath,sizeof(szSysPath));
lstrcpy(szChannelPath, szSysPath); AddPath( szChannelPath, "shell32.dll" ); hShell32 = LoadLibrary(szChannelPath);
// This stubs runs on IE4 or IE5 systems. Hence shell32 is garunteed
// to have the SHGetSpecialFolderPath API.
if (hShell32) { fpSH_GSFP = (SH_GSFP_PROC)GetProcAddress(hShell32,"SHGetSpecialFolderPathA");
*szChannelPath = '\0'; if (fpSH_GSFP && fpSH_GSFP(NULL, szChannelPath, CSIDL_FAVORITES, FALSE)) { HKEY hKey; DWORD cbSize = sizeof(szChannelName);
// Get the potentially localized name of the Channel folder from the
// registry if it is there. Otherwise use "Channels"
// Then tack this on the favorites path.
//
if ( RegOpenKeyEx(HKEY_LOCAL_MACHINE, REGSTR_PATH_SETUP, 0, KEY_READ, &hKey) == ERROR_SUCCESS) { if (RegQueryValueEx(hKey,"ChannelFolderName", NULL, NULL, (LPBYTE)szChannelName,&cbSize) == ERROR_SUCCESS) { bGetRC = FALSE; } RegCloseKey(hKey); }
if (bGetRC) { HMODULE hLib;
// Get the default name for Channels folder from the
// CdfView.dll
AddPath(szSysPath,"cdfview.dll");
hLib = LoadLibraryEx(szSysPath,NULL,LOAD_LIBRARY_AS_DATAFILE); if (hLib) { if (LoadString(hLib, CHANNEL_FOLDER_RESID,szChannelName,sizeof(szChannelName)) == 0) { // Fail to read the resource, default to English
lstrcpy(szChannelName,"Channels"); }
FreeLibrary(hLib); } } AddPath(szChannelPath, szChannelName); // Check if the folder exists...
dwAttr = GetFileAttributes(szChannelPath); if ((dwAttr != 0xffffffff) && (dwAttr & FILE_ATTRIBUTE_DIRECTORY)) bRet = TRUE; }
FreeLibrary(hShell32); }
return bRet; }
HRESULT IEAccessHideExplorerIcon() { const TCHAR *szKeyComponent = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\CLSID\\{871C5380-42A0-1069-A2EA-08002B30309D}"); const TCHAR *szShellFolder = TEXT("ShellFolder"); const TCHAR *szAttribute = TEXT("Attributes"); DWORD dwValue, dwSize, dwDisposition; HKEY hKeyComponent, hKeyShellFolder; HRESULT hResult = ERROR_SUCCESS;
hResult = RegCreateKeyEx(HKEY_CURRENT_USER, szKeyComponent, NULL, NULL, REG_OPTION_NON_VOLATILE, KEY_CREATE_SUB_KEY, NULL, &hKeyComponent, &dwDisposition);
if (hResult != ERROR_SUCCESS) return hResult;
hResult = RegCreateKeyEx(hKeyComponent, szShellFolder, NULL, NULL, REG_OPTION_NON_VOLATILE, KEY_QUERY_VALUE | KEY_SET_VALUE, NULL, &hKeyShellFolder, &dwDisposition);
RegCloseKey(hKeyComponent); if (hResult == ERROR_SUCCESS) { dwSize = sizeof(dwValue); hResult = RegQueryValueEx( hKeyShellFolder, szAttribute, NULL, NULL, (LPBYTE)&dwValue, &dwSize);
if (hResult != ERROR_SUCCESS) dwValue = 0;
dwValue |= SFGAO_NONENUMERATED;
hResult = RegSetValueEx(hKeyShellFolder, szAttribute, NULL, REG_DWORD, (LPBYTE)&dwValue, sizeof(dwValue));
RegCloseKey(hKeyShellFolder); }
return hResult; }
#define REGVAL_SHOW_CHANNELBAND "Show_ChannelBand"
#define REGVAL_SOURCE "Source"
#define REGVAL_FLAGS "Flags"
#define REG_IE_MAIN "Software\\Microsoft\\Internet Explorer\\Main"
#define REG_DESKTOP_COMP "Software\\Microsoft\\Internet Explorer\\Desktop\\Components"
#define GUID_CHNLBAND "131A6951-7F78-11D0-A979-00C04FD705A2"
#define FLAG_ENABLE_CHNLBAND 0x00002000
/*----------------------------------------------------------
Purpose: Worker function to do the work */
void DoWork( BOOL bInstall ) { TCHAR szHomeDir[MAX_PATH] = { 0 }; HKEY hkeyProfRec = NULL; HKEY hkeyFolderPolicies; BOOL fIntShellMode = FALSE; HMODULE hmodShell = NULL; // HINSTANCE hlib;
TCHAR szPath[MAX_PATH] = { 0 }; DWORD dwMV, dwLV; BOOL fUseShell32 = FALSE;
if ( bInstall ) { if (g_fRunningOnNT) { ExpandEnvironmentStrings("%USERPROFILE%", szHomeDir, ARRAYSIZE(szHomeDir)); } else { szHomeDir[0] = '\0'; LONG err = RegCreateKeyEx(HKEY_CURRENT_USER, c_szProfRecKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ|KEY_WRITE, NULL, &hkeyProfRec, NULL); if (err == ERROR_SUCCESS) { DWORD dwType; DWORD cbData = sizeof(szHomeDir); RegQueryValueEx(hkeyProfRec, c_szHomeDirValue, 0, &dwType, (LPBYTE)szHomeDir, &cbData); } }
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Per User Folders", 0, KEY_QUERY_VALUE, &hkeyFolderPolicies) != ERROR_SUCCESS) hkeyFolderPolicies = NULL;
/* Dynamically link to the SHFlushSFCache API in SHELL32.DLL. Its ordinal
* is 526. This API tells the shell to reinitialize the shell folder cache * in all processes. */
// due to the buggy in the old shell32 of this api function. We are advised to use the new wrap
// which is in shlwapi.dll. Its ordinal is 419.
fIntShellMode = FALSE; GetSystemDirectory( szPath,sizeof( szPath ) ); AddPath( szPath, "shlwapi.dll" ); GetVersionFromFile( szPath, &dwMV, &dwLV, TRUE );
// if major version >= 5.0
//
if ( (dwMV >= 0x00050000)) { hmodShell = ::LoadLibrary(szPath); } else { hmodShell = ::LoadLibrary("shell32.dll"); fUseShell32 = TRUE; }
if (hmodShell != NULL) { if ( !fUseShell32 ) { ::pfnSHFlushSFCacheWrap = (PFNSHFLUSHSFCACHEWRAP)::GetProcAddress(hmodShell, (LPCTSTR)419); if (::pfnSHFlushSFCacheWrap != NULL) { fIntShellMode = TRUE; } } else { ::pfnSHFlushSFCache = (PFNSHFLUSHSFCACHE)::GetProcAddress(hmodShell, (LPCTSTR)526); if (::pfnSHFlushSFCache != NULL) { fIntShellMode = TRUE; } } }
BOOL fDefaultProfile; LPTSTR pchHomeDirEnd = szHomeDir; int cchHomeDir = 0;
if (szHomeDir[0] != '\0') { fDefaultProfile = FALSE; } else { GetWindowsDirectory(szHomeDir, ARRAYSIZE(szHomeDir)); fDefaultProfile = TRUE; } AddPath(szHomeDir,""); pchHomeDirEnd = szHomeDir + lstrlen(szHomeDir); cchHomeDir = ARRAYSIZE(szHomeDir) - (int)(pchHomeDirEnd - szHomeDir);
for (UINT i=0; i<ARRAYSIZE(aFolders); i++) { if (aFolders[i].fIntShellOnly && !fIntShellMode) continue;
if (FAILED(SetupFolder(hkeyProfRec, szHomeDir, pchHomeDirEnd, cchHomeDir, &aFolders[i], fDefaultProfile, hkeyFolderPolicies))) break; }
if (hkeyProfRec != NULL) RegCloseKey(hkeyProfRec);
if (hkeyFolderPolicies != NULL) RegCloseKey(hkeyFolderPolicies);
// import NS stuff if there
ImportNetscapeProxySettings( IMPTPROXY_CALLAFTIE4 ); ImportBookmarks(g_hinst);
if ( !fUseShell32 ) { if (::pfnSHFlushSFCacheWrap != NULL) { (*::pfnSHFlushSFCacheWrap)(); } } else { if (::pfnSHFlushSFCache != NULL) { (*::pfnSHFlushSFCache)(); } }
if (hmodShell != NULL) { ::FreeLibrary(hmodShell); } }
/* BUGBUG - add code to populate the default IE4 favorites, channels, and
* shortcuts here */
// #75346: Upgrade from Win9x to NT5, new users have no Channels folder
// and the ChannelBand pops-up with Fav. entries in it. This hack will
// ensure that the Ch.Band does not pop-up when the new user logs in for
// the first time.
if (bInstall && g_fRunningOnNT5) { if (!DoesChannelFolderExist()) { HKEY hKey; char szNo[] = "No";
// Turn off the Show_ChannelBand for this user.
if (RegOpenKeyEx(HKEY_CURRENT_USER,REG_IE_MAIN, 0, KEY_READ|KEY_WRITE, &hKey) == ERROR_SUCCESS) { RegSetValueEx(hKey, REGVAL_SHOW_CHANNELBAND,0, REG_SZ,(LPBYTE)szNo,sizeof(szNo)); RegCloseKey(hKey); }
// Also turn off the Desktop\Components(ChannelBand)
// Open HKCU\S\M\InternetExplorer\Desktop\Coomponents and enum for
// the ChannelBand GUID. Disable the show flag.
if (RegOpenKeyEx(HKEY_CURRENT_USER, REG_DESKTOP_COMP, 0, KEY_READ|KEY_WRITE, &hKey) == ERROR_SUCCESS) { HKEY hSubKey = NULL; char szSubKey[MAX_PATH]; char szSourceID[130]; DWORD dwSize = sizeof(szSubKey);
for (int i = 0; RegEnumKeyEx(hKey,i, szSubKey, &dwSize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS; i++, dwSize = sizeof(szSubKey)) { // Open this subkey and checks its SourceID.
if (RegOpenKeyEx(hKey,szSubKey,0, KEY_READ|KEY_WRITE, &hSubKey) == ERROR_SUCCESS) { dwSize = sizeof(szSourceID); if ((RegQueryValueEx(hSubKey, REGVAL_SOURCE, NULL, NULL, (LPBYTE)szSourceID,&dwSize) == ERROR_SUCCESS) && (lstrcmpi(szSourceID, GUID_CHNLBAND) == 0)) { // Read the current Flags setting.
DWORD dwFlags = 0;
dwSize = sizeof(dwFlags); RegQueryValueEx(hSubKey,REGVAL_FLAGS, NULL, NULL, (LPBYTE)&dwFlags, &dwSize);
dwFlags &= ~(FLAG_ENABLE_CHNLBAND); dwSize = sizeof(dwFlags); RegSetValueEx(hSubKey, REGVAL_FLAGS, 0, REG_DWORD, (LPBYTE)&dwFlags, dwSize);
// close the key since we have a match and are therefore going to break out
RegCloseKey(hSubKey); break; } RegCloseKey(hSubKey); }
} // end of RegEnum loop
RegCloseKey(hKey); }
} }
// before we do the INF work, we have to run the following function which is
// hack way to fix Russian NT 4.0 localization problem. This only apply to Russian NT box.
if (g_fRunningOnNT && IsBrokenLang() ) { FixRegData(); }
// On win95, due to the RegSave/Restore problem on default valuename, and valuename is space,
// we will do a specific fix for SearchUrl subkey. The generic registry operation fix will in advpack.dll.
if ( (!g_fRunningOnNT) && bInstall ) { FixSearchUrl(); }
// because this stub code is left after uninstall IE5 to do both IE4 and IE5 work, we need the smartness to
// know when to run IE4 inf and when only needed to run IE5 inf
// BUGBUG: this portion of code is very version specific and need to be updated whenever the new Major
// version is shipped. Bud pain!! Most likely, in IE6 time we need to stub EXE to get around the problem!!
if (bInstall) { UINT uIEVer = CheckIEVersion();
// install stub case:
if (uIEVer == IE4) { DoINFWork(bInstall, c_szPrevStubINF, NULL, 0); // NULL means DefaultInstall section
} else if (uIEVer >= IE5) { if (!IsPrevStubRun() ) { // Simulate a pre-installation of IE4. So run IE4 browser stub
// first, then followed by the IE4 Shell stub (if required).
DoINFWork( bInstall, c_szPrevStubINF, NULL, RSC_FLAG_INF | RSC_FLAG_QUIET );
if (IsPrevIE4WebShell()) { DoINFWork( bInstall, c_szPrevStubINF, g_fRunningOnNT ? TEXT("Shell.UserStubNT") : TEXT("Shell.UserStub"), RSC_FLAG_INF | RSC_FLAG_QUIET); }
}
DoINFWork( bInstall, c_szStubINFFile, NULL, 0 ); ProcessMouseException(); } } else { // uninstall stub case: use HKCU value to make sure which version it is uninstalling
UINT uUninstIEVer = CheckUninstIEVersion();
if (uUninstIEVer == IE4) { DoINFWork(bInstall, c_szPrevStubINF, NULL, 0); } else if (uUninstIEVer == IE5) { DoINFWork(bInstall, c_szStubINFFile, NULL, 0); } else if (uUninstIEVer == IE55 || uUninstIEVer == IE6) { DoINFWork(bInstall, c_szStubINFFile, NULL, 0); }
}
if (bInstall && g_fRunningOnWinXP) IEAccessHideExplorerIcon(); }
INT WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpszCmdLine, INT nCmdShow ) { BOOL bInstall;
if ( !lpszCmdLine || !*lpszCmdLine ) bInstall = TRUE; else bInstall = FALSE;
DoWork( bInstall );
TCHAR szCmdLine[MAX_PATH];
GetSystemDirectory(szCmdLine, ARRAYSIZE(szCmdLine)); AddPath(szCmdLine, TEXT("shmgrate.exe")); ShellExecute(NULL, NULL, szCmdLine, TEXT("OCInstallUserConfigIE"), NULL, SW_SHOWDEFAULT);
return 0; }
// stolen from the CRT, used to shrink our code
int _stdcall ModuleEntry(void) { STARTUPINFO si; LPSTR pszCmdLine = GetCommandLine();
g_hinst = GetModuleHandle(NULL);
#ifdef DEBUG
CcshellGetDebugFlags();
if (IsFlagSet(g_dwBreakFlags, BF_ONOPEN)) DebugBreak();
#endif
if (FAILED(OleInitialize(NULL))) return 0;
OSVERSIONINFO osvi;
osvi.dwOSVersionInfoSize = sizeof(osvi); GetVersionEx(&osvi); if (VER_PLATFORM_WIN32_NT == osvi.dwPlatformId) { g_fRunningOnNT = TRUE;
if (osvi.dwMajorVersion >= 5) { g_fRunningOnNT5 = TRUE; if (osvi.dwMinorVersion >= 1) g_fRunningOnWinXP = TRUE; } } else if ((VER_PLATFORM_WIN32_WINDOWS == osvi.dwPlatformId) && (0 == osvi.dwMinorVersion)) { g_fRunningOnWin95 = TRUE; }
// turn off critical error stuff
SetErrorMode(SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS);
if ( *pszCmdLine == '\"' ) { /*
* Scan, and skip over, subsequent characters until * another double-quote or a null is encountered. */ while ( *++pszCmdLine && (*pszCmdLine != '\"') ); /*
* If we stopped on a double-quote (usual case), skip * over it. */ if ( *pszCmdLine == '\"' ) pszCmdLine++; } else { while (*pszCmdLine > ' ') pszCmdLine++; }
/*
* Skip past any white space preceeding the second token. */ while (*pszCmdLine && (*pszCmdLine <= ' ')) { pszCmdLine++; }
si.dwFlags = 0; GetStartupInfoA(&si);
WinMain(GetModuleHandle(NULL), NULL, pszCmdLine, si.dwFlags & STARTF_USESHOWWINDOW ? si.wShowWindow : SW_SHOWDEFAULT);
OleUninitialize();
ExitProcess(0); return 0; // We never come here
}
UINT CheckUninstIEVersion() { HKEY hKey; DWORD dwSize; TCHAR szPreIEVer[50]; WORD wPreIEVer[4]; UINT uRet = LESSIE4;
if ( RegOpenKeyEx( HKEY_CURRENT_USER, c_szActInstalledIEGUIDRestore, 0, KEY_READ, &hKey) != ERROR_SUCCESS ) { if ( RegOpenKeyEx( HKEY_CURRENT_USER, c_szActInstalledIEGUID, 0, KEY_READ, &hKey) != ERROR_SUCCESS ) { return uRet; } }
dwSize = sizeof( szPreIEVer ); if ( RegQueryValueEx(hKey, TEXT("Version"), NULL, NULL, (LPBYTE)szPreIEVer, &dwSize) == ERROR_SUCCESS ) { ConvertVersionString( szPreIEVer, wPreIEVer, ',' ); if ((wPreIEVer[0] == 0x0004) && (wPreIEVer[1]>=0x0047)) uRet = IE4; else if (wPreIEVer[0] == 0x0005) { if (wPreIEVer[1] >= 0x0032) uRet = IE55; else uRet = IE5; } else if (wPreIEVer[0] == 0x0006) uRet = IE6; } RegCloseKey(hKey);
return uRet; }
BOOL IsPrevIE4() { HKEY hKey; DWORD dwSize; TCHAR szPreIEVer[50]; WORD wPreIEVer[4]; BOOL bRet = FALSE;
if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, c_szIE4Setup, 0, KEY_READ, &hKey) == ERROR_SUCCESS ) { dwSize = sizeof( szPreIEVer ); if ( RegQueryValueEx(hKey, c_szPreIEVer, NULL, NULL, (LPBYTE)szPreIEVer, &dwSize) == ERROR_SUCCESS ) { ConvertVersionString( szPreIEVer, wPreIEVer, '.' ); if ( (wPreIEVer[0] == 0x0004) && (wPreIEVer[1]>=0x0047) ) { bRet = TRUE; } } RegCloseKey(hKey); } return bRet; }
BOOL IsPrevIE4WebShell() { HKEY hKey; DWORD dwSize; TCHAR szPreShellVer[50]; WORD wPreShellVer[4]; BOOL bRet = FALSE;
if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, c_szIE4Setup, 0, KEY_READ, &hKey) == ERROR_SUCCESS ) { dwSize = sizeof( szPreShellVer ); if ( RegQueryValueEx(hKey, c_szPreShellVer, NULL, NULL, (LPBYTE)szPreShellVer, &dwSize) == ERROR_SUCCESS ) { ConvertVersionString( szPreShellVer, wPreShellVer, '.' ); if ((wPreShellVer[0] == 0x0004) && (wPreShellVer[1]>=0x0047) ) { bRet = TRUE; } } RegCloseKey(hKey); } return bRet; }
const TCHAR c_szMouseExceptions[] = TEXT("Control Panel\\Microsoft Input Devices\\Mouse\\Exceptions"); // This gets written to the registry
const TCHAR c_szFilename[] = TEXT("FileName"); const TCHAR c_szInternetExplorer[] = TEXT("Internet Explorer"); const TCHAR c_szDescription[] = TEXT("Description"); const TCHAR c_szVersion[] = TEXT("Version"); const TCHAR c_szIE[] = TEXT("IEXPLORE.EXE"); #define IE_VERSION 0x50000
void ProcessMouseException() { HKEY hKey; HKEY hSubKey; DWORD dwIndex = 1001; // start with 1001.
TCHAR szSubKey[16]; BOOL bCannotUse = TRUE; TCHAR szData[MAX_PATH];
RemoveOldMouseException(); if (RegCreateKeyEx(HKEY_CURRENT_USER, c_szMouseExceptions, 0, NULL, 0, KEY_WRITE|KEY_READ, NULL, &hKey, NULL) == ERROR_SUCCESS) { while (bCannotUse) { wsprintf(szSubKey, "%d", dwIndex); if (RegOpenKeyEx(hKey, szSubKey, 0, KEY_READ, &hSubKey) == ERROR_SUCCESS) { RegCloseKey(hSubKey); dwIndex++; } else bCannotUse = FALSE; } if (RegCreateKeyEx(hKey, szSubKey, 0, NULL, 0, KEY_WRITE, NULL, &hSubKey, NULL) == ERROR_SUCCESS) { if (!LoadString(g_hinst, IDS_IE_APPNAME, szData, sizeof(szData))) lstrcpy(szData, c_szInternetExplorer); RegSetValueEx(hSubKey, c_szDescription, 0, REG_SZ, (LPBYTE)szData, (lstrlen(szData)+1) * sizeof(TCHAR)); RegSetValueEx(hSubKey, c_szFilename, 0, REG_SZ, (LPBYTE)c_szIE, (lstrlen(c_szIE)+1) * sizeof(TCHAR)); dwIndex = IE_VERSION; RegSetValueEx(hSubKey, c_szVersion, 0, REG_DWORD, (LPBYTE)&dwIndex , sizeof(DWORD)); RegCloseKey(hSubKey); } RegCloseKey(hKey); } }
void RemoveOldMouseException() { HKEY hKey; HKEY hSubKey; DWORD dwIndex = 0; BOOL bFound = FALSE; LONG lRet = ERROR_SUCCESS; TCHAR szSubKey[MAX_PATH]; DWORD dwSize; TCHAR szData[MAX_PATH];
if (RegOpenKeyEx(HKEY_CURRENT_USER, c_szMouseExceptions, 0, KEY_READ|KEY_WRITE, &hKey) == ERROR_SUCCESS) { while (!bFound && (lRet == ERROR_SUCCESS)) { dwSize = sizeof(szSubKey); lRet = RegEnumKeyEx(hKey, dwIndex, szSubKey, &dwSize, NULL, NULL, NULL, NULL); if (lRet == ERROR_SUCCESS) { if (RegOpenKeyEx(hKey, szSubKey, 0, KEY_READ, &hSubKey) == ERROR_SUCCESS) { dwSize = sizeof(szData); if (RegQueryValueEx(hSubKey, c_szFilename,NULL, NULL, (LPBYTE)szData, &dwSize) == ERROR_SUCCESS) { bFound = (lstrcmpi(szData, c_szIE) == 0); } RegCloseKey(hSubKey); } if (bFound) { RegDeleteKey(hKey, szSubKey); } else dwIndex++; } } RegCloseKey(hKey); } }
|