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.

1020 lines
30 KiB

  1. #include <windows.h>
  2. #include <windowsx.h>
  3. #include <shlwapi.h>
  4. #include <shlobj.h>
  5. #include <regstr.h>
  6. #include <advpub.h>
  7. #include "resource.h"
  8. #include <ntverp.h> //these are for
  9. #include <common.ver> //ver_productversion_str
  10. #include "..\inc\iedkbrnd.h"
  11. #include "..\ieakutil\ieakutil.h"
  12. #define OS_WIN95 0
  13. #define OS_WINNT3X 1
  14. #define OS_WINNT40 2
  15. #define OS_WINNT50 3
  16. #define UPGRADE_OLD 1 // indicates upgrading from an older version of IEAK. Example: 501 to 5.5
  17. #define UPGRADE_EXISTING 2 // indicates upgrading between builds of newer version. Example: 5.5(old) to 5.5(new)
  18. #define INSTALL_NEW 3 // indicates first time installation
  19. #define INSTALL_SIDEBYSIDE 4 // indicates install side by side. Example: 501 & 5.5 exists in different directory
  20. #define ADVPACKDLL TEXT("advpack.dll")
  21. #define IEAKWIZEXE TEXT("ieakwiz.exe")
  22. #define IEAK6WIZEXE TEXT("ieak6wiz.exe")
  23. #define HasFlag(dwFlags, dwMask) (((DWORD)(dwFlags) & (DWORD)(dwMask)) != 0L)
  24. #define ErrorMessageBox1(hWnd, idErrorStr, dwFlags) \
  25. ErrorMessageBox(hWnd, idErrorStr, NULL, dwFlags)
  26. #define ErrorMessageBox2(hWnd, pcszMsg, dwFlags) \
  27. ErrorMessageBox(hWnd, 0, pcszMsg, dwFlags)
  28. typedef HRESULT (WINAPI *RUNSETUPCOMMAND) (HWND, LPCSTR, LPCSTR, LPCSTR, LPCSTR, HANDLE *, DWORD, LPVOID);
  29. static TCHAR g_szRUNSETUPCOMMAND[] = TEXT("RunSetupCommand");
  30. // global variables
  31. HINSTANCE g_hInstance;
  32. TCHAR g_szCurrentDir[MAX_PATH];
  33. TCHAR g_szInf[MAX_PATH];
  34. HRESULT g_hResult;
  35. BOOL g_fQuietMode;
  36. int g_dwType = INTRANET;
  37. //
  38. int WINAPI ErrorMessageBox(HWND hWnd, UINT idErrorStr, LPCTSTR pcszMsg, DWORD dwFlags)
  39. {
  40. int nRetVal = IDOK;
  41. if (!g_fQuietMode)
  42. {
  43. TCHAR szTitle[MAX_PATH];
  44. LoadString(g_hInstance, IDS_TITLE, szTitle, countof(szTitle));
  45. if (pcszMsg != NULL)
  46. {
  47. nRetVal = MessageBox(hWnd, pcszMsg, szTitle, dwFlags | MB_APPLMODAL | MB_SETFOREGROUND);
  48. }
  49. else
  50. {
  51. TCHAR szMsg[MAX_PATH];
  52. LoadString(g_hInstance, idErrorStr, szMsg, countof(szMsg));
  53. nRetVal = MessageBox(hWnd, szMsg, szTitle, dwFlags | MB_APPLMODAL | MB_SETFOREGROUND);
  54. }
  55. }
  56. return nRetVal;
  57. }
  58. void EnableDBCSChar(HWND hDlg, int iCtrlID)
  59. {
  60. static HFONT s_hfontSys = NULL;
  61. LOGFONT lf;
  62. HDC hDC;
  63. HWND hwndCtrl = GetDlgItem(hDlg, iCtrlID);
  64. HFONT hFont;
  65. int cyLogPixels;
  66. hDC = GetDC(NULL);
  67. if (hDC == NULL)
  68. return;
  69. cyLogPixels = GetDeviceCaps(hDC, LOGPIXELSY);
  70. ReleaseDC(NULL, hDC);
  71. if (s_hfontSys == NULL)
  72. {
  73. LOGFONT lfTemp;
  74. HFONT hfontDef = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
  75. GetObject(hfontDef, sizeof(lfTemp), &lfTemp);
  76. hFont = GetWindowFont(hwndCtrl);
  77. if (hFont != NULL)
  78. if (GetObject(hFont, sizeof(LOGFONT), (PVOID)&lf))
  79. {
  80. StrCpy(lf.lfFaceName, lfTemp.lfFaceName);
  81. lf.lfQuality = lfTemp.lfQuality;
  82. lf.lfPitchAndFamily = lfTemp.lfPitchAndFamily;
  83. lf.lfCharSet = lfTemp.lfCharSet;
  84. s_hfontSys = CreateFontIndirect(&lf);
  85. }
  86. }
  87. if (iCtrlID == 0xFFFF)
  88. return;
  89. if (s_hfontSys != NULL)
  90. SetWindowFont(hwndCtrl, s_hfontSys, FALSE);
  91. }
  92. BOOL IsFullPath(LPCTSTR pcszPath)
  93. {
  94. if ((pcszPath == NULL) || (lstrlen(pcszPath) < 3) || !PathIsValidPath(pcszPath))
  95. return FALSE;
  96. return TRUE;
  97. }
  98. BOOL CreateFullPath(LPCTSTR pcszPath)
  99. {
  100. TCHAR szPath[MAX_PATH];
  101. LPTSTR pszPoint = NULL;
  102. BOOL fLastDir = FALSE;
  103. if (!IsFullPath(pcszPath))
  104. return FALSE;
  105. StrCpy(szPath, pcszPath);
  106. if (lstrlen(szPath) > 3)
  107. {
  108. LPTSTR szTemp;
  109. szTemp = CharPrev(szPath, szPath + lstrlen(szPath)) ;
  110. if (szTemp > szPath && *szTemp == TEXT('\\'))
  111. *szTemp = TEXT('\0');
  112. }
  113. // If it's a UNC path, seek up to the first share name.
  114. if (szPath[0] == TEXT('\\') && szPath[1] == TEXT('\\'))
  115. {
  116. pszPoint = &szPath[2];
  117. for (int nCount = 0; nCount < 2; nCount++)
  118. {
  119. while (*pszPoint != TEXT('\\'))
  120. {
  121. if (*pszPoint == TEXT('\0'))
  122. {
  123. // Share name missing? Else, nothing after share name!
  124. if (nCount == 0)
  125. return FALSE;
  126. return TRUE;
  127. }
  128. pszPoint = CharNext(pszPoint);
  129. }
  130. }
  131. pszPoint = CharNext(pszPoint);
  132. }
  133. else
  134. {
  135. // Otherwise, just point to the beginning of the first directory
  136. pszPoint = &szPath[3];
  137. }
  138. while (*pszPoint != TEXT('\0'))
  139. {
  140. while (*pszPoint != TEXT('\\') && *pszPoint != TEXT('\0'))
  141. pszPoint = CharNext(pszPoint);
  142. if (*pszPoint == TEXT('\0'))
  143. fLastDir = TRUE;
  144. *pszPoint = TEXT('\0');
  145. if (GetFileAttributes(szPath) == 0xFFFFFFFF)
  146. {
  147. if (!CreateDirectory(szPath, NULL))
  148. return FALSE;
  149. }
  150. if (fLastDir)
  151. break;
  152. *pszPoint = TEXT('\\');
  153. pszPoint = CharNext(pszPoint);
  154. }
  155. return TRUE;
  156. }
  157. DWORD FolderSize(LPCTSTR pszFolderName)
  158. {
  159. DWORD dwSize = 0;
  160. WIN32_FIND_DATA fileData;
  161. HANDLE hFindFile;
  162. TCHAR szFile[MAX_PATH];
  163. if (pszFolderName == NULL || *pszFolderName == TEXT('\0'))
  164. return dwSize;
  165. PathCombine(szFile, pszFolderName, TEXT("*"));
  166. if ((hFindFile = FindFirstFile(szFile, &fileData)) != INVALID_HANDLE_VALUE)
  167. {
  168. do
  169. {
  170. if (!(fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
  171. dwSize += fileData.nFileSizeLow;
  172. } while (FindNextFile(hFindFile, &fileData));
  173. FindClose(hFindFile);
  174. }
  175. // convert bytes to KB
  176. dwSize = dwSize >> 10;
  177. return dwSize;
  178. }
  179. DWORD GetSpace(LPCTSTR pcszPath)
  180. {
  181. DWORD dwSecsPerCluster = 0;
  182. DWORD dwBytesPerSector = 0;
  183. DWORD dwFreeClusters = 0;
  184. DWORD dwTotalClusters = 0;
  185. DWORD dwClusterSize = 0;
  186. DWORD dwFreeBytes = 0;
  187. if(*pcszPath == TEXT('\0'))
  188. return 0;
  189. if (!GetDiskFreeSpace(pcszPath, &dwSecsPerCluster, &dwBytesPerSector, &dwFreeClusters, &dwTotalClusters))
  190. return 0;
  191. dwClusterSize = dwBytesPerSector * dwSecsPerCluster;
  192. dwFreeBytes = MulDiv(dwClusterSize, dwFreeClusters, 1024);
  193. return dwFreeBytes;
  194. }
  195. BOOL HasEnoughSpace(HWND hDlg, LPCTSTR pcszPath, DWORD dwNeedSize, LPDWORD pdwPadSize)
  196. {
  197. TCHAR szDrive[MAX_PATH];
  198. DWORD dwFreeBytes = 0;
  199. DWORD dwVolFlags, dwMaxCompLen;
  200. // set to zero to indicate to caller that the given drive can not be checked.
  201. if (pdwPadSize)
  202. *pdwPadSize = 0;
  203. if (dwNeedSize == 0)
  204. return TRUE;
  205. // If you are here, we expect that the caller have validated the path which
  206. // has the Fullpath directory name
  207. //
  208. if (pcszPath[1] == TEXT(':'))
  209. StrCpyN(szDrive, pcszPath, 4);
  210. else if (pcszPath[0] == TEXT('\\') && pcszPath[1] == TEXT('\\'))
  211. return TRUE; //no way to get it
  212. else
  213. return FALSE; // you should not get here, if so, we don't know how to check it.
  214. if ((dwFreeBytes = GetSpace(szDrive)) == 0)
  215. {
  216. TCHAR szMsg[MAX_PATH];
  217. LPTSTR pMsg;
  218. LoadString(g_hInstance, IDS_ERR_GET_DISKSPACE, szMsg, countof(szMsg));
  219. pMsg = FormatString(szMsg, szDrive);
  220. ErrorMessageBox2(hDlg, pMsg, MB_ICONEXCLAMATION | MB_OK);
  221. LocalFree(pMsg);
  222. return FALSE;
  223. }
  224. // find out if the drive is compressed
  225. if (!GetVolumeInformation(szDrive, NULL, 0, NULL, &dwMaxCompLen, &dwVolFlags, NULL, 0))
  226. {
  227. TCHAR szMsg[MAX_PATH];
  228. LPTSTR pMsg;
  229. LoadString(g_hInstance, IDS_ERR_GETVOLINFOR, szMsg, countof(szMsg));
  230. pMsg = FormatString(szMsg, szDrive);
  231. ErrorMessageBox2(hDlg, pMsg, MB_ICONEXCLAMATION | MB_OK);
  232. LocalFree(pMsg);
  233. return FALSE;
  234. }
  235. if (pdwPadSize)
  236. *pdwPadSize = dwNeedSize;
  237. if ((dwVolFlags & FS_VOL_IS_COMPRESSED))
  238. {
  239. dwNeedSize = dwNeedSize + dwNeedSize/4;
  240. if (pdwPadSize)
  241. *pdwPadSize = dwNeedSize;
  242. }
  243. if (dwNeedSize > dwFreeBytes)
  244. return FALSE;
  245. else
  246. return TRUE;
  247. }
  248. BOOL IsValidDir(LPCTSTR pcszPath)
  249. {
  250. DWORD dwAttribs;
  251. HANDLE hFile;
  252. TCHAR szTestFile[MAX_PATH];
  253. PathCombine(szTestFile, pcszPath, TEXT("TMP4352$.TMP"));
  254. DeleteFile(szTestFile);
  255. hFile = CreateFile(szTestFile, GENERIC_WRITE, 0, NULL, CREATE_NEW,
  256. FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, NULL);
  257. if (hFile == INVALID_HANDLE_VALUE)
  258. return FALSE;
  259. CloseHandle(hFile);
  260. dwAttribs = GetFileAttributes(pcszPath);
  261. if ((dwAttribs != 0xFFFFFFFF) && (dwAttribs & FILE_ATTRIBUTE_DIRECTORY))
  262. return TRUE;
  263. return FALSE;
  264. }
  265. BOOL BrowseForDir(HWND hParent, LPCTSTR pszTitle, LPTSTR pszDir)
  266. {
  267. BROWSEINFO bi;
  268. LPITEMIDLIST pidl;
  269. ZeroMemory(&bi, sizeof(bi));
  270. bi.hwndOwner = hParent;
  271. bi.pidlRoot = NULL;
  272. bi.pszDisplayName = pszDir;
  273. bi.lpszTitle = pszTitle;
  274. bi.ulFlags = BIF_RETURNONLYFSDIRS;
  275. pidl = SHBrowseForFolder(&bi);
  276. if(pidl)
  277. {
  278. SHGetPathFromIDList(pidl, pszDir);
  279. //SHFree(pidl);
  280. return TRUE;
  281. }
  282. return FALSE;
  283. }
  284. int GetOSVersion()
  285. {
  286. OSVERSIONINFO verinfo; // Version Check
  287. int nOSVersion;
  288. verinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  289. if (GetVersionEx(&verinfo) == FALSE)
  290. return -1;
  291. switch (verinfo.dwPlatformId)
  292. {
  293. case VER_PLATFORM_WIN32_WINDOWS: // Win95
  294. nOSVersion = OS_WIN95;
  295. break;
  296. case VER_PLATFORM_WIN32_NT: // Win NT
  297. nOSVersion = OS_WINNT40;
  298. if (verinfo.dwMajorVersion <= 3)
  299. nOSVersion = OS_WINNT3X;
  300. else if (verinfo.dwMajorVersion >= 5)
  301. nOSVersion = OS_WINNT50;
  302. break;
  303. default:
  304. nOSVersion = -1;
  305. break;
  306. }
  307. return nOSVersion;
  308. }
  309. BOOL GetProgramFilesDir(LPTSTR pszPrgfDir, DWORD cchSize)
  310. {
  311. int nOSVersion;
  312. DWORD dwType,
  313. cbSize;
  314. nOSVersion = GetOSVersion();
  315. *pszPrgfDir = 0;
  316. if (nOSVersion >= OS_WINNT50)
  317. {
  318. if (GetEnvironmentVariable(TEXT("ProgramFiles"), pszPrgfDir, cchSize))
  319. return TRUE;
  320. }
  321. dwType = REG_SZ;
  322. cbSize = cchSize * sizeof(TCHAR);
  323. if (SHGetValue(HKEY_LOCAL_MACHINE, REGSTR_PATH_SETUP, TEXT("ProgramFilesDir"), &dwType, (LPVOID) pszPrgfDir, &cbSize) == ERROR_SUCCESS)
  324. {
  325. if (nOSVersion >= OS_WINNT40)
  326. {
  327. TCHAR szSysDrv[5] = { 0 };
  328. // combine reg value and systemDrive to get the acurate ProgramFiles dir
  329. if (GetEnvironmentVariable(TEXT("SystemDrive"), szSysDrv, countof(szSysDrv)) && *szSysDrv)
  330. *pszPrgfDir = *szSysDrv;
  331. }
  332. return TRUE;
  333. }
  334. return FALSE;
  335. }
  336. void SHCopyKey(HKEY hkFrom, HKEY hkTo)
  337. {
  338. TCHAR szData[1024],
  339. szValue[MAX_PATH];
  340. DWORD dwSize, dwVal, dwSizeData, dwType;
  341. HKEY hkSubkeyFrom, hkSubkeyTo;
  342. dwVal = 0;
  343. dwSize = countof(szValue);
  344. dwSizeData = sizeof(szData);
  345. while (ERROR_SUCCESS == RegEnumValue(hkFrom, dwVal++, szValue, &dwSize, NULL, &dwType, (LPBYTE)szData, &dwSizeData)) {
  346. RegSetValueEx(hkTo, szValue, 0, dwType, (LPBYTE)szData, dwSizeData);
  347. dwSize = countof(szValue);
  348. dwSizeData = sizeof(szData);
  349. }
  350. dwVal = 0;
  351. while (ERROR_SUCCESS == RegEnumKey(hkFrom, dwVal++, szValue, countof(szValue)))
  352. if (ERROR_SUCCESS == RegOpenKeyEx(hkFrom, szValue, 0, KEY_READ | KEY_WRITE, &hkSubkeyFrom))
  353. if (RegCreateKeyEx(hkTo, szValue, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WRITE, NULL, &hkSubkeyTo, NULL) == ERROR_SUCCESS)
  354. SHCopyKey(hkSubkeyFrom, hkSubkeyTo);
  355. }
  356. void SHCopyValue(HKEY hkFrom, HKEY hkTo, LPCTSTR pcszSubKey, LPCTSTR pcszValue)
  357. {
  358. TCHAR szBuffer[MAX_PATH];
  359. DWORD dwType, cbBuffer;
  360. dwType = REG_SZ;
  361. cbBuffer = sizeof(szBuffer);
  362. if (SHGetValue(hkFrom, pcszSubKey, pcszValue, &dwType, (LPVOID)szBuffer, &cbBuffer) == ERROR_SUCCESS)
  363. {
  364. cbBuffer = lstrlen(szBuffer) * sizeof(TCHAR);
  365. SHSetValue(hkTo, pcszSubKey, pcszValue, dwType, (LPCVOID)szBuffer, cbBuffer);
  366. }
  367. }
  368. HRESULT InstallIEAK(HWND hDlg, LPCTSTR pcszPath, int nUpgrade, DWORD dwMode)
  369. {
  370. HINSTANCE hAdvPackDll;
  371. TCHAR szPath[MAX_PATH],
  372. szTitle[MAX_PATH],
  373. szInf[MAX_PATH];
  374. RUNSETUPCOMMAND pRunSetupCommand;
  375. HRESULT hResult = S_OK;
  376. PathCombine(szPath, g_szCurrentDir, ADVPACKDLL);
  377. hAdvPackDll = LoadLibrary(szPath);
  378. if (hAdvPackDll == NULL)
  379. {
  380. TCHAR szMsg[MAX_PATH];
  381. LPTSTR pMsg;
  382. LoadString(g_hInstance, IDS_ERR_LOAD_DLL, szMsg, countof(szMsg));
  383. pMsg = FormatString(szMsg, ADVPACKDLL);
  384. ErrorMessageBox2(hDlg, pMsg, MB_ICONEXCLAMATION | MB_OK);
  385. LocalFree(pMsg);
  386. return E_FAIL;
  387. }
  388. pRunSetupCommand = (RUNSETUPCOMMAND) GetProcAddress(hAdvPackDll, g_szRUNSETUPCOMMAND);
  389. if (pRunSetupCommand == NULL)
  390. {
  391. TCHAR szMsg[MAX_PATH];
  392. LPTSTR pMsg;
  393. LoadString(g_hInstance, IDS_ERR_GET_PROC_ADDR, szMsg, countof(szMsg));
  394. pMsg = FormatString(szMsg, g_szRUNSETUPCOMMAND);
  395. ErrorMessageBox2(hDlg, pMsg, MB_ICONEXCLAMATION | MB_OK);
  396. LocalFree(pMsg);
  397. FreeLibrary(hAdvPackDll);
  398. return E_FAIL;
  399. }
  400. LoadString(g_hInstance, IDS_TITLE, szTitle, countof(szTitle));
  401. PathCombine(szInf, g_szCurrentDir, g_szInf);
  402. if (*pcszPath != TEXT('\0'))
  403. {
  404. SHSetValue(HKEY_CURRENT_USER, TEXT("Software\\Microsoft\\IEAK6"), TEXT("InstallPath"),
  405. REG_SZ, pcszPath, lstrlen(pcszPath) * sizeof(TCHAR));
  406. }
  407. ShowWindow(hDlg, SW_HIDE);
  408. if (nUpgrade == UPGRADE_OLD)
  409. {
  410. pRunSetupCommand(hDlg, szInf, TEXT("ClearOldSettings"), g_szCurrentDir, szTitle,
  411. NULL, RSC_FLAG_INF | RSC_FLAG_QUIET, 0);
  412. }
  413. hResult = pRunSetupCommand(hDlg, szInf, NULL, g_szCurrentDir, szTitle,
  414. NULL, (RSC_FLAG_INF | (g_fQuietMode ? RSC_FLAG_QUIET : 0)), 0);
  415. if (hResult == S_OK)
  416. {
  417. BOOL fUpdate = TRUE;
  418. if (nUpgrade == UPGRADE_OLD || nUpgrade == INSTALL_SIDEBYSIDE)
  419. {
  420. HKEY hkSrc, hkDest;
  421. hkSrc = hkDest = NULL;
  422. if ((RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Software\\Microsoft\\IEAK"), 0, KEY_READ | KEY_WRITE, &hkSrc) == ERROR_SUCCESS) &&
  423. (RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Software\\Microsoft\\IEAK6"), 0, KEY_READ | KEY_WRITE, &hkDest) == ERROR_SUCCESS))
  424. {
  425. if (nUpgrade == UPGRADE_OLD)
  426. {
  427. // copy all the values from old location to the new location
  428. SHCopyKey(hkSrc, hkDest);
  429. }
  430. else // INSTALL_SIDEBYSIDE
  431. {
  432. SHCopyValue(hkSrc, hkDest, TEXT("Main"), TEXT("Company"));
  433. SHCopyValue(hkSrc, hkDest, TEXT("Main"), TEXT("KeyCode"));
  434. fUpdate = FALSE;
  435. }
  436. }
  437. if (hkSrc != NULL)
  438. RegCloseKey(hkSrc);
  439. if (hkDest != NULL)
  440. RegCloseKey(hkDest);
  441. if (nUpgrade == UPGRADE_OLD)
  442. SHDeleteKey(HKEY_CURRENT_USER, TEXT("Software\\Microsoft\\IEAK"));
  443. }
  444. else if (nUpgrade == UPGRADE_EXISTING)
  445. {
  446. TCHAR szOldWizPath[MAX_PATH];
  447. DWORD dwType = REG_SZ;
  448. DWORD cbSize = sizeof(szOldWizPath);
  449. // if ieak501 exists in another location, do not update the AppPaths\ieakwiz.exe key
  450. if (SHGetValue(HKEY_LOCAL_MACHINE, REGSTR_PATH_APPPATHS TEXT("\\IEAKWIZ.EXE"), NULL, &dwType,
  451. (LPVOID)szOldWizPath, &cbSize) == ERROR_SUCCESS)
  452. {
  453. if (StrCmpI(PathFindFileName(szOldWizPath), IEAKWIZEXE) == 0)
  454. fUpdate = FALSE;
  455. }
  456. }
  457. if (fUpdate)
  458. {
  459. TCHAR szOldWizPath[MAX_PATH];
  460. SHSetValue(HKEY_LOCAL_MACHINE, REGSTR_PATH_APPPATHS TEXT("\\IEAKWIZ.EXE"), TEXT("Path"), REG_SZ,
  461. pcszPath, lstrlen(pcszPath) * sizeof(TCHAR));
  462. PathCombine(szOldWizPath, pcszPath, IEAK6WIZEXE);
  463. SHSetValue(HKEY_LOCAL_MACHINE, REGSTR_PATH_APPPATHS TEXT("\\IEAKWIZ.EXE"), NULL, REG_SZ,
  464. szOldWizPath, lstrlen(szOldWizPath) * sizeof(TCHAR));
  465. }
  466. HKEY hKey;
  467. if (RegCreateKeyEx(HKEY_LOCAL_MACHINE,TEXT("Software\\Microsoft\\IEAK"),NULL,NULL,NULL,KEY_SET_VALUE,NULL,&hKey,NULL) == ERROR_SUCCESS)
  468. {
  469. RegSetValueEx(hKey,TEXT("Version"),NULL,REG_SZ,(LPBYTE)VER_PRODUCTVERSION_STR,(lstrlen(VER_PRODUCTVERSION_STR)+1) * sizeof(TCHAR));
  470. RegSetValueEx(hKey,TEXT("Mode"),NULL,REG_DWORD,g_fQuietMode ? (CONST BYTE *) &g_dwType : (CONST BYTE *) &dwMode,sizeof(DWORD));
  471. }
  472. }
  473. return hResult;
  474. }
  475. void CenterWindow(HWND hwnd)
  476. {
  477. int nScreenx;
  478. int nScreeny;
  479. int nHeight, nWidth, x, y;
  480. RECT rect;
  481. nScreenx = GetSystemMetrics(SM_CXSCREEN);
  482. nScreeny = GetSystemMetrics(SM_CYSCREEN);
  483. GetWindowRect(hwnd, &rect);
  484. nWidth = rect.right - rect.left;
  485. nHeight = rect.bottom - rect.top;
  486. x = (nScreenx / 2) - (nWidth / 2);
  487. y = (nScreeny / 2) - (nHeight / 2);
  488. SetWindowPos(hwnd, HWND_TOP, x, y, nWidth, nHeight, SWP_NOZORDER);
  489. }
  490. void InitPath(HWND hDlg, LPTSTR pszDefaultPath, LPBOOL pnUpgrade)
  491. {
  492. TCHAR szPath[MAX_PATH];
  493. DWORD dwType, cbSize;
  494. int nUpgrade = INSTALL_NEW;
  495. *szPath = TEXT('\0');
  496. // check for the upgrade path
  497. dwType = REG_SZ;
  498. cbSize = sizeof(szPath);
  499. *szPath = TEXT('\0');
  500. if (SHGetValue(HKEY_LOCAL_MACHINE, REGSTR_PATH_APPPATHS TEXT("\\IEAK6WIZ.EXE"),
  501. TEXT("Path"), &dwType, (LPVOID) szPath, &cbSize) != ERROR_SUCCESS)
  502. {
  503. dwType = REG_SZ;
  504. cbSize = sizeof(szPath);
  505. if (SHGetValue(HKEY_LOCAL_MACHINE, REGSTR_PATH_APPPATHS TEXT("\\IEAKWIZ.EXE"),
  506. NULL, &dwType, (LPVOID) szPath, &cbSize) == ERROR_SUCCESS)
  507. {
  508. DWORD dwAttribs;
  509. dwAttribs = GetFileAttributes(szPath);
  510. if (dwAttribs != 0xFFFFFFFF && !(dwAttribs & FILE_ATTRIBUTE_DIRECTORY))
  511. {
  512. if (!g_fQuietMode && ErrorMessageBox1(hDlg, IDS_IEAK_UPGRADE, MB_ICONQUESTION | MB_YESNO) == IDNO)
  513. nUpgrade = INSTALL_SIDEBYSIDE;
  514. else
  515. {
  516. PathRemoveFileSpec(szPath);
  517. nUpgrade = UPGRADE_OLD;
  518. }
  519. }
  520. }
  521. if (nUpgrade == INSTALL_NEW || nUpgrade == INSTALL_SIDEBYSIDE)
  522. {
  523. // default to "Program Files\IEAK6"
  524. if (!GetProgramFilesDir(szPath, countof(szPath)))
  525. LoadString(g_hInstance, IDS_PROGRAMFILES_PATH, szPath, countof(szPath));
  526. PathAppend(szPath, TEXT("IEAK6"));
  527. }
  528. }
  529. else
  530. nUpgrade = UPGRADE_EXISTING;
  531. if (pszDefaultPath != NULL)
  532. StrCpy(pszDefaultPath, szPath);
  533. if (pnUpgrade != NULL)
  534. *pnUpgrade = nUpgrade;
  535. }
  536. BOOL ProcessPath(HWND hDlg, LPTSTR pcszPath, LPTSTR pcszDefaultPath, int nUpgrade)
  537. {
  538. TCHAR szMsg[MAX_PATH],
  539. szTitle[MAX_PATH];
  540. BOOL fClear = FALSE;
  541. DWORD dwTemp = 0;
  542. DWORD dwAttribs;
  543. if (*pcszPath == TEXT('\0') || !IsFullPath(pcszPath))
  544. {
  545. ErrorMessageBox1(hDlg, IDS_ERR_EMPTY_PATH, MB_ICONINFORMATION | MB_OK);
  546. return FALSE;
  547. }
  548. // if installing side by side, make sure that the destination path is different than that of the earlier IEAK
  549. if (nUpgrade == INSTALL_SIDEBYSIDE)
  550. {
  551. DWORD dwType, cbSize;
  552. TCHAR szIEAKOldPath[MAX_PATH];
  553. dwType = REG_SZ;
  554. cbSize = sizeof(szIEAKOldPath);
  555. if (SHGetValue(HKEY_LOCAL_MACHINE, REGSTR_PATH_APPPATHS TEXT("\\IEAKWIZ.EXE"),
  556. TEXT("Path"), &dwType, (LPVOID) szIEAKOldPath, &cbSize) == ERROR_SUCCESS)
  557. {
  558. if (StrCmpI(pcszPath, szIEAKOldPath) == 0)
  559. {
  560. ErrorMessageBox1(hDlg, IDS_SPECIFY_DIFFERENT_PATH, MB_ICONINFORMATION | MB_OK);
  561. return FALSE;
  562. }
  563. }
  564. }
  565. while (!HasEnoughSpace(hDlg, pcszPath, FolderSize(g_szCurrentDir), &dwTemp))
  566. {
  567. if (dwTemp && !g_fQuietMode)
  568. {
  569. TCHAR szMsg[MAX_PATH];
  570. LPTSTR pMsg;
  571. int nResult;
  572. LoadString(g_hInstance, IDS_ERR_NO_SPACE_INST, szMsg, countof(szMsg));
  573. pMsg = FormatString(szMsg, dwTemp);
  574. nResult = ErrorMessageBox2(hDlg, pMsg, MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2);
  575. LocalFree(pMsg);
  576. if (nResult == IDNO)
  577. return FALSE;
  578. }
  579. else // given drive cannot be checked, error has been posted. no further needed or its quiet mode
  580. return FALSE;
  581. }
  582. dwAttribs = GetFileAttributes(pcszPath);
  583. if (dwAttribs == 0xFFFFFFFF)
  584. {
  585. // If this new entry is different from the original, then prompt the user.
  586. if (StrCmpI(pcszPath, pcszDefaultPath) != 0 && !g_fQuietMode)
  587. {
  588. TCHAR szMsg[MAX_PATH];
  589. LPTSTR pMsg;
  590. int nResult;
  591. LoadString(g_hInstance, IDS_CREATE_DIR, szMsg, countof(szMsg));
  592. pMsg = FormatString(szMsg, pcszPath);
  593. nResult = ErrorMessageBox2(hDlg, pMsg, MB_ICONQUESTION | MB_YESNO);
  594. LocalFree(pMsg);
  595. if (nResult == IDNO)
  596. return FALSE;
  597. }
  598. if (!CreateFullPath(pcszPath))
  599. {
  600. TCHAR szMsg[MAX_PATH];
  601. LPTSTR pMsg;
  602. LoadString(g_hInstance, IDS_ERR_CREATE_DIR, szMsg, countof(szMsg));
  603. pMsg = FormatString(szMsg, pcszPath);
  604. ErrorMessageBox2(hDlg, pMsg, MB_ICONEXCLAMATION | MB_OK);
  605. LocalFree(pMsg);
  606. return FALSE;
  607. }
  608. }
  609. if (!IsValidDir(pcszPath))
  610. {
  611. TCHAR szMsg[MAX_PATH];
  612. LPTSTR pMsg;
  613. LoadString(g_hInstance, IDS_ERR_INVALID_DIR, szMsg, countof(szMsg));
  614. pMsg = FormatString(szMsg, pcszPath);
  615. ErrorMessageBox2(hDlg, pMsg, MB_ICONEXCLAMATION | MB_OK);
  616. LocalFree(pMsg);
  617. return FALSE;
  618. }
  619. return TRUE;
  620. }
  621. INT_PTR CALLBACK ConfirmDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
  622. {
  623. switch(msg)
  624. {
  625. case WM_INITDIALOG:
  626. {
  627. TCHAR szTmp[1024];
  628. DWORD dwMode;
  629. dwMode = (DWORD)GetWindowLongPtr(GetParent(hDlg),GWLP_USERDATA);
  630. switch (dwMode)
  631. {
  632. case REDIST:
  633. LoadString(g_hInstance,IDS_ICP,szTmp,countof(szTmp));
  634. break;
  635. case BRANDED:
  636. LoadString(g_hInstance,IDS_ISP,szTmp,countof(szTmp));
  637. break;
  638. case INTRANET:
  639. default:
  640. LoadString(g_hInstance,IDS_CORP,szTmp,countof(szTmp));
  641. break;
  642. }
  643. SetDlgItemText(hDlg,IDC_STATICLICENSE,szTmp);
  644. return TRUE;
  645. }
  646. case WM_COMMAND:
  647. switch (wParam)
  648. {
  649. case IDOK:
  650. EndDialog(hDlg, TRUE);
  651. return TRUE;
  652. case IDCANCEL:
  653. EndDialog(hDlg, FALSE);
  654. return TRUE;
  655. }
  656. }
  657. return FALSE;
  658. }
  659. INT_PTR CALLBACK DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
  660. {
  661. static TCHAR szDefaultPath[MAX_PATH];
  662. static int nUpgrade;
  663. static DWORD dwMode = BRANDED; //default mode
  664. switch(msg)
  665. {
  666. case WM_INITDIALOG:
  667. {
  668. EnableDBCSChar(hDlg, IDE_INSTALLDIR);
  669. InitPath(hDlg, szDefaultPath, &nUpgrade);
  670. SetDlgItemText(hDlg, IDE_INSTALLDIR, szDefaultPath);
  671. CenterWindow(hDlg);
  672. switch (dwMode)
  673. {
  674. case REDIST:
  675. CheckDlgButton(hDlg,IDC_ICP,TRUE);
  676. break;
  677. case BRANDED:
  678. CheckDlgButton(hDlg,IDC_ISP,TRUE);
  679. break;
  680. case INTRANET:
  681. default:
  682. CheckDlgButton(hDlg,IDC_INTRA,TRUE);
  683. break;
  684. }
  685. if(nUpgrade == UPGRADE_OLD)
  686. {
  687. ShowWindow(hDlg, SW_HIDE);
  688. PostMessage(hDlg, WM_COMMAND, MAKEWPARAM(IDOK, BN_CLICKED), 0L);
  689. }
  690. return TRUE;
  691. }
  692. case WM_COMMAND:
  693. switch (wParam)
  694. {
  695. case IDC_BROWSE:
  696. {
  697. TCHAR szPath[MAX_PATH];
  698. GetDlgItemText(hDlg, IDE_INSTALLDIR, szPath, countof(szPath));
  699. TCHAR szInstructions[MAX_PATH];
  700. LoadString(g_hInstance,IDS_INSTALLINSTR,szInstructions,countof(szInstructions));
  701. if (BrowseForDir(hDlg, szInstructions, szPath))
  702. SetDlgItemText(hDlg, IDE_INSTALLDIR, szPath);
  703. return TRUE;
  704. }
  705. case IDC_ICP:
  706. dwMode = REDIST;
  707. break;
  708. case IDC_ISP:
  709. dwMode = BRANDED;
  710. break;
  711. case IDC_INTRA:
  712. dwMode = INTRANET;
  713. break;
  714. case IDOK:
  715. {
  716. TCHAR szPath[MAX_PATH];
  717. SetWindowLongPtr(hDlg,GWLP_USERDATA,dwMode);
  718. if (!DialogBox(g_hInstance, MAKEINTRESOURCE(IDD_CONFIRMLICENSE), hDlg, ConfirmDlgProc))
  719. return TRUE; //keep trying
  720. GetDlgItemText(hDlg, IDE_INSTALLDIR, szPath, countof(szPath));
  721. if (!ProcessPath(hDlg, szPath, szDefaultPath, nUpgrade))
  722. return TRUE;
  723. g_hResult = InstallIEAK(hDlg, szPath, nUpgrade, dwMode);
  724. EndDialog(hDlg, TRUE);
  725. return TRUE;
  726. }
  727. case IDCANCEL:
  728. EndDialog(hDlg, FALSE);
  729. return TRUE;
  730. }
  731. break;
  732. case WM_CLOSE:
  733. EndDialog(hDlg, FALSE);
  734. return TRUE;
  735. }
  736. return FALSE;
  737. }
  738. HRESULT SilentInstallIEAK()
  739. {
  740. TCHAR szPath[MAX_PATH];
  741. int nUpgrade;
  742. InitPath(NULL, szPath, &nUpgrade);
  743. if (!ProcessPath(NULL, szPath, szPath, nUpgrade))
  744. return E_FAIL;
  745. return InstallIEAK(NULL, szPath, nUpgrade, 0 /*default type goes here*/);
  746. }
  747. // Reads the next word in the string pszData and copies it into szWord
  748. // Returns a pointer to the next character after the word
  749. LPTSTR ReadWord(LPTSTR pszData, LPTSTR szWord, int cchLength)
  750. {
  751. int i;
  752. int nIndex;
  753. ZeroMemory(szWord, cchLength*sizeof(TCHAR));
  754. // remove whitespace
  755. i = StrSpn(pszData, TEXT(" \n\t\x0d\x0a"));
  756. pszData += i;
  757. i = StrCSpn(pszData, TEXT(" \n\t\x0d\x0a"));
  758. if(i > cchLength) // make sure we dont overrun our buffer
  759. i = cchLength - 1;
  760. StrCpyN(szWord, pszData, i+1);
  761. pszData += i;
  762. return pszData;
  763. }
  764. void ParseCmdLine(LPTSTR lpCmdLine)
  765. {
  766. LPTSTR pParam;
  767. TCHAR szWord[MAX_PATH];
  768. *g_szInf = TEXT('\0');
  769. g_fQuietMode = FALSE;
  770. pParam = lpCmdLine;
  771. while ((pParam - lpCmdLine) < lstrlen(lpCmdLine))
  772. {
  773. pParam = ReadWord(pParam, szWord, countof(szWord));
  774. if (*szWord != TEXT('\0'))
  775. {
  776. if (szWord[0] == TEXT('/') && (szWord[1] == TEXT('q') || szWord[1] == TEXT('Q')))
  777. g_fQuietMode = TRUE;
  778. else if (szWord[0] == TEXT('/') && (szWord[1] == TEXT('m') || szWord[1] == TEXT('M')))
  779. {
  780. switch (szWord[3])
  781. {
  782. case TEXT('B'):
  783. case TEXT('b'):
  784. g_dwType = BRANDED;
  785. break;
  786. case TEXT('r'):
  787. case TEXT('R'):
  788. g_dwType = REDIST;
  789. break;
  790. case TEXT('I'):
  791. case TEXT('i'):
  792. default:
  793. g_dwType = INTRANET;
  794. break;
  795. }
  796. }
  797. else if (*g_szInf == TEXT('\0'))
  798. StrCpy(g_szInf, szWord);
  799. }
  800. }
  801. }
  802. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nCmdShow)
  803. {
  804. g_hResult = S_OK;
  805. g_hInstance = hInstance;
  806. ParseCmdLine(lpCmdLine);
  807. GetModuleFileName(GetModuleHandle(NULL), g_szCurrentDir, MAX_PATH);
  808. PathRemoveFileSpec(g_szCurrentDir);
  809. if (!IsNTAdmin())
  810. {
  811. if (!g_fQuietMode)
  812. {
  813. TCHAR szError[MAX_PATH];
  814. LoadString(hInstance,IDS_ERR_NOTADMIN,szError,countof(szError));
  815. MessageBox(NULL,szError,NULL,MB_ICONSTOP);
  816. }
  817. g_hResult = E_ACCESSDENIED;
  818. }
  819. else
  820. {
  821. if (g_fQuietMode)
  822. g_hResult = SilentInstallIEAK();
  823. else
  824. {
  825. if (!DialogBox(hInstance, MAKEINTRESOURCE(IDD_INSTALLDIR), NULL, DlgProc))
  826. g_hResult = HRESULT_FROM_WIN32(ERROR_CANCELLED);
  827. }
  828. }
  829. return g_hResult;
  830. }