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.

1895 lines
67 KiB

  1. #include "priv.h"
  2. #include "advpub.h"
  3. #include "sdsutils.h"
  4. #include "utils.h"
  5. #include "convert.h"
  6. #include "regstr.h"
  7. const TCHAR c_szAppName[] = TEXT("ie4uinit");
  8. const TCHAR c_szProfRecKey[] = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\ProfileReconciliation");
  9. const TCHAR c_szHomeDirValue[] = TEXT("ProfileDirectory");
  10. const TCHAR c_szExplorerKey[] = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders");
  11. const TCHAR c_szIExploreMain[] = TEXT( "Software\\microsoft\\Internet Explorer\\Main" );
  12. const TCHAR c_szIExplorerSearchUrl[] = TEXT( "Software\\microsoft\\Internet Explorer\\SearchUrl" );
  13. const TCHAR c_szIExplorer[] = TEXT( "Software\\microsoft\\Internet Explorer" );
  14. const TCHAR c_szCentralFile[] = TEXT("CentralFile");
  15. const TCHAR c_szLocalFile[] = TEXT("LocalFile");
  16. const TCHAR c_szName[] = TEXT("Name");
  17. const TCHAR c_szRegKey[] = TEXT("RegKey");
  18. const TCHAR c_szRegValue[] = TEXT("RegValue");
  19. const TCHAR c_szMustBeRelative[] = TEXT("MustBeRelative");
  20. const TCHAR c_szDefault[] = TEXT("Default");
  21. const TCHAR c_szDefaultDir[] = TEXT("DefaultDir");
  22. const TCHAR c_szIExploreLnk[] = TEXT("Internet Explorer.lnk" );
  23. const TCHAR c_szIExploreBackLnk[] = TEXT("Internet Explorer Lnk.bak" );
  24. const TCHAR c_szIExploreBackLnkIni[] = TEXT("IELnkbak.ini" );
  25. const TCHAR c_szIESetupPath[] = TEXT( "software\\microsoft\\IE Setup\\setup" );
  26. const TCHAR c_szIE4Path[] = TEXT( "software\\microsoft\\IE4" );
  27. const TCHAR c_szAdvINFSetup[] = TEXT( "software\\microsoft\\Advanced INF Setup" );
  28. const TCHAR c_szIEModRollback[] = TEXT( "IE CompList" );
  29. const TCHAR c_szRegBackup[] = TEXT( "RegBackup" );
  30. const TCHAR c_szInstallMode[] = TEXT("InstallMode");
  31. const TCHAR c_szStarDotStar[] = "*.*";
  32. const TCHAR c_szSearchUrl[] = TEXT("CleanSearchUrl");
  33. const TCHAR c_szPrevStubINF[] = TEXT("ie4uinit.inf");
  34. const TCHAR c_szStubINFFile[] = TEXT("ieuinit.inf");
  35. const TCHAR c_szActInstalledIEGUID[] = TEXT( "SOFTWARE\\Microsoft\\Active Setup\\Installed Components\\{89820200-ECBD-11cf-8B85-00AA005B4383}");
  36. const TCHAR c_szActInstalledIEGUIDRestore[] = TEXT( "SOFTWARE\\Microsoft\\Active Setup\\Installed Components\\{89820200-ECBD-11cf-8B85-00AA005B4383}.Restore");
  37. const TCHAR c_szMyDocsDLL[] = TEXT("\\mydocs.dll");
  38. const TCHAR c_szIE4Setup[]= TEXT("Software\\Microsoft\\IE Setup\\Setup");
  39. const TCHAR c_szPreIEVer[]= TEXT("PreviousIESysFile");
  40. const TCHAR c_szPreShellVer[]= TEXT("PreviousShellFile");
  41. typedef VOID (*LPFNMYDOCSINIT)(VOID);
  42. // used only at install stub time
  43. BOOL IsPrevIE4();
  44. BOOL IsPrevIE4WebShell();
  45. UINT CheckIEVersion();
  46. void RemoveOldMouseException();
  47. void ProcessMouseException();
  48. // used at uninstall stub time
  49. UINT CheckUninstIEVersion();
  50. //
  51. //====== DllGetVersion =======================================================
  52. //
  53. typedef struct _DllVersionInfo
  54. {
  55. DWORD cbSize;
  56. DWORD dwMajorVersion; // Major version
  57. DWORD dwMinorVersion; // Minor version
  58. DWORD dwBuildNumber; // Build number
  59. DWORD dwPlatformID; // DLLVER_PLATFORM_*
  60. } DLLVERSIONINFO;
  61. // Platform IDs for DLLVERSIONINFO
  62. //#define DLLVER_PLATFORM_WINDOWS 0x00000001 // Windows 95
  63. //#define DLLVER_PLATFORM_NT 0x00000002 // Windows NT
  64. //
  65. // The caller should always GetProcAddress("DllGetVersion"), not
  66. // implicitly link to it.
  67. //
  68. typedef HRESULT (CALLBACK* DLLGETVERSIONPROC)(DLLVERSIONINFO *);
  69. //
  70. //====== DllGetVersion =from shlwapi.h==========================================
  71. //
  72. HINSTANCE g_hinst;
  73. BOOL g_fRunningOnNT = FALSE;
  74. BOOL g_fRunningOnNT5 = FALSE;
  75. BOOL g_fRunningOnWinXP = FALSE;
  76. BOOL g_fRunningOnWin95 = FALSE;
  77. // shlwapi.dll api
  78. typedef void (* PFNSHFLUSHSFCACHEWRAP)();
  79. PFNSHFLUSHSFCACHEWRAP pfnSHFlushSFCacheWrap = NULL;
  80. // old shell32.dll api
  81. typedef void (* PFNSHFLUSHSFCACHE)();
  82. PFNSHFLUSHSFCACHE pfnSHFlushSFCache = NULL;
  83. struct FolderDescriptor;
  84. typedef void (* PFNINITFOLDER)(FolderDescriptor *pFolder, LPTSTR pszBaseName, LPTSTR pszUserDirectory);
  85. void InitFolderFromDefault(FolderDescriptor *pFolder, LPTSTR pszBaseName, LPTSTR pszUserDirectory);
  86. void InitFolderMyDocs(FolderDescriptor *pFolder, LPTSTR pszBaseName, LPTSTR pszUserDirectory);
  87. struct FolderDescriptor {
  88. UINT idsDirName; /* Resource ID for directory name */
  89. LPCTSTR pszRegKey; /* Name of reg key under which to set path */
  90. LPCTSTR pszRegValue; /* Name of reg value to set path in */
  91. LPCTSTR pszStaticName; /* Static name for ProfileReconciliation subkey */
  92. LPCTSTR pszFiles; /* Spec for which files should roam */
  93. PFNINITFOLDER InitFolder; /* Function to init contents */
  94. DWORD dwAttribs; /* Desired directory attributes */
  95. BOOL fIntShellOnly : 1; /* TRUE if should not do this in browser only mode */
  96. BOOL fMustBePerUser : 1; /* TRUE if should always be forced per-user on all platforms */
  97. BOOL fDefaultInRoot : 1; /* TRUE if default location is root of drive, not windows dir */
  98. BOOL fWriteToUSF : 1; /* TRUE if we should write to User Shell Folders to work around Win95 bug */
  99. } aFolders[] = {
  100. { IDS_CSIDL_DESKTOP_L, c_szExplorerKey, TEXT("Desktop"), TEXT("Desktop"), c_szStarDotStar, InitFolderFromDefault, FILE_ATTRIBUTE_DIRECTORY, TRUE, FALSE, FALSE, FALSE } ,
  101. { IDS_CSIDL_RECENT_L, c_szExplorerKey, TEXT("Recent"), TEXT("Recent"), c_szStarDotStar, InitFolderFromDefault, FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_DIRECTORY, TRUE, FALSE, FALSE, FALSE } ,
  102. { IDS_CSIDL_NETHOOD_L, c_szExplorerKey, TEXT("NetHood"), TEXT("NetHood"), c_szStarDotStar, InitFolderFromDefault, FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_DIRECTORY, TRUE, FALSE, FALSE, FALSE } ,
  103. { IDS_CSIDL_PERSONAL_L, c_szExplorerKey, TEXT("Personal"), TEXT("Personal"), c_szStarDotStar, InitFolderMyDocs, FILE_ATTRIBUTE_DIRECTORY, TRUE, FALSE, TRUE, FALSE } ,
  104. { IDS_CSIDL_FAVORITES_L, c_szExplorerKey, TEXT("Favorites"), TEXT("Favorites"), c_szStarDotStar, InitFolderFromDefault, FILE_ATTRIBUTE_DIRECTORY, FALSE, FALSE, FALSE, TRUE },
  105. { IDS_CSIDL_APPDATA_L, c_szExplorerKey, TEXT("AppData"), TEXT("AppData"), c_szStarDotStar, InitFolderFromDefault, FILE_ATTRIBUTE_DIRECTORY, FALSE, TRUE, FALSE, FALSE },
  106. { IDS_CSIDL_CACHE_L, c_szExplorerKey, TEXT("Cache"), TEXT("Cache"), TEXT(""), NULL, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_DIRECTORY, FALSE, FALSE, FALSE, FALSE },
  107. { IDS_CSIDL_COOKIES_L, c_szExplorerKey, TEXT("Cookies"), TEXT("Cookies"), c_szStarDotStar, NULL, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_DIRECTORY, FALSE, TRUE, FALSE, FALSE },
  108. { IDS_CSIDL_HISTORY_L, c_szExplorerKey, TEXT("History"), TEXT("History"), c_szStarDotStar, NULL, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_DIRECTORY, FALSE, TRUE, FALSE, FALSE },
  109. };
  110. // Verion number 4.71
  111. #define IE_4_MS_VERSION 0x00040047
  112. // Build number 1712.0 (IE4.0 RTW)
  113. #define IE_4_LS_VERSION 0x06B00000
  114. // IE5 Major version
  115. #define IE_5_MS_VERSION 0x00050000
  116. // IE5.5 Major version
  117. #define IE_55_MS_VERSION 0x00050032
  118. // IE6 (Whistler) Major version
  119. #define IE_6_MS_VERSION 0x00060000
  120. // check IE version return code
  121. #define LESSIE4 0
  122. #define IE4 1
  123. #define IE5 2
  124. #define IE55 3
  125. #define IE6 4 // Whistler
  126. BOOL CheckWebViewShell(UINT *puiShell32)
  127. {
  128. HINSTANCE hInstShell32;
  129. DLLGETVERSIONPROC fpGetDllVersion;
  130. char szShell32[MAX_PATH];
  131. BOOL bRet = FALSE;
  132. GetSystemDirectory(szShell32, sizeof(szShell32));
  133. AddPath(szShell32,"Shell32.dll");
  134. hInstShell32 = LoadLibrary(szShell32);
  135. if ( hInstShell32 )
  136. {
  137. DLLVERSIONINFO dllinfo;
  138. fpGetDllVersion = (DLLGETVERSIONPROC)GetProcAddress(hInstShell32, "DllGetVersion");
  139. bRet = (fpGetDllVersion != NULL);
  140. if (puiShell32 && fpGetDllVersion)
  141. {
  142. dllinfo.cbSize = sizeof(DLLVERSIONINFO);
  143. if ( fpGetDllVersion(&dllinfo) == NOERROR )
  144. *puiShell32 = dllinfo.dwMajorVersion;
  145. else
  146. *puiShell32 = 0; // error case, should never be here
  147. }
  148. FreeLibrary(hInstShell32);
  149. }
  150. return bRet;
  151. }
  152. // this code need to be updated whenever the new major version is released!!
  153. UINT CheckIEVersion()
  154. {
  155. char szIE[MAX_PATH] = { 0 };
  156. DWORD dwMSVer, dwLSVer;
  157. GetSystemDirectory(szIE, sizeof(szIE));
  158. AddPath(szIE, "shdocvw.dll");
  159. GetVersionFromFile(szIE, &dwMSVer, &dwLSVer, TRUE);
  160. if (dwMSVer < IE_4_MS_VERSION)
  161. {
  162. return LESSIE4;
  163. }
  164. if ((dwMSVer >= IE_4_MS_VERSION) && (dwMSVer < IE_5_MS_VERSION))
  165. {
  166. return IE4;
  167. }
  168. if ((dwMSVer >= IE_5_MS_VERSION) && (dwMSVer < IE_55_MS_VERSION))
  169. {
  170. return IE5;
  171. }
  172. if ((dwMSVer >= IE_55_MS_VERSION) && (dwMSVer < IE_6_MS_VERSION))
  173. {
  174. return IE55;
  175. }
  176. if (dwMSVer == IE_6_MS_VERSION)
  177. {
  178. return IE6;
  179. }
  180. #ifdef DEBUG
  181. OutputDebugStringA("CheckIEVersion - unknown shdocvw.dll version# ! Need to add new IE_XX_MS_VERSION id\n");
  182. DebugBreak();
  183. #endif
  184. return IE6;
  185. }
  186. void InitFolderFromDefault(FolderDescriptor *pFolder, LPTSTR pszBaseName, LPTSTR pszUserDirectory)
  187. {
  188. SHFILEOPSTRUCT fos;
  189. TCHAR szFrom[MAX_PATH];
  190. lstrcpy(szFrom, pszBaseName);
  191. /* Before we build the complete source filespec, check to see if the
  192. * directory exists. In the case of lesser-used folders such as
  193. * "Application Data", the default may not have ever been created.
  194. * In that case, we have no contents to copy.
  195. */
  196. DWORD dwAttr = GetFileAttributes(szFrom);
  197. if (dwAttr == 0xffffffff || !(dwAttr & FILE_ATTRIBUTE_DIRECTORY))
  198. return;
  199. AddPath(szFrom,"");
  200. lstrcat(szFrom, pFolder->pszFiles);
  201. szFrom[lstrlen(szFrom)+1] = '\0'; /* double null terminate from string */
  202. pszUserDirectory[lstrlen(pszUserDirectory)+1] = '\0'; /* and to string */
  203. fos.hwnd = NULL;
  204. fos.wFunc = FO_COPY;
  205. fos.pFrom = szFrom;
  206. fos.pTo = pszUserDirectory;
  207. fos.fFlags = FOF_NOCONFIRMATION | FOF_NOCONFIRMMKDIR | FOF_NOERRORUI;
  208. fos.fAnyOperationsAborted = FALSE;
  209. fos.hNameMappings = NULL;
  210. fos.lpszProgressTitle = NULL;
  211. SHFileOperation(&fos);
  212. }
  213. void InitFolderMyDocs(FolderDescriptor *pFolder, LPTSTR pszBaseName, LPTSTR pszUserDirectory)
  214. {
  215. HRESULT hres = E_FAIL;
  216. TCHAR szFrom[MAX_PATH];
  217. TCHAR szPathDest[MAX_PATH];
  218. BOOL fCopyLnk;
  219. lstrcpy(szFrom, pszBaseName);
  220. /* Before we build the complete source filespec, check to see if the
  221. * directory exists. In the case of lesser-used folders such as
  222. * "Application Data", the default may not have ever been created.
  223. * In that case, we have no contents to copy.
  224. */
  225. DWORD dwAttr = GetFileAttributes(szFrom);
  226. if (dwAttr == 0xffffffff || !(dwAttr & FILE_ATTRIBUTE_DIRECTORY))
  227. return;
  228. IShellLink *psl;
  229. if (FAILED(CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
  230. IID_IShellLink, (void **)&psl)))
  231. return;
  232. if (SHGetNewLinkInfo(szFrom,
  233. pszUserDirectory, szPathDest, &fCopyLnk,
  234. SHGNLI_PREFIXNAME)) {
  235. if (fCopyLnk) {
  236. if (GetFileAttributes(szPathDest) == 0xffffffff &&
  237. CopyFile(szFrom, szPathDest, TRUE)) {
  238. hres = S_OK;
  239. SHChangeNotify(SHCNE_CREATE, SHCNF_PATH, szPathDest, NULL);
  240. SHChangeNotify(SHCNE_FREESPACE, SHCNF_PATH, szPathDest, NULL);
  241. } else {
  242. // DebugMsg(TF_ERROR, TEXT("****copy failed (%d)"),GetLastError());
  243. }
  244. } else {
  245. IPersistFile *ppf;
  246. psl->SetPath(szFrom);
  247. //
  248. // make sure the working directory is set to the same
  249. // directory as the app (or document).
  250. //
  251. // dont do this for non-FS pidls (ie control panel)
  252. //
  253. // what about a UNC directory? we go ahead and set
  254. // it, wont work for a WIn16 app.
  255. //
  256. if (!PathIsDirectory(szFrom)) {
  257. PathRemoveFileSpec(szFrom);
  258. psl->SetWorkingDirectory(szFrom);
  259. }
  260. /* We only did the SHGetNewLinkInfo for the fCopyLnk flag;
  261. * load a resource string to get a more descriptive name
  262. * for the shortcut.
  263. */
  264. LPTSTR pszPathEnd = PathFindFileName(szPathDest);
  265. LoadString(g_hinst, IDS_MYDOCS_SHORTCUT, pszPathEnd, ARRAYSIZE(szPathDest) - (int)(pszPathEnd - szPathDest));
  266. if (GetFileAttributes(szPathDest) == 0xffffffff) {
  267. hres = psl->QueryInterface(IID_IPersistFile, (void **)&ppf);
  268. if (SUCCEEDED(hres)) {
  269. #ifdef UNICODE
  270. hres = ppf->Save(szPathDest, TRUE);
  271. #else
  272. WCHAR wszPath[MAX_PATH];
  273. MultiByteToWideChar(CP_ACP, 0, szPathDest, -1, wszPath, ARRAYSIZE(wszPath));
  274. hres = ppf->Save(wszPath, TRUE);
  275. #endif
  276. ppf->Release();
  277. }
  278. }
  279. }
  280. }
  281. psl->Release();
  282. }
  283. HRESULT SetupFolder(HKEY hkeyProfRec, LPTSTR pszHomeDir, LPTSTR pszHomeDirEnd,
  284. int cchHomeDir, FolderDescriptor *pFolder, BOOL fDefaultProfile,
  285. HKEY hkeyFolderPolicies)
  286. {
  287. DWORD dwType, cbData;
  288. BOOL fMakeFolderPerUser;
  289. BOOL fGotFromPolicy = FALSE;
  290. /* Figure out whether to make this folder be per-user or not. On NT we
  291. * make everything per-user. Some folders (notably Application Data)
  292. * are also always per-user. The default for everything else is to not
  293. * make it per-user here unless a policy is set to force it. If we do
  294. * not want to make it per-user here, we'll just leave it the way it is;
  295. * of course, the folder could have already been made per-user by some
  296. * other means.
  297. *
  298. * "Make per-user" means set a profile-relative path if we're not operating
  299. * on the default profile, plus adding a ProfileReconciliation key on win95
  300. * (any profile, including default).
  301. */
  302. if (hkeyFolderPolicies != NULL) {
  303. DWORD dwFlag;
  304. cbData = sizeof(dwFlag);
  305. if (RegQueryValueEx(hkeyFolderPolicies, pFolder->pszStaticName, NULL,
  306. &dwType, (LPBYTE)&dwFlag, &cbData) == ERROR_SUCCESS &&
  307. (dwType == REG_DWORD || (dwType == REG_BINARY && cbData == sizeof(dwFlag)))) {
  308. fMakeFolderPerUser = dwFlag;
  309. fGotFromPolicy = TRUE;
  310. }
  311. }
  312. if (!fGotFromPolicy)
  313. fMakeFolderPerUser = (g_fRunningOnNT || pFolder->fMustBePerUser);
  314. TCHAR szUserHomeDir[MAX_PATH];
  315. *pszHomeDirEnd = '\0'; /* strip off dir name from last time through */
  316. lstrcpy(szUserHomeDir, pszHomeDir);
  317. PathRemoveBackslash(szUserHomeDir);
  318. /* Get the localized name for the directory, as it should appear in
  319. * the file system.
  320. */
  321. int cchDir = LoadString(g_hinst, pFolder->idsDirName, pszHomeDirEnd, cchHomeDir);
  322. if (!cchDir)
  323. return HRESULT_FROM_WIN32(GetLastError());
  324. cchDir++; /* count null character */
  325. /* Create the reg key where a pointer to the new directory is supposed to
  326. * be stored, and write the path there.
  327. */
  328. HKEY hkeyFolder;
  329. LONG err = RegCreateKeyEx(HKEY_CURRENT_USER, pFolder->pszRegKey,0, NULL, REG_OPTION_NON_VOLATILE,
  330. KEY_READ|KEY_WRITE, NULL, &hkeyFolder, NULL);
  331. if (err != ERROR_SUCCESS)
  332. return HRESULT_FROM_WIN32(err);
  333. /* Build the default location for this directory (usually just under the
  334. * Windows directory, except for My Documents). We'll use this as the
  335. * location to create if nothing is in the registry, and also to compare
  336. * the registry-set location to see if we should move it or leave it
  337. * alone.
  338. */
  339. TCHAR szDefaultDir[MAX_PATH];
  340. GetWindowsDirectory(szDefaultDir, ARRAYSIZE(szDefaultDir));
  341. if (pFolder->fDefaultInRoot) {
  342. LPTSTR pszRoot;
  343. if (PathIsUNC(szDefaultDir)) {
  344. pszRoot = ANSIStrChr(szDefaultDir, (WORD)'\\');
  345. if (pszRoot != NULL)
  346. pszRoot = ANSIStrChr(pszRoot+1, (WORD)'\\');
  347. if (pszRoot != NULL)
  348. *(pszRoot+1) = '\0';
  349. }
  350. else {
  351. pszRoot = CharNext(szDefaultDir);
  352. if (*pszRoot == ':')
  353. pszRoot++;
  354. if (*pszRoot == '\\')
  355. pszRoot++;
  356. *pszRoot = '\0';
  357. }
  358. }
  359. else {
  360. AddPath(szDefaultDir, "");
  361. }
  362. lstrcat(szDefaultDir, pszHomeDirEnd);
  363. /* Get the path that was recorded for this folder before we ran. We will
  364. * use it as the default for migrating contents, unless it's not there or
  365. * it's already set to the new directory. In either of those cases we use
  366. * the localized name, relative to the Windows directory.
  367. */
  368. TCHAR szOldDir[MAX_PATH];
  369. BOOL fDefaultLocation = FALSE;
  370. cbData = sizeof(szOldDir);
  371. szOldDir[0] = '\0';
  372. err = SDSQueryValueExA(hkeyFolder, pFolder->pszRegValue, 0, &dwType,
  373. (LPBYTE)szOldDir, &cbData);
  374. BOOL fGotPathFromRegistry = (err == ERROR_SUCCESS);
  375. if (!fGotPathFromRegistry) {
  376. lstrcpy(szOldDir, szDefaultDir);
  377. if (!pFolder->fDefaultInRoot)
  378. fDefaultLocation = TRUE;
  379. }
  380. else {
  381. /* Previous path is present in the registry. If it's a net path,
  382. * it's probably been set by system policies and we want to leave
  383. * it the way it is.
  384. */
  385. BOOL fIsNet = FALSE;
  386. if (PathIsUNC(szOldDir))
  387. fIsNet = TRUE;
  388. else {
  389. int nDriveNumber = PathGetDriveNumber(szOldDir);
  390. if (nDriveNumber != -1) {
  391. TCHAR szRootPath[4] = TEXT("X:\\");
  392. szRootPath[0] = nDriveNumber + TEXT('A');
  393. if (::GetDriveType(szRootPath) == DRIVE_REMOTE)
  394. fIsNet = TRUE;
  395. }
  396. }
  397. if (fIsNet) {
  398. RegCloseKey(hkeyFolder);
  399. return S_OK;
  400. }
  401. }
  402. LPSTR pszDirToCreate;
  403. BOOL fInit = TRUE;
  404. if (fDefaultProfile || !fMakeFolderPerUser) {
  405. /* On the default profile, the directory path we want is the one we
  406. * read from the registry (or the default windir-based path we built).
  407. * Also, most folders we want to keep as the user has them already
  408. * configured. In either case, we do not initialize the contents
  409. * because there's no place to initialize them from in the first case,
  410. * and we want the contents undisturbed in the second case.
  411. */
  412. pszDirToCreate = szOldDir;
  413. fInit = FALSE;
  414. }
  415. else {
  416. /* We want to give this user a profile-relative path for this folder.
  417. * However, if they already have an explicit non-default path set for
  418. * this folder, we don't bother initializing it since they already have
  419. * it set up someplace where they want it.
  420. */
  421. if (fGotPathFromRegistry &&
  422. ::GetFileAttributes(szOldDir) != 0xffffffff &&
  423. lstrcmpi(szOldDir, szDefaultDir)) {
  424. pszDirToCreate = szOldDir;
  425. fInit = FALSE;
  426. }
  427. else {
  428. pszDirToCreate = pszHomeDir;
  429. }
  430. }
  431. /* Only write the path out to the registry if we didn't originally get it
  432. * from the registry.
  433. */
  434. if (!fGotPathFromRegistry) {
  435. /* If we're writing to the User Shell Folders key, only write non-
  436. * default paths there.
  437. */
  438. /* There are some applications (German Corel Office 7) which
  439. * depend on the entry being in User Shell Folders for some shell
  440. * folders. This dependency is due to the fact that the entry use
  441. * to be created always by down level browsers (IE30).
  442. *
  443. * We do not do this generically because no value under
  444. * USF is supposed to mean "use the one in the Windows
  445. * directory", whereas an absolute path means "use that
  446. * path"; if there's a path under USF, it will be used
  447. * literally, which is a problem if the folder is set up
  448. * to use the shared folder location but roams to a machine
  449. * with Windows installed in a different directory.
  450. */
  451. if ((pFolder->pszRegKey != c_szExplorerKey) ||
  452. pszDirToCreate != szOldDir ||
  453. !fDefaultLocation ||
  454. pFolder->fWriteToUSF) {
  455. if (g_fRunningOnNT) {
  456. TCHAR szRegPath[MAX_PATH];
  457. lstrcpy(szRegPath, TEXT("%USERPROFILE%\\"));
  458. lstrcat(szRegPath, pszHomeDirEnd);
  459. RegSetValueEx( hkeyFolder, pFolder->pszRegValue, 0, REG_EXPAND_SZ,
  460. (LPBYTE)szRegPath, (lstrlen(szRegPath)+1) * sizeof(TCHAR));
  461. }
  462. else {
  463. if (!pFolder->fWriteToUSF || g_fRunningOnWin95)
  464. {
  465. RegSetValueEx(hkeyFolder, pFolder->pszRegValue, 0, REG_SZ,
  466. (LPBYTE)pszDirToCreate, (lstrlen(pszDirToCreate)+1) * sizeof(TCHAR));
  467. }
  468. else
  469. {
  470. // 98/12/30 #238093 (IE#50598 / Office#188177) vtan: There exists a
  471. // case where HKCU\..\Explorer\User Shell Folders\Favorites does NOT
  472. // exist on Win98 (unknown cause). This case simulates a Windows95
  473. // bug which the fWriteToUSF flag is designed to get around. In the
  474. // German Win9x this replaces the Favorites folder in User Shell
  475. // Folders key with the english name and this is propogated below to
  476. // Shell Folders which destroys the localization.
  477. // In this case we want to write the value of the key in Shell Folders
  478. // (if that points to a valid directory) to the User Shell Folders key
  479. // and just let the code below write the same value back to the Shell
  480. // Folders key. A little bit of wasted effort.
  481. HKEY hkeySF;
  482. if (RegCreateKeyEx(HKEY_CURRENT_USER,
  483. "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders",
  484. 0,
  485. NULL,
  486. REG_OPTION_NON_VOLATILE,
  487. KEY_READ,
  488. NULL,
  489. &hkeySF,
  490. NULL) == ERROR_SUCCESS)
  491. {
  492. DWORD dwRegDataType, dwRegDataSize;
  493. TCHAR szRegValue[MAX_PATH];
  494. dwRegDataSize = sizeof(szRegValue);
  495. if (RegQueryValueEx(hkeySF,
  496. pFolder->pszRegValue,
  497. 0,
  498. &dwRegDataType,
  499. reinterpret_cast<LPBYTE>(szRegValue),
  500. &dwRegDataSize) == ERROR_SUCCESS)
  501. {
  502. if (GetFileAttributes(szRegValue) != 0xFFFFFFFF)
  503. {
  504. lstrcpy(pszDirToCreate, szRegValue);
  505. RegSetValueEx(hkeyFolder,
  506. pFolder->pszRegValue,
  507. 0,
  508. REG_SZ,
  509. (LPBYTE)pszDirToCreate,
  510. (lstrlen(pszDirToCreate)+1) * sizeof(TCHAR));
  511. }
  512. }
  513. RegCloseKey(hkeySF);
  514. }
  515. }
  516. }
  517. }
  518. /* The User Shell Folders key has a near-twin: Shell Folders, which
  519. * (a) should always contain the path to a folder, even if the folder
  520. * is in its default location, and (b) should contain the expanded
  521. * path on NT.
  522. */
  523. if (pFolder->pszRegKey == c_szExplorerKey) {
  524. HKEY hkeySF;
  525. if (RegCreateKeyEx(HKEY_CURRENT_USER,
  526. "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders",
  527. 0, NULL, REG_OPTION_NON_VOLATILE,
  528. KEY_READ|KEY_WRITE, NULL, &hkeySF, NULL) == ERROR_SUCCESS) {
  529. RegSetValueEx(hkeySF, pFolder->pszRegValue, 0, REG_SZ,
  530. (LPBYTE)pszDirToCreate, (lstrlen(pszDirToCreate)+1) * sizeof(TCHAR));
  531. RegCloseKey(hkeySF);
  532. }
  533. }
  534. /* Initialize default contents of the folder.
  535. */
  536. if (fInit && pFolder->InitFolder != NULL)
  537. pFolder->InitFolder(pFolder, szOldDir, pszHomeDir);
  538. }
  539. /* Always try to create the directory we want, if it doesn't already
  540. * exist.
  541. */
  542. if (::GetFileAttributes(pszDirToCreate) == 0xffffffff) {
  543. CreateDirectory(pszDirToCreate, NULL);
  544. if (pFolder->dwAttribs != FILE_ATTRIBUTE_DIRECTORY)
  545. SetFileAttributes(pszDirToCreate, pFolder->dwAttribs);
  546. }
  547. RegCloseKey(hkeyFolder);
  548. /*
  549. * If it's the My Documents folder, there is some per-user initialization
  550. * to do regardless of whether we set the values or they already existed.
  551. */
  552. if (pFolder->InitFolder == InitFolderMyDocs)
  553. {
  554. TCHAR szMyDocs[ MAX_PATH ];
  555. if (GetSystemDirectory( szMyDocs, ARRAYSIZE(szMyDocs) ))
  556. {
  557. HINSTANCE hMyDocs;
  558. lstrcat( szMyDocs, c_szMyDocsDLL );
  559. hMyDocs = LoadLibrary( szMyDocs );
  560. if (hMyDocs)
  561. {
  562. LPFNMYDOCSINIT pMyDocsInit =
  563. (LPFNMYDOCSINIT)GetProcAddress( hMyDocs, "PerUserInit" );
  564. if (pMyDocsInit)
  565. {
  566. pMyDocsInit();
  567. }
  568. FreeLibrary( hMyDocs );
  569. }
  570. }
  571. }
  572. /* Now, for Windows 95 systems, create a ProfileReconciliation subkey
  573. * which will make this folder roam. Only if we want to make this folder
  574. * per-user, of course.
  575. */
  576. if (fMakeFolderPerUser && !g_fRunningOnNT) {
  577. TCHAR szDefaultPath[MAX_PATH];
  578. lstrcpy(szDefaultPath, TEXT("*windir\\"));
  579. lstrcat(szDefaultPath, pszHomeDirEnd);
  580. HKEY hSubKey;
  581. LONG err = RegCreateKeyEx(hkeyProfRec, pFolder->pszStaticName, 0, NULL, REG_OPTION_NON_VOLATILE,
  582. KEY_WRITE, NULL, &hSubKey, NULL);
  583. if (err == ERROR_SUCCESS)
  584. err = RegSetValueEx(hSubKey, c_szCentralFile, 0, REG_SZ, (LPBYTE)pszHomeDirEnd,
  585. cchDir);
  586. if (err == ERROR_SUCCESS)
  587. err = RegSetValueEx(hSubKey, c_szLocalFile, 0, REG_SZ, (LPBYTE)pszHomeDirEnd,
  588. cchDir);
  589. if (err == ERROR_SUCCESS)
  590. err = RegSetValueEx(hSubKey, c_szName, 0, REG_SZ, (LPBYTE)pFolder->pszFiles,
  591. lstrlen(pFolder->pszFiles) + 1);
  592. if (err == ERROR_SUCCESS)
  593. err = RegSetValueEx(hSubKey, c_szDefaultDir, 0, REG_SZ, (LPBYTE)szDefaultPath,
  594. lstrlen(szDefaultPath) + 1);
  595. DWORD dwOne = 1;
  596. if (err == ERROR_SUCCESS)
  597. err = RegSetValueEx(hSubKey, c_szMustBeRelative, 0, REG_DWORD, (LPBYTE)&dwOne,
  598. sizeof(dwOne));
  599. if (err == ERROR_SUCCESS)
  600. err = RegSetValueEx(hSubKey, c_szDefault, 0, REG_DWORD, (LPBYTE)&dwOne,
  601. sizeof(dwOne));
  602. if (err == ERROR_SUCCESS)
  603. err = RegSetValueEx(hSubKey, c_szRegKey, 0, REG_SZ, (LPBYTE)pFolder->pszRegKey,
  604. lstrlen(pFolder->pszRegKey) + 1);
  605. if (err == ERROR_SUCCESS)
  606. err = RegSetValueEx(hSubKey, c_szRegValue, 0, REG_SZ, (LPBYTE)pFolder->pszRegValue,
  607. lstrlen(pFolder->pszRegValue) + 1);
  608. RegCloseKey(hSubKey);
  609. if (err != ERROR_SUCCESS)
  610. return HRESULT_FROM_WIN32(err);
  611. }
  612. return S_OK;
  613. }
  614. BOOL GetModulePath( LPTSTR szPath, UINT cbPath )
  615. {
  616. PSTR pszTmp;
  617. if (GetModuleFileName(g_hinst, szPath, cbPath ) == 0)
  618. {
  619. szPath[0] = '\0';
  620. return FALSE;
  621. }
  622. else
  623. {
  624. pszTmp = ANSIStrRChr( szPath, '\\' );
  625. if ( pszTmp )
  626. *pszTmp = '\0';
  627. }
  628. return TRUE ;
  629. }
  630. int DoMsgBoxParam(HWND hwnd, UINT TextString, UINT TitleString, UINT style, PTSTR param )
  631. {
  632. TCHAR szTitle[MAX_PATH];
  633. TCHAR szMsg[2*MAX_PATH];
  634. if (!LoadString(g_hinst, TextString, szMsg, sizeof(szMsg)))
  635. szMsg[0] = '\0';
  636. if ( param )
  637. {
  638. TCHAR szBuf[2*MAX_PATH];
  639. wsprintf( szBuf, szMsg, param );
  640. lstrcpy( szMsg, szBuf );
  641. }
  642. if (!LoadString(g_hinst, TitleString, szTitle, sizeof(szTitle)))
  643. szTitle[0] = '\0';
  644. return MessageBox(hwnd, szMsg, szTitle, style);
  645. }
  646. void InstINFFile( LPCTSTR pcszInf, LPTSTR pszSec, BOOL bInstall, BOOL bSaveRollback, DWORD dwFlag )
  647. {
  648. TCHAR szPath[MAX_PATH];
  649. CABINFO cabInfo;
  650. if ( GetModulePath( szPath, sizeof(szPath) ) )
  651. {
  652. if ( bSaveRollback )
  653. {
  654. ZeroMemory( &cabInfo, sizeof(CABINFO) );
  655. // install IE4Uinit.INF
  656. lstrcpy( cabInfo.szSrcPath, szPath );
  657. AddPath( szPath, pcszInf );
  658. if ( FileExists( szPath ) )
  659. {
  660. cabInfo.pszInf = szPath;
  661. cabInfo.pszSection = pszSec;
  662. cabInfo.dwFlags = (bInstall ? ALINF_BKINSTALL : ALINF_ROLLBACK);
  663. cabInfo.dwFlags |= ALINF_QUIET;
  664. ExecuteCab( NULL, &cabInfo, NULL );
  665. }
  666. else if (!(dwFlag & RSC_FLAG_QUIET))
  667. {
  668. DoMsgBoxParam( NULL, IDS_ERR_NOFOUNDINF, IDS_APPNAME, MB_OK|MB_ICONINFORMATION, szPath );
  669. }
  670. }
  671. else
  672. {
  673. char szInfFile[MAX_PATH];
  674. lstrcpy( szInfFile, szPath);
  675. AddPath( szInfFile, pcszInf);
  676. RunSetupCommand(NULL, szInfFile, pszSec, szPath,
  677. NULL, NULL, dwFlag, NULL);
  678. }
  679. }
  680. }
  681. void DoRollback()
  682. {
  683. HKEY hLMkey;
  684. HKEY hSubkey1, hSubkey2;
  685. TCHAR szBuf[MAX_PATH];
  686. DWORD dwSize;
  687. DWORD dwIndex = 0;
  688. int ilen;
  689. // rollback all the components listed in c_szIEModRollback key
  690. //
  691. if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, c_szAdvINFSetup, 0, KEY_READ , &hLMkey) == ERROR_SUCCESS )
  692. {
  693. if ( RegOpenKeyEx(hLMkey, c_szIEModRollback, 0, KEY_READ , &hSubkey1) == ERROR_SUCCESS )
  694. {
  695. lstrcpy( szBuf, c_szAdvINFSetup );
  696. AddPath( szBuf, "" );
  697. ilen = lstrlen(szBuf);
  698. dwSize = ARRAYSIZE(szBuf) - ilen;
  699. while ( RegEnumValue( hSubkey1, dwIndex, &szBuf[ilen], &dwSize,
  700. NULL, NULL, NULL, NULL ) == ERROR_SUCCESS )
  701. {
  702. if ( RegOpenKeyEx(hLMkey, &szBuf[ilen], 0, KEY_READ | KEY_WRITE, &hSubkey2) == ERROR_SUCCESS )
  703. {
  704. RegSetValueEx( hSubkey2, TEXT("BackupRegistry"), 0, REG_SZ, (LPBYTE)TEXT("n"), (lstrlen(TEXT("n"))+1)*sizeof(TCHAR) );
  705. RegCloseKey( hSubkey2 );
  706. }
  707. AddPath( szBuf, c_szRegBackup );
  708. ///////////////////////////////////////////////////////////////////////////
  709. // ShabbirS - 8/17/98
  710. // Bug# 26774 : Found that this restoring of backup reg data undoes our
  711. // dll registering done during the RunOnceEx phase.
  712. ///////////////////////////////////////////////////////////////////////////
  713. // restore HKLM if there
  714. //if ( RegOpenKeyEx(hLMkey, &szBuf[ilen], 0, KEY_READ | KEY_WRITE, &hSubkey2) == ERROR_SUCCESS )
  715. //{
  716. // RegRestoreAll( NULL, NULL, hSubkey2 );
  717. // RegCloseKey( hSubkey2 );
  718. //}
  719. // restore HKCU if there
  720. if ( RegOpenKeyEx( HKEY_CURRENT_USER, szBuf, 0, KEY_READ | KEY_WRITE, &hSubkey2) == ERROR_SUCCESS )
  721. {
  722. RegRestoreAll( NULL, NULL, hSubkey2 );
  723. RegCloseKey( hSubkey2 );
  724. }
  725. dwIndex++;
  726. dwSize = ARRAYSIZE( szBuf ) - ilen;
  727. }
  728. RegCloseKey( hSubkey1 );
  729. }
  730. RegCloseKey( hLMkey );
  731. }
  732. }
  733. #define NT_MEMORYLIMIT 0x03f00000
  734. #define WIN9X_MEMORYLIMIT 0x01f00000
  735. void DoINFWork( BOOL bInstall, LPCTSTR pcszInfFile, LPTSTR pszInfSec, DWORD dwFlag )
  736. {
  737. HKEY hkey;
  738. TCHAR szBuf[MAX_PATH] = { 0 };
  739. DWORD dwSize;
  740. DWORD dwRedist = 0;
  741. BOOL bRedistMode = FALSE;
  742. // check the InstallMode and determin if make the desktop icon and StartMenu item.
  743. if ( bInstall && (RegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szIESetupPath, 0, KEY_READ, &hkey) == ERROR_SUCCESS) )
  744. {
  745. dwSize = sizeof(dwRedist);
  746. // If we can read the Installmode and bit 0 is set, assume redist (Remove short cuts)
  747. if ( (RegQueryValueEx( hkey, c_szInstallMode, 0, NULL, (LPBYTE)&dwRedist, &dwSize) == ERROR_SUCCESS) &&
  748. (dwRedist & 1) )
  749. {
  750. bRedistMode = TRUE;
  751. }
  752. RegCloseKey( hkey );
  753. }
  754. // if not installed over SP4 level crypto, then backup/restore the crypto keys.
  755. // NOTE that bInstall is passed in the 4th argument, so during install bSaveRollback is TRUE. During
  756. // uninstall, the reg backup data should be restored when the DefaultInstall section is processed, so
  757. // set bSaveRollback to FALSE
  758. if (!FSP4LevelCryptoInstalled())
  759. InstINFFile( pcszInfFile, bInstall ? "BackupCryptoKeys" : "DelCryptoKeys", bInstall, bInstall, dwFlag );
  760. else
  761. {
  762. // BUGBUG: if bInstall is FALSE, need to delete the reg backup data for the crypto keys
  763. }
  764. // install the WinXP specific section
  765. if(g_fRunningOnWinXP && !pszInfSec ) {
  766. InstINFFile( pcszInfFile, TEXT("DefaultInstall.WinXP"), bInstall, TRUE, dwFlag);
  767. }
  768. else {
  769. // install the current shortcut and HKCU settings by stub INF
  770. InstINFFile( pcszInfFile, pszInfSec, bInstall, TRUE, dwFlag );
  771. }
  772. // Even though IE5.0 does not install channelband, if the channelband exists on IE4.0, it should works in
  773. // IE5.0. Therefore if there is channelbar link exists(PrevIE Version is IE4.0 browser only), IE5 will update
  774. // the channelbar link to the current browser. Otherwise, do nothing.
  775. if (bInstall && IsPrevIE4() && !IsPrevIE4WebShell())
  776. {
  777. InstINFFile( pcszInfFile, TEXT("Shell.UserStub.Uninstall"), bInstall, FALSE, RSC_FLAG_INF | RSC_FLAG_QUIET );
  778. }
  779. if ( bRedistMode )
  780. {
  781. LPTSTR lpszSection;
  782. if ( g_fRunningOnNT )
  783. lpszSection = TEXT("RedistIE.NT");
  784. else
  785. lpszSection = TEXT("RedistIE.Win");
  786. InstINFFile( pcszInfFile, lpszSection, bInstall, TRUE, dwFlag );
  787. }
  788. // On uninstall, check what the current browser version and determin if we need to cleanup the
  789. // Channel and quick launch folders
  790. if ( !bInstall && ( CheckIEVersion() == LESSIE4))
  791. {
  792. LPTSTR lpszSection;
  793. if ( g_fRunningOnNT )
  794. lpszSection = TEXT("CleanFolders.NT");
  795. else
  796. lpszSection = TEXT("CleanFolders.Win");
  797. InstINFFile( pcszInfFile, lpszSection, bInstall, FALSE, RSC_FLAG_INF | RSC_FLAG_QUIET | RSC_FLAG_NGCONV );
  798. }
  799. // Enable sounds if user has a big enough machine
  800. // NT - 64MB, Win9x - 32MB
  801. if(bInstall)
  802. {
  803. LPTSTR lpszSection = NULL;
  804. MEMORYSTATUS ms;
  805. ms.dwLength = sizeof(MEMORYSTATUS);
  806. GlobalMemoryStatus(&ms);
  807. if ( g_fRunningOnNT)
  808. {
  809. if(ms.dwTotalPhys >= NT_MEMORYLIMIT)
  810. {
  811. lpszSection = TEXT("SoundInstall.NT");
  812. }
  813. }
  814. else
  815. {
  816. if(ms.dwTotalPhys >= WIN9X_MEMORYLIMIT)
  817. {
  818. lpszSection = TEXT("SoundInstall");
  819. }
  820. }
  821. if(lpszSection)
  822. InstINFFile( pcszInfFile, lpszSection, bInstall, TRUE, RSC_FLAG_INF | RSC_FLAG_QUIET | RSC_FLAG_NGCONV );
  823. }
  824. if (bInstall)
  825. {
  826. // in fact this is only true for IE5 install inf, but IE4 inf is called ok too since there is no
  827. // such section in IE4 stub inf.
  828. if (CheckWebViewShell(NULL)) {
  829. LPSTR lpszSection = NULL;
  830. if(g_fRunningOnWinXP)
  831. lpszSection = TEXT("IE5onIE4Shell.WinXP");
  832. else
  833. lpszSection = TEXT("IE5onIE4Shell");
  834. InstINFFile( pcszInfFile, lpszSection, bInstall, FALSE, RSC_FLAG_INF | RSC_FLAG_QUIET );
  835. }
  836. }
  837. // check if the user's home page is bogus one
  838. if ( bInstall && (RegOpenKeyEx( HKEY_CURRENT_USER, c_szIExploreMain, 0, KEY_READ, &hkey ) == ERROR_SUCCESS) )
  839. {
  840. DWORD dwSize;
  841. dwSize = sizeof(szBuf);
  842. if ( RegQueryValueEx( hkey, TEXT("Start Page"), NULL, NULL, (LPBYTE)szBuf, &dwSize ) == ERROR_SUCCESS )
  843. {
  844. if ( (g_fRunningOnNT && ANSIStrStrI(szBuf, "Plus!") && ANSIStrStrI(szBuf, "File:")) ||
  845. (!lstrcmpi(szBuf, TEXT("http://home.microsoft.com"))) ||
  846. (!lstrcmpi(szBuf, TEXT("http://home.microsoft.com/"))) )
  847. {
  848. InstINFFile( pcszInfFile, TEXT("OverrideHomePage.NT"), bInstall, TRUE, dwFlag );
  849. }
  850. }
  851. RegCloseKey( hkey );
  852. }
  853. if ( !bRedistMode )
  854. {
  855. typedef void (*PFSetFirstHomepage)();
  856. PFSetFirstHomepage pfSetFirstHomepage;
  857. HMODULE hMod = LoadLibrary("iesetup.dll");
  858. if (hMod)
  859. {
  860. pfSetFirstHomepage = (PFSetFirstHomepage)GetProcAddress(hMod, "SetFirstHomepage");
  861. if (pfSetFirstHomepage)
  862. {
  863. pfSetFirstHomepage();
  864. }
  865. FreeLibrary(hMod);
  866. }
  867. }
  868. // DoRollback if needed
  869. if ( !bInstall )
  870. {
  871. DoRollback();
  872. }
  873. }
  874. /*----------------------------------------------------------
  875. Purpose: Detect if it is run on Russian LangID
  876. */
  877. //DWORD dwLangList[] = { 0x0419, 0xFFFF };
  878. #define RUSSIANLANG 0x0419
  879. BOOL IsBrokenLang()
  880. {
  881. char szTmp[MAX_PATH] = { 0 };
  882. DWORD dwLangKernel32;
  883. DWORD dwTmp;
  884. BOOL bBadLang = FALSE;
  885. GetSystemDirectory(szTmp, sizeof(szTmp));
  886. AddPath(szTmp,"kernel32.dll" );
  887. GetVersionFromFile(szTmp, &dwLangKernel32, &dwTmp, FALSE);
  888. if ( dwLangKernel32 == RUSSIANLANG )
  889. {
  890. bBadLang = TRUE;
  891. }
  892. return bBadLang;
  893. }
  894. BOOL IsPrevStubRun()
  895. {
  896. HKEY hLMKey, hCUKey;
  897. BOOL bRet = FALSE;
  898. char szStubVer[50], szPreIEVer[50];
  899. DWORD dwSize;
  900. WORD wStubVer[4]={0}, wPreIEVer[4]={0};
  901. // check if the pre-version iestub is run
  902. if ( RegOpenKeyEx( HKEY_CURRENT_USER, c_szActInstalledIEGUID, 0, KEY_READ, &hCUKey ) == ERROR_SUCCESS )
  903. {
  904. dwSize = sizeof(szStubVer);
  905. if ( RegQueryValueEx( hCUKey, TEXT("Version"), NULL, NULL, (LPBYTE)szStubVer, &dwSize ) == ERROR_SUCCESS )
  906. {
  907. ConvertVersionString( szStubVer, wStubVer, ',' );
  908. }
  909. RegCloseKey(hCUKey);
  910. }
  911. if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, c_szIESetupPath, 0, KEY_READ, &hLMKey ) == ERROR_SUCCESS )
  912. {
  913. dwSize = sizeof(szPreIEVer);
  914. if ( RegQueryValueEx( hLMKey, TEXT("PreviousIESysFile"), NULL, NULL, (LPBYTE)szPreIEVer, &dwSize ) == ERROR_SUCCESS )
  915. {
  916. ConvertVersionString( szPreIEVer, wPreIEVer, '.' );
  917. if ( (MAKELONG(wPreIEVer[1],wPreIEVer[0])<IE_4_MS_VERSION) ||
  918. (wStubVer[0] > wPreIEVer[0]) ||
  919. ((wStubVer[0] == wPreIEVer[0]) && (wStubVer[1] >= wPreIEVer[1])) )
  920. {
  921. bRet = TRUE;
  922. }
  923. }
  924. else //should never be here. OW
  925. bRet = TRUE; //not forcing rerun the prev-stub
  926. RegCloseKey(hLMKey);
  927. }
  928. else //should never be here. OW
  929. bRet = TRUE; //not forcing rerun the prev-stub
  930. return bRet;
  931. }
  932. /*----------------------------------------------------------
  933. Purpose: Stripping off the trailing spaces for the registry data in the list
  934. */
  935. typedef struct _REGDATACHECK
  936. {
  937. HKEY hRootKey;
  938. LPSTR lpszSubKey;
  939. LPSTR lpszValueName;
  940. } REGDATACHECK;
  941. REGDATACHECK chkList[] = {
  942. { HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders", "AppData" },
  943. { HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders", "Start Menu" },
  944. { HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", "AppData" },
  945. { HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", "Start Menu" },
  946. { HKEY_USERS, ".DEFAULT\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders", "AppData" },
  947. { HKEY_USERS, ".DEFAULT\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders", "Start Menu" },
  948. { HKEY_USERS, ".DEFAULT\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", "AppData" },
  949. { HKEY_USERS, ".DEFAULT\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", "Start Menu" },
  950. };
  951. void FixRegData()
  952. {
  953. int iList, i;
  954. LPSTR pszTmp;
  955. char szBuf[MAX_PATH];
  956. DWORD dwSize, dwType;
  957. HKEY hKey;
  958. iList = ARRAYSIZE( chkList );
  959. for ( i = 0; i < iList; i++ )
  960. {
  961. if ( RegOpenKeyEx(chkList[i].hRootKey, chkList[i].lpszSubKey, 0, KEY_READ|KEY_WRITE,
  962. &hKey) == ERROR_SUCCESS )
  963. {
  964. dwSize = sizeof(szBuf);
  965. if ( RegQueryValueEx(hKey, chkList[i].lpszValueName, 0, &dwType, (LPBYTE)szBuf,
  966. &dwSize) == ERROR_SUCCESS )
  967. {
  968. // strip off the trailing blanks
  969. pszTmp = szBuf;
  970. pszTmp += lstrlen(szBuf) - 1;
  971. while ( (pszTmp >= szBuf) && (*pszTmp == ' ') )
  972. {
  973. *pszTmp = '\0';
  974. pszTmp--;
  975. }
  976. RegSetValueEx( hKey, chkList[i].lpszValueName, 0, dwType, (LPBYTE)szBuf, lstrlen(szBuf)+1 );
  977. }
  978. RegCloseKey( hKey );
  979. }
  980. }
  981. }
  982. void FixSearchUrl()
  983. {
  984. HKEY hkey, hIEKey;
  985. TCHAR szBuf[MAX_PATH];
  986. DWORD dwSize;
  987. // if HKCU, software\microsoft\internet explorer\SearchUrl, "default" value is ""
  988. // Delete the "" default value.
  989. //
  990. if ( RegOpenKeyEx(HKEY_CURRENT_USER, c_szIExplorerSearchUrl, 0, KEY_READ|KEY_WRITE, &hkey) == ERROR_SUCCESS )
  991. {
  992. dwSize = 0;
  993. if ( RegQueryValueEx( hkey, TEXT(""), 0, NULL, (LPBYTE)szBuf, &dwSize ) != ERROR_SUCCESS )
  994. {
  995. dwSize = sizeof(szBuf);
  996. if ( (RegQueryValueEx( hkey, TEXT(""), 0, NULL, (LPBYTE)szBuf, &dwSize ) == ERROR_SUCCESS) &&
  997. (szBuf[0] == TEXT('\0')) )
  998. {
  999. // found "" empty string as default value, check if we have cleaned up before.
  1000. // If not, clean it now, otherwise do nothing.
  1001. if ( RegCreateKeyEx( HKEY_CURRENT_USER, c_szIE4Path,0, NULL, REG_OPTION_NON_VOLATILE,
  1002. KEY_READ|KEY_WRITE, NULL, &hIEKey, NULL) == ERROR_SUCCESS )
  1003. {
  1004. dwSize = sizeof(szBuf);
  1005. if ( (RegQueryValueEx( hIEKey, c_szSearchUrl, 0, NULL, (LPBYTE)szBuf, &dwSize ) != ERROR_SUCCESS) ||
  1006. (*CharUpper(szBuf) != TEXT('Y')) )
  1007. {
  1008. RegDeleteValue( hkey, TEXT("") );
  1009. lstrcpy( szBuf, TEXT("Y") );
  1010. RegSetValueEx( hIEKey, c_szSearchUrl, 0, REG_SZ, (LPBYTE)szBuf, (lstrlen(szBuf)+1)*sizeof(TCHAR) );
  1011. }
  1012. RegCloseKey( hIEKey );
  1013. }
  1014. }
  1015. }
  1016. RegCloseKey( hkey );
  1017. }
  1018. }
  1019. /*----------------------------------------------------------
  1020. * Helper function to check if the Channels folder exists in
  1021. * the current user profile.
  1022. *----------------------------------------------------------
  1023. */
  1024. // "Channels" resid from CdfView. (Need to use this, b'cos could be localized
  1025. #define CHANNEL_FOLDER_RESID 0x1200
  1026. // SHGetSpecialFolderPath function from Shell32.dll
  1027. typedef BOOL (WINAPI *SH_GSFP_PROC) (HWND, LPTSTR, int, BOOL);
  1028. BOOL DoesChannelFolderExist()
  1029. {
  1030. char szChannelName[MAX_PATH];
  1031. char szSysPath[MAX_PATH] = { 0 };
  1032. char szChannelPath[MAX_PATH];
  1033. BOOL bRet = FALSE;
  1034. BOOL bGetRC = TRUE;
  1035. HMODULE hShell32 = NULL;
  1036. SH_GSFP_PROC fpSH_GSFP = NULL;
  1037. DWORD dwAttr = 0;
  1038. GetSystemDirectory( szSysPath,sizeof(szSysPath));
  1039. lstrcpy(szChannelPath, szSysPath);
  1040. AddPath( szChannelPath, "shell32.dll" );
  1041. hShell32 = LoadLibrary(szChannelPath);
  1042. // This stubs runs on IE4 or IE5 systems. Hence shell32 is garunteed
  1043. // to have the SHGetSpecialFolderPath API.
  1044. if (hShell32)
  1045. {
  1046. fpSH_GSFP = (SH_GSFP_PROC)GetProcAddress(hShell32,"SHGetSpecialFolderPathA");
  1047. *szChannelPath = '\0';
  1048. if (fpSH_GSFP && fpSH_GSFP(NULL, szChannelPath, CSIDL_FAVORITES, FALSE))
  1049. {
  1050. HKEY hKey;
  1051. DWORD cbSize = sizeof(szChannelName);
  1052. // Get the potentially localized name of the Channel folder from the
  1053. // registry if it is there. Otherwise use "Channels"
  1054. // Then tack this on the favorites path.
  1055. //
  1056. if ( RegOpenKeyEx(HKEY_LOCAL_MACHINE, REGSTR_PATH_SETUP, 0, KEY_READ, &hKey) == ERROR_SUCCESS)
  1057. {
  1058. if (RegQueryValueEx(hKey,"ChannelFolderName", NULL, NULL, (LPBYTE)szChannelName,&cbSize) == ERROR_SUCCESS)
  1059. {
  1060. bGetRC = FALSE;
  1061. }
  1062. RegCloseKey(hKey);
  1063. }
  1064. if (bGetRC)
  1065. {
  1066. HMODULE hLib;
  1067. // Get the default name for Channels folder from the
  1068. // CdfView.dll
  1069. AddPath(szSysPath,"cdfview.dll");
  1070. hLib = LoadLibraryEx(szSysPath,NULL,LOAD_LIBRARY_AS_DATAFILE);
  1071. if (hLib)
  1072. {
  1073. if (LoadString(hLib, CHANNEL_FOLDER_RESID,szChannelName,sizeof(szChannelName)) == 0)
  1074. {
  1075. // Fail to read the resource, default to English
  1076. lstrcpy(szChannelName,"Channels");
  1077. }
  1078. FreeLibrary(hLib);
  1079. }
  1080. }
  1081. AddPath(szChannelPath, szChannelName);
  1082. // Check if the folder exists...
  1083. dwAttr = GetFileAttributes(szChannelPath);
  1084. if ((dwAttr != 0xffffffff) && (dwAttr & FILE_ATTRIBUTE_DIRECTORY))
  1085. bRet = TRUE;
  1086. }
  1087. FreeLibrary(hShell32);
  1088. }
  1089. return bRet;
  1090. }
  1091. HRESULT IEAccessHideExplorerIcon()
  1092. {
  1093. const TCHAR *szKeyComponent = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\CLSID\\{871C5380-42A0-1069-A2EA-08002B30309D}");
  1094. const TCHAR *szShellFolder = TEXT("ShellFolder");
  1095. const TCHAR *szAttribute = TEXT("Attributes");
  1096. DWORD dwValue, dwSize, dwDisposition;
  1097. HKEY hKeyComponent, hKeyShellFolder;
  1098. HRESULT hResult = ERROR_SUCCESS;
  1099. hResult = RegCreateKeyEx(HKEY_CURRENT_USER, szKeyComponent, NULL, NULL, REG_OPTION_NON_VOLATILE,
  1100. KEY_CREATE_SUB_KEY, NULL, &hKeyComponent, &dwDisposition);
  1101. if (hResult != ERROR_SUCCESS)
  1102. return hResult;
  1103. hResult = RegCreateKeyEx(hKeyComponent, szShellFolder, NULL, NULL, REG_OPTION_NON_VOLATILE,
  1104. KEY_QUERY_VALUE | KEY_SET_VALUE, NULL, &hKeyShellFolder, &dwDisposition);
  1105. RegCloseKey(hKeyComponent);
  1106. if (hResult == ERROR_SUCCESS)
  1107. {
  1108. dwSize = sizeof(dwValue);
  1109. hResult = RegQueryValueEx( hKeyShellFolder, szAttribute, NULL, NULL, (LPBYTE)&dwValue, &dwSize);
  1110. if (hResult != ERROR_SUCCESS)
  1111. dwValue = 0;
  1112. dwValue |= SFGAO_NONENUMERATED;
  1113. hResult = RegSetValueEx(hKeyShellFolder, szAttribute, NULL, REG_DWORD, (LPBYTE)&dwValue, sizeof(dwValue));
  1114. RegCloseKey(hKeyShellFolder);
  1115. }
  1116. return hResult;
  1117. }
  1118. #define REGVAL_SHOW_CHANNELBAND "Show_ChannelBand"
  1119. #define REGVAL_SOURCE "Source"
  1120. #define REGVAL_FLAGS "Flags"
  1121. #define REG_IE_MAIN "Software\\Microsoft\\Internet Explorer\\Main"
  1122. #define REG_DESKTOP_COMP "Software\\Microsoft\\Internet Explorer\\Desktop\\Components"
  1123. #define GUID_CHNLBAND "131A6951-7F78-11D0-A979-00C04FD705A2"
  1124. #define FLAG_ENABLE_CHNLBAND 0x00002000
  1125. /*----------------------------------------------------------
  1126. Purpose: Worker function to do the work
  1127. */
  1128. void DoWork( BOOL bInstall )
  1129. {
  1130. TCHAR szHomeDir[MAX_PATH] = { 0 };
  1131. HKEY hkeyProfRec = NULL;
  1132. HKEY hkeyFolderPolicies;
  1133. BOOL fIntShellMode = FALSE;
  1134. HMODULE hmodShell = NULL;
  1135. // HINSTANCE hlib;
  1136. TCHAR szPath[MAX_PATH] = { 0 };
  1137. DWORD dwMV, dwLV;
  1138. BOOL fUseShell32 = FALSE;
  1139. if ( bInstall )
  1140. {
  1141. if (g_fRunningOnNT) {
  1142. ExpandEnvironmentStrings("%USERPROFILE%", szHomeDir, ARRAYSIZE(szHomeDir));
  1143. }
  1144. else {
  1145. szHomeDir[0] = '\0';
  1146. LONG err = RegCreateKeyEx(HKEY_CURRENT_USER, c_szProfRecKey, 0, NULL,
  1147. REG_OPTION_NON_VOLATILE, KEY_READ|KEY_WRITE,
  1148. NULL, &hkeyProfRec, NULL);
  1149. if (err == ERROR_SUCCESS) {
  1150. DWORD dwType;
  1151. DWORD cbData = sizeof(szHomeDir);
  1152. RegQueryValueEx(hkeyProfRec, c_szHomeDirValue, 0, &dwType,
  1153. (LPBYTE)szHomeDir, &cbData);
  1154. }
  1155. }
  1156. if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Per User Folders",
  1157. 0, KEY_QUERY_VALUE, &hkeyFolderPolicies) != ERROR_SUCCESS)
  1158. hkeyFolderPolicies = NULL;
  1159. /* Dynamically link to the SHFlushSFCache API in SHELL32.DLL. Its ordinal
  1160. * is 526. This API tells the shell to reinitialize the shell folder cache
  1161. * in all processes.
  1162. */
  1163. // due to the buggy in the old shell32 of this api function. We are advised to use the new wrap
  1164. // which is in shlwapi.dll. Its ordinal is 419.
  1165. fIntShellMode = FALSE;
  1166. GetSystemDirectory( szPath,sizeof( szPath ) );
  1167. AddPath( szPath, "shlwapi.dll" );
  1168. GetVersionFromFile( szPath, &dwMV, &dwLV, TRUE );
  1169. // if major version >= 5.0
  1170. //
  1171. if ( (dwMV >= 0x00050000))
  1172. {
  1173. hmodShell = ::LoadLibrary(szPath);
  1174. }
  1175. else
  1176. {
  1177. hmodShell = ::LoadLibrary("shell32.dll");
  1178. fUseShell32 = TRUE;
  1179. }
  1180. if (hmodShell != NULL)
  1181. {
  1182. if ( !fUseShell32 )
  1183. {
  1184. ::pfnSHFlushSFCacheWrap = (PFNSHFLUSHSFCACHEWRAP)::GetProcAddress(hmodShell, (LPCTSTR)419);
  1185. if (::pfnSHFlushSFCacheWrap != NULL)
  1186. {
  1187. fIntShellMode = TRUE;
  1188. }
  1189. }
  1190. else
  1191. {
  1192. ::pfnSHFlushSFCache = (PFNSHFLUSHSFCACHE)::GetProcAddress(hmodShell, (LPCTSTR)526);
  1193. if (::pfnSHFlushSFCache != NULL)
  1194. {
  1195. fIntShellMode = TRUE;
  1196. }
  1197. }
  1198. }
  1199. BOOL fDefaultProfile;
  1200. LPTSTR pchHomeDirEnd = szHomeDir;
  1201. int cchHomeDir = 0;
  1202. if (szHomeDir[0] != '\0') {
  1203. fDefaultProfile = FALSE;
  1204. }
  1205. else {
  1206. GetWindowsDirectory(szHomeDir, ARRAYSIZE(szHomeDir));
  1207. fDefaultProfile = TRUE;
  1208. }
  1209. AddPath(szHomeDir,"");
  1210. pchHomeDirEnd = szHomeDir + lstrlen(szHomeDir);
  1211. cchHomeDir = ARRAYSIZE(szHomeDir) - (int)(pchHomeDirEnd - szHomeDir);
  1212. for (UINT i=0; i<ARRAYSIZE(aFolders); i++) {
  1213. if (aFolders[i].fIntShellOnly && !fIntShellMode)
  1214. continue;
  1215. if (FAILED(SetupFolder(hkeyProfRec, szHomeDir, pchHomeDirEnd,
  1216. cchHomeDir, &aFolders[i], fDefaultProfile,
  1217. hkeyFolderPolicies)))
  1218. break;
  1219. }
  1220. if (hkeyProfRec != NULL)
  1221. RegCloseKey(hkeyProfRec);
  1222. if (hkeyFolderPolicies != NULL)
  1223. RegCloseKey(hkeyFolderPolicies);
  1224. // import NS stuff if there
  1225. ImportNetscapeProxySettings( IMPTPROXY_CALLAFTIE4 );
  1226. ImportBookmarks(g_hinst);
  1227. if ( !fUseShell32 )
  1228. {
  1229. if (::pfnSHFlushSFCacheWrap != NULL)
  1230. {
  1231. (*::pfnSHFlushSFCacheWrap)();
  1232. }
  1233. }
  1234. else
  1235. {
  1236. if (::pfnSHFlushSFCache != NULL)
  1237. {
  1238. (*::pfnSHFlushSFCache)();
  1239. }
  1240. }
  1241. if (hmodShell != NULL) {
  1242. ::FreeLibrary(hmodShell);
  1243. }
  1244. }
  1245. /* BUGBUG - add code to populate the default IE4 favorites, channels, and
  1246. * shortcuts here
  1247. */
  1248. // #75346: Upgrade from Win9x to NT5, new users have no Channels folder
  1249. // and the ChannelBand pops-up with Fav. entries in it. This hack will
  1250. // ensure that the Ch.Band does not pop-up when the new user logs in for
  1251. // the first time.
  1252. if (bInstall && g_fRunningOnNT5)
  1253. {
  1254. if (!DoesChannelFolderExist())
  1255. {
  1256. HKEY hKey;
  1257. char szNo[] = "No";
  1258. // Turn off the Show_ChannelBand for this user.
  1259. if (RegOpenKeyEx(HKEY_CURRENT_USER,REG_IE_MAIN, 0, KEY_READ|KEY_WRITE, &hKey) == ERROR_SUCCESS)
  1260. {
  1261. RegSetValueEx(hKey, REGVAL_SHOW_CHANNELBAND,0, REG_SZ,(LPBYTE)szNo,sizeof(szNo));
  1262. RegCloseKey(hKey);
  1263. }
  1264. // Also turn off the Desktop\Components(ChannelBand)
  1265. // Open HKCU\S\M\InternetExplorer\Desktop\Coomponents and enum for
  1266. // the ChannelBand GUID. Disable the show flag.
  1267. if (RegOpenKeyEx(HKEY_CURRENT_USER, REG_DESKTOP_COMP, 0, KEY_READ|KEY_WRITE, &hKey) == ERROR_SUCCESS)
  1268. {
  1269. HKEY hSubKey = NULL;
  1270. char szSubKey[MAX_PATH];
  1271. char szSourceID[130];
  1272. DWORD dwSize = sizeof(szSubKey);
  1273. for (int i = 0;
  1274. RegEnumKeyEx(hKey,i, szSubKey, &dwSize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS;
  1275. i++, dwSize = sizeof(szSubKey))
  1276. {
  1277. // Open this subkey and checks its SourceID.
  1278. if (RegOpenKeyEx(hKey,szSubKey,0, KEY_READ|KEY_WRITE, &hSubKey) == ERROR_SUCCESS)
  1279. {
  1280. dwSize = sizeof(szSourceID);
  1281. if ((RegQueryValueEx(hSubKey, REGVAL_SOURCE, NULL, NULL, (LPBYTE)szSourceID,&dwSize) == ERROR_SUCCESS)
  1282. && (lstrcmpi(szSourceID, GUID_CHNLBAND) == 0))
  1283. {
  1284. // Read the current Flags setting.
  1285. DWORD dwFlags = 0;
  1286. dwSize = sizeof(dwFlags);
  1287. RegQueryValueEx(hSubKey,REGVAL_FLAGS, NULL, NULL, (LPBYTE)&dwFlags, &dwSize);
  1288. dwFlags &= ~(FLAG_ENABLE_CHNLBAND);
  1289. dwSize = sizeof(dwFlags);
  1290. RegSetValueEx(hSubKey, REGVAL_FLAGS, 0, REG_DWORD, (LPBYTE)&dwFlags, dwSize);
  1291. // close the key since we have a match and are therefore going to break out
  1292. RegCloseKey(hSubKey);
  1293. break;
  1294. }
  1295. RegCloseKey(hSubKey);
  1296. }
  1297. } // end of RegEnum loop
  1298. RegCloseKey(hKey);
  1299. }
  1300. }
  1301. }
  1302. // before we do the INF work, we have to run the following function which is
  1303. // hack way to fix Russian NT 4.0 localization problem. This only apply to Russian NT box.
  1304. if (g_fRunningOnNT && IsBrokenLang() )
  1305. {
  1306. FixRegData();
  1307. }
  1308. // On win95, due to the RegSave/Restore problem on default valuename, and valuename is space,
  1309. // we will do a specific fix for SearchUrl subkey. The generic registry operation fix will in advpack.dll.
  1310. if ( (!g_fRunningOnNT) && bInstall )
  1311. {
  1312. FixSearchUrl();
  1313. }
  1314. // because this stub code is left after uninstall IE5 to do both IE4 and IE5 work, we need the smartness to
  1315. // know when to run IE4 inf and when only needed to run IE5 inf
  1316. // BUGBUG: this portion of code is very version specific and need to be updated whenever the new Major
  1317. // version is shipped. Bud pain!! Most likely, in IE6 time we need to stub EXE to get around the problem!!
  1318. if (bInstall)
  1319. {
  1320. UINT uIEVer = CheckIEVersion();
  1321. // install stub case:
  1322. if (uIEVer == IE4)
  1323. {
  1324. DoINFWork(bInstall, c_szPrevStubINF, NULL, 0); // NULL means DefaultInstall section
  1325. }
  1326. else if (uIEVer >= IE5)
  1327. {
  1328. if (!IsPrevStubRun() )
  1329. {
  1330. // Simulate a pre-installation of IE4. So run IE4 browser stub
  1331. // first, then followed by the IE4 Shell stub (if required).
  1332. DoINFWork( bInstall, c_szPrevStubINF, NULL, RSC_FLAG_INF | RSC_FLAG_QUIET );
  1333. if (IsPrevIE4WebShell())
  1334. {
  1335. DoINFWork( bInstall, c_szPrevStubINF, g_fRunningOnNT ? TEXT("Shell.UserStubNT") : TEXT("Shell.UserStub"), RSC_FLAG_INF | RSC_FLAG_QUIET);
  1336. }
  1337. }
  1338. DoINFWork( bInstall, c_szStubINFFile, NULL, 0 );
  1339. ProcessMouseException();
  1340. }
  1341. }
  1342. else
  1343. {
  1344. // uninstall stub case: use HKCU value to make sure which version it is uninstalling
  1345. UINT uUninstIEVer = CheckUninstIEVersion();
  1346. if (uUninstIEVer == IE4)
  1347. {
  1348. DoINFWork(bInstall, c_szPrevStubINF, NULL, 0);
  1349. }
  1350. else if (uUninstIEVer == IE5)
  1351. {
  1352. DoINFWork(bInstall, c_szStubINFFile, NULL, 0);
  1353. }
  1354. else if (uUninstIEVer == IE55 || uUninstIEVer == IE6)
  1355. {
  1356. DoINFWork(bInstall, c_szStubINFFile, NULL, 0);
  1357. }
  1358. }
  1359. if (bInstall && g_fRunningOnWinXP)
  1360. IEAccessHideExplorerIcon();
  1361. }
  1362. INT WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
  1363. LPTSTR lpszCmdLine, INT nCmdShow )
  1364. {
  1365. BOOL bInstall;
  1366. if ( !lpszCmdLine || !*lpszCmdLine )
  1367. bInstall = TRUE;
  1368. else
  1369. bInstall = FALSE;
  1370. DoWork( bInstall );
  1371. TCHAR szCmdLine[MAX_PATH];
  1372. GetSystemDirectory(szCmdLine, ARRAYSIZE(szCmdLine));
  1373. AddPath(szCmdLine, TEXT("shmgrate.exe"));
  1374. ShellExecute(NULL, NULL, szCmdLine, TEXT("OCInstallUserConfigIE"), NULL, SW_SHOWDEFAULT);
  1375. return 0;
  1376. }
  1377. // stolen from the CRT, used to shrink our code
  1378. int
  1379. _stdcall
  1380. ModuleEntry(void)
  1381. {
  1382. STARTUPINFO si;
  1383. LPSTR pszCmdLine = GetCommandLine();
  1384. g_hinst = GetModuleHandle(NULL);
  1385. #ifdef DEBUG
  1386. CcshellGetDebugFlags();
  1387. if (IsFlagSet(g_dwBreakFlags, BF_ONOPEN))
  1388. DebugBreak();
  1389. #endif
  1390. if (FAILED(OleInitialize(NULL)))
  1391. return 0;
  1392. OSVERSIONINFO osvi;
  1393. osvi.dwOSVersionInfoSize = sizeof(osvi);
  1394. GetVersionEx(&osvi);
  1395. if (VER_PLATFORM_WIN32_NT == osvi.dwPlatformId)
  1396. {
  1397. g_fRunningOnNT = TRUE;
  1398. if (osvi.dwMajorVersion >= 5) {
  1399. g_fRunningOnNT5 = TRUE;
  1400. if (osvi.dwMinorVersion >= 1)
  1401. g_fRunningOnWinXP = TRUE;
  1402. }
  1403. }
  1404. else if ((VER_PLATFORM_WIN32_WINDOWS == osvi.dwPlatformId) && (0 == osvi.dwMinorVersion))
  1405. {
  1406. g_fRunningOnWin95 = TRUE;
  1407. }
  1408. // turn off critical error stuff
  1409. SetErrorMode(SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS);
  1410. if ( *pszCmdLine == '\"' ) {
  1411. /*
  1412. * Scan, and skip over, subsequent characters until
  1413. * another double-quote or a null is encountered.
  1414. */
  1415. while ( *++pszCmdLine && (*pszCmdLine != '\"') );
  1416. /*
  1417. * If we stopped on a double-quote (usual case), skip
  1418. * over it.
  1419. */
  1420. if ( *pszCmdLine == '\"' )
  1421. pszCmdLine++;
  1422. }
  1423. else {
  1424. while (*pszCmdLine > ' ')
  1425. pszCmdLine++;
  1426. }
  1427. /*
  1428. * Skip past any white space preceeding the second token.
  1429. */
  1430. while (*pszCmdLine && (*pszCmdLine <= ' ')) {
  1431. pszCmdLine++;
  1432. }
  1433. si.dwFlags = 0;
  1434. GetStartupInfoA(&si);
  1435. WinMain(GetModuleHandle(NULL), NULL, pszCmdLine,
  1436. si.dwFlags & STARTF_USESHOWWINDOW ? si.wShowWindow : SW_SHOWDEFAULT);
  1437. OleUninitialize();
  1438. ExitProcess(0);
  1439. return 0; // We never come here
  1440. }
  1441. UINT CheckUninstIEVersion()
  1442. {
  1443. HKEY hKey;
  1444. DWORD dwSize;
  1445. TCHAR szPreIEVer[50];
  1446. WORD wPreIEVer[4];
  1447. UINT uRet = LESSIE4;
  1448. if ( RegOpenKeyEx( HKEY_CURRENT_USER, c_szActInstalledIEGUIDRestore, 0, KEY_READ, &hKey) != ERROR_SUCCESS )
  1449. {
  1450. if ( RegOpenKeyEx( HKEY_CURRENT_USER, c_szActInstalledIEGUID, 0, KEY_READ, &hKey) != ERROR_SUCCESS )
  1451. {
  1452. return uRet;
  1453. }
  1454. }
  1455. dwSize = sizeof( szPreIEVer );
  1456. if ( RegQueryValueEx(hKey, TEXT("Version"), NULL, NULL, (LPBYTE)szPreIEVer, &dwSize) == ERROR_SUCCESS )
  1457. {
  1458. ConvertVersionString( szPreIEVer, wPreIEVer, ',' );
  1459. if ((wPreIEVer[0] == 0x0004) && (wPreIEVer[1]>=0x0047))
  1460. uRet = IE4;
  1461. else if (wPreIEVer[0] == 0x0005)
  1462. {
  1463. if (wPreIEVer[1] >= 0x0032)
  1464. uRet = IE55;
  1465. else
  1466. uRet = IE5;
  1467. }
  1468. else if (wPreIEVer[0] == 0x0006)
  1469. uRet = IE6;
  1470. }
  1471. RegCloseKey(hKey);
  1472. return uRet;
  1473. }
  1474. BOOL IsPrevIE4()
  1475. {
  1476. HKEY hKey;
  1477. DWORD dwSize;
  1478. TCHAR szPreIEVer[50];
  1479. WORD wPreIEVer[4];
  1480. BOOL bRet = FALSE;
  1481. if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, c_szIE4Setup, 0, KEY_READ, &hKey) == ERROR_SUCCESS )
  1482. {
  1483. dwSize = sizeof( szPreIEVer );
  1484. if ( RegQueryValueEx(hKey, c_szPreIEVer, NULL, NULL, (LPBYTE)szPreIEVer, &dwSize) == ERROR_SUCCESS )
  1485. {
  1486. ConvertVersionString( szPreIEVer, wPreIEVer, '.' );
  1487. if ( (wPreIEVer[0] == 0x0004) && (wPreIEVer[1]>=0x0047) )
  1488. {
  1489. bRet = TRUE;
  1490. }
  1491. }
  1492. RegCloseKey(hKey);
  1493. }
  1494. return bRet;
  1495. }
  1496. BOOL IsPrevIE4WebShell()
  1497. {
  1498. HKEY hKey;
  1499. DWORD dwSize;
  1500. TCHAR szPreShellVer[50];
  1501. WORD wPreShellVer[4];
  1502. BOOL bRet = FALSE;
  1503. if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, c_szIE4Setup, 0, KEY_READ, &hKey) == ERROR_SUCCESS )
  1504. {
  1505. dwSize = sizeof( szPreShellVer );
  1506. if ( RegQueryValueEx(hKey, c_szPreShellVer, NULL, NULL, (LPBYTE)szPreShellVer, &dwSize) == ERROR_SUCCESS )
  1507. {
  1508. ConvertVersionString( szPreShellVer, wPreShellVer, '.' );
  1509. if ((wPreShellVer[0] == 0x0004) && (wPreShellVer[1]>=0x0047) )
  1510. {
  1511. bRet = TRUE;
  1512. }
  1513. }
  1514. RegCloseKey(hKey);
  1515. }
  1516. return bRet;
  1517. }
  1518. const TCHAR c_szMouseExceptions[] = TEXT("Control Panel\\Microsoft Input Devices\\Mouse\\Exceptions");
  1519. // This gets written to the registry
  1520. const TCHAR c_szFilename[] = TEXT("FileName");
  1521. const TCHAR c_szInternetExplorer[] = TEXT("Internet Explorer");
  1522. const TCHAR c_szDescription[] = TEXT("Description");
  1523. const TCHAR c_szVersion[] = TEXT("Version");
  1524. const TCHAR c_szIE[] = TEXT("IEXPLORE.EXE");
  1525. #define IE_VERSION 0x50000
  1526. void ProcessMouseException()
  1527. {
  1528. HKEY hKey;
  1529. HKEY hSubKey;
  1530. DWORD dwIndex = 1001; // start with 1001.
  1531. TCHAR szSubKey[16];
  1532. BOOL bCannotUse = TRUE;
  1533. TCHAR szData[MAX_PATH];
  1534. RemoveOldMouseException();
  1535. if (RegCreateKeyEx(HKEY_CURRENT_USER, c_szMouseExceptions, 0, NULL, 0, KEY_WRITE|KEY_READ, NULL, &hKey, NULL) == ERROR_SUCCESS)
  1536. {
  1537. while (bCannotUse)
  1538. {
  1539. wsprintf(szSubKey, "%d", dwIndex);
  1540. if (RegOpenKeyEx(hKey, szSubKey, 0, KEY_READ, &hSubKey) == ERROR_SUCCESS)
  1541. {
  1542. RegCloseKey(hSubKey);
  1543. dwIndex++;
  1544. }
  1545. else
  1546. bCannotUse = FALSE;
  1547. }
  1548. if (RegCreateKeyEx(hKey, szSubKey, 0, NULL, 0, KEY_WRITE, NULL, &hSubKey, NULL) == ERROR_SUCCESS)
  1549. {
  1550. if (!LoadString(g_hinst, IDS_IE_APPNAME, szData, sizeof(szData)))
  1551. lstrcpy(szData, c_szInternetExplorer);
  1552. RegSetValueEx(hSubKey, c_szDescription, 0, REG_SZ, (LPBYTE)szData, (lstrlen(szData)+1) * sizeof(TCHAR));
  1553. RegSetValueEx(hSubKey, c_szFilename, 0, REG_SZ, (LPBYTE)c_szIE, (lstrlen(c_szIE)+1) * sizeof(TCHAR));
  1554. dwIndex = IE_VERSION;
  1555. RegSetValueEx(hSubKey, c_szVersion, 0, REG_DWORD, (LPBYTE)&dwIndex , sizeof(DWORD));
  1556. RegCloseKey(hSubKey);
  1557. }
  1558. RegCloseKey(hKey);
  1559. }
  1560. }
  1561. void RemoveOldMouseException()
  1562. {
  1563. HKEY hKey;
  1564. HKEY hSubKey;
  1565. DWORD dwIndex = 0;
  1566. BOOL bFound = FALSE;
  1567. LONG lRet = ERROR_SUCCESS;
  1568. TCHAR szSubKey[MAX_PATH];
  1569. DWORD dwSize;
  1570. TCHAR szData[MAX_PATH];
  1571. if (RegOpenKeyEx(HKEY_CURRENT_USER, c_szMouseExceptions, 0, KEY_READ|KEY_WRITE, &hKey) == ERROR_SUCCESS)
  1572. {
  1573. while (!bFound && (lRet == ERROR_SUCCESS))
  1574. {
  1575. dwSize = sizeof(szSubKey);
  1576. lRet = RegEnumKeyEx(hKey, dwIndex, szSubKey, &dwSize, NULL, NULL, NULL, NULL);
  1577. if (lRet == ERROR_SUCCESS)
  1578. {
  1579. if (RegOpenKeyEx(hKey, szSubKey, 0, KEY_READ, &hSubKey) == ERROR_SUCCESS)
  1580. {
  1581. dwSize = sizeof(szData);
  1582. if (RegQueryValueEx(hSubKey, c_szFilename,NULL, NULL, (LPBYTE)szData, &dwSize) == ERROR_SUCCESS)
  1583. {
  1584. bFound = (lstrcmpi(szData, c_szIE) == 0);
  1585. }
  1586. RegCloseKey(hSubKey);
  1587. }
  1588. if (bFound)
  1589. {
  1590. RegDeleteKey(hKey, szSubKey);
  1591. }
  1592. else
  1593. dwIndex++;
  1594. }
  1595. }
  1596. RegCloseKey(hKey);
  1597. }
  1598. }