Source code of Windows XP (NT5)
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.

1065 lines
32 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. File Name:
  4. cachecpl.c
  5. Module :
  6. inetcpl.cpl
  7. Abstract:
  8. This file contains code to set cache config information from the internet
  9. control panel
  10. Author:
  11. Shishir Pardikar
  12. 6/22/96 t-gpease moved entire dailog to this file from "dialdlg.c"
  13. Environment:
  14. User Mode - Win32
  15. Revision History:
  16. --*/
  17. #include "inetcplp.h"
  18. #include "cachecpl.h"
  19. #include <mluisupp.h>
  20. #include <winnls.h>
  21. #ifdef unix
  22. #define DIR_SEPARATOR_CHAR TEXT('/')
  23. #else
  24. #define DIR_SEPARATOR_CHAR TEXT('\\')
  25. #endif /* unix */
  26. #define CONSTANT_MEGABYTE (1024*1024)
  27. INT_PTR CALLBACK
  28. EmptyCacheDlgProc(
  29. HWND hDlg,
  30. UINT uMsg,
  31. WPARAM wParam,
  32. LPARAM lParam);
  33. INT_PTR CALLBACK
  34. EmptyCacheCookiesDlgProc(
  35. HWND hDlg,
  36. UINT uMsg,
  37. WPARAM wParam,
  38. LPARAM lParam);
  39. #ifdef UNICODE
  40. /* GetDiskInfo
  41. A nice way to get volume information
  42. */
  43. BOOL GetDiskInfo(PTSTR pszPath, PDWORD pdwClusterSize, PDWORDLONG pdlAvail,
  44. PDWORDLONG pdlTotal)
  45. {
  46. CHAR szGDFSEXA[MAX_PATH];
  47. SHUnicodeToAnsi(pszPath, szGDFSEXA, ARRAYSIZE(szGDFSEXA));
  48. return GetDiskInfoA(szGDFSEXA, pdwClusterSize, pdlAvail, pdlTotal);
  49. }
  50. #else
  51. #define GetDiskInfo GetDiskInfoA
  52. #endif
  53. /* DispMessage
  54. A quick and easy way to display messages for the cachecpl
  55. */
  56. INT DispMessage(HWND hWnd, UINT Msg, UINT Title, UINT Type)
  57. {
  58. TCHAR szTitle[80];
  59. TCHAR szMessage[1024];
  60. // something went wrong with the registry
  61. // notify user
  62. MLLoadShellLangString(Msg, szMessage, ARRAYSIZE(szMessage));
  63. MLLoadShellLangString(Title, szTitle, ARRAYSIZE(szTitle));
  64. return MessageBox(hWnd, szMessage, szTitle, Type);
  65. }
  66. typedef HRESULT (*PFNSHGETFOLDERPATH)(HWND hwnd, int csidl, HANDLE hToken, DWORD dwFlags, LPTSTR pszPath);
  67. #undef SHGetFolderPath
  68. #ifdef UNICODE
  69. #define SHGETFOLDERPATH_STR "SHGetFolderPathW"
  70. #else
  71. #define SHGETFOLDERPATH_STR "SHGetFolderPathA"
  72. #endif
  73. HRESULT SHGetFolderPath(HWND hwnd, int csidl, HANDLE hToken, DWORD dwFlags, LPTSTR pszPath)
  74. {
  75. HMODULE hmodSHFolder = LoadLibrary(TEXT("shfolder.dll"));
  76. HRESULT hr = E_FAIL;
  77. if (hmodSHFolder)
  78. {
  79. PFNSHGETFOLDERPATH pfn = (PFNSHGETFOLDERPATH)GetProcAddress(hmodSHFolder, SHGETFOLDERPATH_STR);
  80. if (pfn)
  81. {
  82. hr = pfn(hwnd, csidl, hToken, dwFlags, pszPath);
  83. }
  84. FreeLibrary(hmodSHFolder);
  85. }
  86. return hr;
  87. }
  88. // Cache maximum/minimum in MB
  89. #define CACHE_SIZE_CAP 32000
  90. #define CACHE_SIZE_MIN 1
  91. DWORD UpdateCacheQuotaInfo(LPTEMPDLG pTmp, BOOL fUpdate)
  92. {
  93. // The following probably needs to be fixed.
  94. DWORDLONG cKBLimit = pTmp->uiDiskSpaceTotal, cKBSpare = pTmp->uiCacheQuota;
  95. if (cKBLimit==0)
  96. {
  97. return GetLastError();
  98. }
  99. // What's happening in the following sequence:
  100. // We want to ensure that the cache size is
  101. // 1. less than the drive's size (if larger, then reduce to 75% of drive's space
  102. // 2. less than 32 GB
  103. // And adjust percentage accordingly.
  104. if (fUpdate)
  105. {
  106. ASSERT(pTmp->iCachePercent<=100);
  107. if (pTmp->iCachePercent==0)
  108. {
  109. cKBSpare = CACHE_SIZE_MIN;
  110. }
  111. else
  112. {
  113. cKBSpare = (cKBLimit * pTmp->iCachePercent)/ 100;
  114. }
  115. if (cKBSpare > cKBLimit)
  116. {
  117. pTmp->iCachePercent = 75;
  118. cKBSpare = (cKBLimit * pTmp->iCachePercent) / 100;
  119. }
  120. pTmp->uiCacheQuota = (DWORD)cKBSpare;
  121. SetDlgItemInt(pTmp->hDlg, IDC_ADVANCED_CACHE_TEXT_PERCENT, pTmp->uiCacheQuota, FALSE);
  122. }
  123. if (cKBSpare > CACHE_SIZE_CAP)
  124. {
  125. if (fUpdate)
  126. {
  127. cKBSpare = pTmp->uiCacheQuota = CACHE_SIZE_CAP;
  128. SetDlgItemInt(pTmp->hDlg, IDC_ADVANCED_CACHE_TEXT_PERCENT, pTmp->uiCacheQuota, FALSE);
  129. }
  130. fUpdate = FALSE;
  131. }
  132. else if (cKBSpare < CACHE_SIZE_MIN)
  133. {
  134. if (fUpdate)
  135. {
  136. cKBSpare = pTmp->uiCacheQuota = CACHE_SIZE_MIN;
  137. SetDlgItemInt(pTmp->hDlg, IDC_ADVANCED_CACHE_TEXT_PERCENT, pTmp->uiCacheQuota, FALSE);
  138. }
  139. fUpdate = FALSE;
  140. }
  141. else if (cKBSpare > cKBLimit)
  142. {
  143. if (fUpdate)
  144. {
  145. cKBSpare = pTmp->uiCacheQuota = (DWORD)cKBLimit;
  146. SetDlgItemInt(pTmp->hDlg, IDC_ADVANCED_CACHE_TEXT_PERCENT, pTmp->uiCacheQuota, FALSE);
  147. }
  148. fUpdate = FALSE;
  149. }
  150. if (!fUpdate)
  151. {
  152. pTmp->iCachePercent = (WORD)((cKBSpare * 100 + (cKBLimit/2))/cKBLimit);
  153. if (pTmp->iCachePercent>100)
  154. {
  155. pTmp->iCachePercent = 100;
  156. }
  157. SendMessage( pTmp->hwndTrack, TBM_SETPOS, TRUE, pTmp->iCachePercent );
  158. }
  159. return ERROR_SUCCESS;
  160. }
  161. VOID AdjustCacheRange(LPTEMPDLG pTmp)
  162. {
  163. UINT uiMax = 10;
  164. DWORDLONG dlTotal = 0;
  165. if (GetDiskInfo(pTmp->bChangedLocation ? pTmp->szNewCacheLocation : pTmp->szCacheLocation, NULL, NULL, &dlTotal))
  166. {
  167. dlTotal /= (DWORDLONG)CONSTANT_MEGABYTE;
  168. uiMax = (dlTotal < CACHE_SIZE_CAP) ? (UINT)dlTotal : CACHE_SIZE_CAP;
  169. }
  170. SendDlgItemMessage(pTmp->hDlg, IDC_ADVANCED_CACHE_SIZE_SPIN, UDM_SETRANGE, FALSE, MAKELPARAM(uiMax, CACHE_SIZE_MIN));
  171. }
  172. BOOL InvokeCachevu(HWND hDlg)
  173. {
  174. TCHAR szCache[MAX_PATH];
  175. HRESULT hres = SHGetFolderPath(NULL, CSIDL_INTERNET_CACHE | CSIDL_FLAG_CREATE, NULL, 0, szCache);
  176. if (hres == S_OK)
  177. {
  178. DWORD dwAttrib = GetFileAttributes(szCache);
  179. TCHAR szIniFile[MAX_PATH];
  180. PathCombine(szIniFile, szCache, TEXT("desktop.ini"));
  181. if (GetFileAttributes(szIniFile) == -1)
  182. {
  183. DWORD dwAttrib = GetFileAttributes(szCache);
  184. dwAttrib &= ~FILE_ATTRIBUTE_HIDDEN;
  185. dwAttrib |= FILE_ATTRIBUTE_SYSTEM;
  186. // make sure system, but not hidden
  187. SetFileAttributes(szCache, dwAttrib);
  188. WritePrivateProfileString(TEXT(".ShellClassInfo"), TEXT("ConfirmFileOp"), TEXT("0"), szIniFile);
  189. WritePrivateProfileString(TEXT(".ShellClassInfo"), TEXT("UICLSID"), TEXT("{7BD29E00-76C1-11CF-9DD0-00A0C9034933}"), szIniFile);
  190. }
  191. // All seems well, launch it.
  192. SHELLEXECUTEINFO ei = { sizeof(SHELLEXECUTEINFO), 0};
  193. ei.hwnd = hDlg;
  194. ei.lpFile = szCache;
  195. ei.nShow = SW_SHOWNORMAL;
  196. return ShellExecuteEx(&ei);
  197. }
  198. return FALSE;
  199. }
  200. // Following flag swiped from wininet
  201. #define FIND_FLAGS_RETRIEVE_ONLY_STRUCT_INFO 0x2
  202. #define DISK_SPACE_MARGIN 4*1024*1024
  203. // IsEnoughDriveSpace
  204. // verifies that there will enough space for the current contents of the cache
  205. // on the new destination
  206. BOOL IsEnoughDriveSpace(DWORD dwClusterSize, DWORDLONG dlAvailable)
  207. {
  208. // Adjust dlAvailable to leave some space free
  209. if ((DISK_SPACE_MARGIN/dwClusterSize) > dlAvailable)
  210. {
  211. return FALSE;
  212. }
  213. else
  214. {
  215. dlAvailable -= DISK_SPACE_MARGIN/dwClusterSize;
  216. };
  217. // Now, iterate through the cache to discover the actual size.
  218. INTERNET_CACHE_ENTRY_INFOA cei;
  219. DWORD dwSize = sizeof(cei);
  220. DWORDLONG dlClustersNeeded = 0;
  221. BOOL fResult = FALSE;
  222. HANDLE hFind = FindFirstUrlCacheEntryExA(NULL,
  223. FIND_FLAGS_RETRIEVE_ONLY_STRUCT_INFO,
  224. NORMAL_CACHE_ENTRY,
  225. NULL,
  226. &cei,
  227. &dwSize,
  228. NULL,
  229. NULL,
  230. NULL);
  231. if (hFind!=NULL)
  232. {
  233. do
  234. {
  235. ULARGE_INTEGER ulFileSize;
  236. ulFileSize.LowPart = cei.dwSizeLow;
  237. ulFileSize.HighPart = cei.dwSizeHigh;
  238. dlClustersNeeded += (ulFileSize.QuadPart / (DWORDLONG)dwClusterSize) + 1;
  239. fResult = FindNextUrlCacheEntryExA(hFind, &cei, &dwSize, NULL, NULL, NULL) && (dlClustersNeeded < dlAvailable);
  240. }
  241. while (fResult);
  242. FindCloseUrlCache(hFind);
  243. if (GetLastError()==ERROR_NO_MORE_ITEMS)
  244. {
  245. fResult = dlClustersNeeded < dlAvailable;
  246. }
  247. }
  248. else
  249. {
  250. fResult = TRUE;
  251. }
  252. return fResult;
  253. }
  254. //
  255. // SaveTemporarySettings
  256. //
  257. // Save the Temporary Files Dialog (Cache) settings.
  258. //
  259. // History:
  260. //
  261. // 6/14/96 t-gpease created
  262. //
  263. BOOL SaveTemporarySettings(LPTEMPDLG pTmp)
  264. {
  265. if ((pTmp->uiCacheQuota<1) || (pTmp->uiCacheQuota>pTmp->uiDiskSpaceTotal))
  266. {
  267. TCHAR szError[1024], szTemp[100];
  268. MLLoadShellLangString(IDS_SIZE_FORMAT, szTemp, ARRAYSIZE(szTemp));
  269. wnsprintf(szError, ARRAYSIZE(szError), szTemp, pTmp->uiDiskSpaceTotal);
  270. MLLoadShellLangString(IDS_ERROR, szTemp, ARRAYSIZE(szTemp));
  271. MessageBox(pTmp->hDlg, szError, szTemp, MB_OK | MB_ICONEXCLAMATION);
  272. SetFocus(GetDlgItem(pTmp->hDlg, IDC_ADVANCED_CACHE_TEXT_PERCENT));
  273. return FALSE;
  274. }
  275. if (pTmp->bChanged)
  276. {
  277. // derive the syncmode for the radio buttons
  278. if (IsDlgButtonChecked(pTmp->hDlg, IDC_ADVANCED_CACHE_AUTOMATIC))
  279. pTmp->iCacheUpdFrequency = WININET_SYNC_MODE_AUTOMATIC;
  280. else if (IsDlgButtonChecked(pTmp->hDlg, IDC_ADVANCED_CACHE_NEVER))
  281. pTmp->iCacheUpdFrequency = WININET_SYNC_MODE_NEVER;
  282. else if (IsDlgButtonChecked(pTmp->hDlg, IDC_ADVANCED_CACHE_ALWAYS))
  283. pTmp->iCacheUpdFrequency = WININET_SYNC_MODE_ALWAYS;
  284. else {
  285. ASSERT(IsDlgButtonChecked(pTmp->hDlg, IDC_ADVANCED_CACHE_ONCEPERSESS));
  286. pTmp->iCacheUpdFrequency = WININET_SYNC_MODE_ONCE_PER_SESSION;
  287. }
  288. // notify IE
  289. INTERNET_CACHE_CONFIG_INFOA cci;
  290. cci.dwContainer = CONTENT;
  291. cci.dwQuota = pTmp->uiCacheQuota * 1024; // Make into KB
  292. cci.dwSyncMode = pTmp->iCacheUpdFrequency;
  293. ASSERT(cci.dwQuota);
  294. SetUrlCacheConfigInfoA(&cci, CACHE_CONFIG_SYNC_MODE_FC | CACHE_CONFIG_QUOTA_FC);
  295. }
  296. if (pTmp->bChangedLocation)
  297. {
  298. OSVERSIONINFOA VerInfo;
  299. VerInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
  300. GetVersionExA(&VerInfo);
  301. if (g_hwndPropSheet)
  302. {
  303. PropSheet_Apply(g_hwndPropSheet);
  304. }
  305. BOOL fRunningOnNT = (VerInfo.dwPlatformId == VER_PLATFORM_WIN32_NT);
  306. // Well, we're going to have to force a reboot now. Ciao. Confirm.
  307. if (IDYES==DispMessage(pTmp->hDlg,
  308. fRunningOnNT ? IDS_LOGOFF_WARNING : IDS_REBOOTING_WARNING,
  309. fRunningOnNT ? IDS_LOGOFF_TITLE : IDS_REBOOTING_TITLE,
  310. MB_YESNO | MB_ICONEXCLAMATION))
  311. {
  312. // fix registry entries and add RunOnce command
  313. // NOTE: a REBOOT must be done for changes to take effect
  314. // (see SetCacheLocation() ).
  315. // On NT, we must adjust the token privileges
  316. BOOL fSuccess = TRUE;
  317. if (fRunningOnNT)
  318. {
  319. HANDLE hToken;
  320. TOKEN_PRIVILEGES tkp;
  321. // get a token from this process
  322. if (fSuccess=OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
  323. {
  324. // get the LUID for the shutdown privilege
  325. LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid);
  326. tkp.PrivilegeCount = 1;
  327. tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  328. //get the shutdown privilege for this proces
  329. fSuccess = AdjustTokenPrivileges( hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0 );
  330. }
  331. }
  332. if (fSuccess)
  333. {
  334. #ifdef UNICODE //UpdateUrlCacheContentPath takes LPSTR
  335. char szNewPath[MAX_PATH];
  336. SHTCharToAnsi(pTmp->szNewCacheLocation, szNewPath, ARRAYSIZE(szNewPath));
  337. UpdateUrlCacheContentPath(szNewPath);
  338. #else
  339. UpdateUrlCacheContentPath(pTmp->szNewCacheLocation);
  340. #endif
  341. ExitWindowsEx((fRunningOnNT ? EWX_LOGOFF : EWX_REBOOT), 0);
  342. }
  343. else
  344. {
  345. DispMessage(pTmp->hDlg, IDS_ERROR_MOVE_MSG, IDS_ERROR_MOVE_TITLE, MB_OK | MB_ICONEXCLAMATION);
  346. }
  347. }
  348. }
  349. return TRUE;
  350. } // SaveTemporarySettings()
  351. //
  352. // IsValidDirectory()
  353. //
  354. // Checks out the path for mistakes... like just machine names...
  355. // SHBrowseForFolder should NOT just return a machine name... BUG is
  356. // shell code.
  357. //
  358. BOOL IsValidDirectory(LPTSTR szDir)
  359. {
  360. if (szDir)
  361. {
  362. if (!*szDir)
  363. return FALSE; // it's empty... that's not good
  364. if (*szDir!= DIR_SEPARATOR_CHAR)
  365. return TRUE; // not a machine path... then OK
  366. // move forward two chars ( the '\''\')
  367. ++szDir;
  368. ++szDir;
  369. while ((*szDir) && (*szDir!=DIR_SEPARATOR_CHAR))
  370. szDir++;
  371. if (*szDir==DIR_SEPARATOR_CHAR)
  372. return TRUE; // found another '\' so we are happy.
  373. return FALSE; // machine name only... ERROR!
  374. }
  375. return FALSE;
  376. } // IsValidDirecotry()
  377. #define NUM_LEVELS 3 // random dir + cachefile + safety (installed containers)
  378. DWORD g_ccBrandName = 0;
  379. int CALLBACK MoveFolderCallBack(
  380. HWND hwnd,
  381. UINT uMsg,
  382. LPARAM lParam,
  383. LPARAM lpData
  384. )
  385. {
  386. if (uMsg==BFFM_SELCHANGED)
  387. {
  388. TCHAR szNewDest[1024];
  389. TCHAR szStatusText[256];
  390. UINT uErr = 0;
  391. LONG fValid = FALSE;
  392. if (SHGetPathFromIDList((LPCITEMIDLIST)lParam, szNewDest))
  393. {
  394. // Account for "Temporary Internet Files\Content.IE?\randmdir.ext" + NUM_LEVELS*10
  395. DWORD ccAvail = MAX_PATH - g_ccBrandName -1 - ARRAYSIZE("CONTENT.IE?\\") - (NUM_LEVELS*10);
  396. if ((DWORD)lstrlen(szNewDest)>ccAvail) // Win95 limit on how long paths can be
  397. {
  398. uErr = IDS_ERROR_ARCHITECTURE;
  399. }
  400. else if (StrStrI(szNewDest, TEXT("Content.IE")))
  401. {
  402. uErr = IDS_ERROR_WRONG_PLACE;
  403. }
  404. else if (!IsValidDirectory(szNewDest))
  405. {
  406. uErr = IDS_ERROR_INVALID_PATH_MSG;
  407. }
  408. else if (GetFileAttributes(szNewDest) & FILE_ATTRIBUTE_READONLY)
  409. {
  410. uErr = IDS_ERROR_STRANGENESS;
  411. }
  412. else
  413. {
  414. #ifdef UNICODE
  415. CHAR szAnsiPath[MAX_PATH];
  416. BOOL fProblems;
  417. WideCharToMultiByte(CP_ACP, NULL, szNewDest, -1, szAnsiPath, ARRAYSIZE(szAnsiPath),
  418. NULL, &fProblems);
  419. if (fProblems)
  420. {
  421. uErr = IDS_ERROR_INVALID_PATH;
  422. }
  423. else
  424. #endif
  425. {
  426. TCHAR szSystemPath[MAX_PATH+1];
  427. GetSystemDirectory(szSystemPath, MAX_PATH);
  428. if (StrStrI(szNewDest, szSystemPath))
  429. {
  430. uErr = IDC_ERROR_USING_SYSTEM_DIR;
  431. }
  432. else
  433. {
  434. fValid = TRUE;
  435. }
  436. }
  437. }
  438. }
  439. else
  440. {
  441. uErr = IDS_ERROR_STRANGENESS;
  442. }
  443. if (uErr)
  444. {
  445. MLLoadShellLangString(uErr, szStatusText, ARRAYSIZE(szStatusText));
  446. }
  447. else
  448. {
  449. szStatusText[0] = 0;
  450. }
  451. SendMessage(hwnd, BFFM_ENABLEOK, 0, (LPARAM)fValid);
  452. SendMessage(hwnd, BFFM_SETSTATUSTEXT, 0, (LPARAM)szStatusText);
  453. }
  454. return 0;
  455. }
  456. //
  457. // MoveFolder()
  458. //
  459. // Handles the moving of the Temporary Files (Cache) Folder to
  460. // another location. It checks for the existence of the new folder.
  461. // It warns the user that a REBOOT is necessary before changes
  462. // are made.
  463. //
  464. // History:
  465. //
  466. // 6/18/96 t-gpease created.
  467. //
  468. void MoveFolder(LPTEMPDLG pTmp)
  469. {
  470. TCHAR szTemp [1024];
  471. TCHAR szWindowsPath [MAX_PATH+1];
  472. BROWSEINFO biToFolder;
  473. biToFolder.hwndOwner = pTmp->hDlg;
  474. biToFolder.pidlRoot = NULL; // start on the Desktop
  475. biToFolder.pszDisplayName = szWindowsPath; // not used, just making it happy...
  476. TCHAR szBrandName[MAX_PATH];
  477. MLLoadString(IDS_BRAND_NAME, szBrandName, ARRAYSIZE(szBrandName));
  478. g_ccBrandName = lstrlen(szBrandName);
  479. // load the title of the dialog box
  480. MLLoadShellLangString(IDS_SELECT_CACHE, szTemp, ARRAYSIZE(szTemp));
  481. biToFolder.lpszTitle = szTemp;
  482. biToFolder.ulFlags = BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT; // folders... nothing else
  483. biToFolder.lpfn = MoveFolderCallBack; // nothing special
  484. while (1)
  485. {
  486. // start shell dialog
  487. LPITEMIDLIST pidl = SHBrowseForFolder(&biToFolder);
  488. if (pidl) // if everything went OK
  489. {
  490. DWORD dwClusterSize;
  491. DWORDLONG dlAvailable;
  492. DWORD dwError;
  493. // get the choice the user selected
  494. SHGetPathFromIDList(pidl, pTmp->szNewCacheLocation);
  495. SHFree(pidl);
  496. // Resolve local device to UNC if possible
  497. if ((GetDriveType(pTmp->szNewCacheLocation)==DRIVE_REMOTE) && (pTmp->szNewCacheLocation[0]!=DIR_SEPARATOR_CHAR))
  498. {
  499. TCHAR szPath[MAX_PATH];
  500. DWORD dwLen = ARRAYSIZE(szPath);
  501. pTmp->szNewCacheLocation[2] = '\0';
  502. dwError = WNetGetConnection(pTmp->szNewCacheLocation, szPath, &dwLen);
  503. if (dwError!=ERROR_SUCCESS)
  504. {
  505. DispMessage(pTmp->hDlg, IDS_ERROR_CANT_CONNECT, IDS_ERROR_MOVE_TITLE, MB_OK | MB_ICONEXCLAMATION);
  506. continue;
  507. }
  508. memcpy(pTmp->szNewCacheLocation, szPath, dwLen+1);
  509. }
  510. if (!GetDiskInfo(pTmp->szNewCacheLocation, &dwClusterSize, &dlAvailable, NULL))
  511. {
  512. DispMessage(pTmp->hDlg, IDS_ERROR_CANT_CONNECT, IDS_ERROR_MOVE_TITLE, MB_OK | MB_ICONEXCLAMATION);
  513. continue;
  514. }
  515. if (((*pTmp->szNewCacheLocation==*pTmp->szCacheLocation) && (pTmp->szNewCacheLocation[0]!=DIR_SEPARATOR_CHAR))
  516. ||
  517. (IsEnoughDriveSpace(dwClusterSize, dlAvailable)
  518. &&
  519. (GetLastError()==ERROR_NO_MORE_ITEMS)))
  520. {
  521. pTmp->bChangedLocation = TRUE;
  522. }
  523. else
  524. {
  525. DispMessage(pTmp->hDlg, IDS_ERROR_CANT_MOVE_TIF, IDS_ERROR_MOVE_TITLE, MB_OK | MB_ICONEXCLAMATION);
  526. continue;
  527. }
  528. }
  529. break;
  530. }
  531. if (pTmp->bChangedLocation)
  532. {
  533. DWORDLONG cbTotal;
  534. pTmp->uiDiskSpaceTotal = 0;
  535. if (GetDiskInfo(pTmp->szNewCacheLocation, NULL, NULL, &cbTotal))
  536. {
  537. pTmp->uiDiskSpaceTotal = (UINT)(cbTotal / (DWORDLONG)CONSTANT_MEGABYTE);
  538. }
  539. DWORD ccPath = lstrlen(pTmp->szNewCacheLocation);
  540. if (pTmp->szNewCacheLocation[ccPath-1]!=DIR_SEPARATOR_CHAR)
  541. {
  542. pTmp->szNewCacheLocation[ccPath] = DIR_SEPARATOR_CHAR;
  543. ccPath++;
  544. }
  545. memcpy(pTmp->szNewCacheLocation + ccPath, szBrandName, (g_ccBrandName+1)*sizeof(TCHAR));
  546. if (pTmp->uiCacheQuota > pTmp->uiDiskSpaceTotal)
  547. {
  548. pTmp->uiCacheQuota = pTmp->uiDiskSpaceTotal;
  549. SetDlgItemInt(pTmp->hDlg, IDC_ADVANCED_CACHE_TEXT_PERCENT, pTmp->uiCacheQuota, FALSE);
  550. }
  551. SetDlgItemText( pTmp->hDlg, IDC_ADVANCED_CACHE_LOCATION, pTmp->szNewCacheLocation);
  552. // set dialog text
  553. MLLoadString(IDS_STATUS_FOLDER_NEW, szTemp, ARRAYSIZE(szTemp));
  554. SetDlgItemText( pTmp->hDlg, IDC_ADVANCED_CACHE_STATUS, szTemp);
  555. UpdateCacheQuotaInfo(pTmp, FALSE);
  556. AdjustCacheRange(pTmp);
  557. }
  558. } // MoveFolder()
  559. //
  560. // TemporaryInit()
  561. //
  562. // Handles the initialization of Temporary Files Dialog (Cache)
  563. //
  564. // History:
  565. //
  566. // 6/13/96 t-gpease created
  567. //
  568. BOOL TemporaryInit(HWND hDlg)
  569. {
  570. LPTEMPDLG pTmp;
  571. BOOL bAlways, bOnce, bNever, bAuto;
  572. pTmp = (LPTEMPDLG)LocalAlloc(LPTR, sizeof(*pTmp));
  573. if (!pTmp)
  574. {
  575. EndDialog(hDlg, 0);
  576. return FALSE; // no memory?
  577. }
  578. // tell dialog where to get info
  579. SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)pTmp);
  580. // get dialog item handles
  581. pTmp->hDlg = hDlg;
  582. pTmp->hwndTrack = GetDlgItem( hDlg, IDC_ADVANCED_CACHE_PERCENT );
  583. INTERNET_CACHE_CONFIG_INFOA icci;
  584. icci.dwContainer = CONTENT;
  585. if (GetUrlCacheConfigInfoA(&icci, NULL, CACHE_CONFIG_QUOTA_FC
  586. | CACHE_CONFIG_DISK_CACHE_PATHS_FC
  587. | CACHE_CONFIG_SYNC_MODE_FC))
  588. {
  589. SHAnsiToTChar(icci.CachePath, pTmp->szCacheLocation, ARRAYSIZE(pTmp->szCacheLocation));
  590. pTmp->iCachePercent = 0;
  591. pTmp->uiCacheQuota = icci.dwQuota / 1024;
  592. pTmp->iCacheUpdFrequency = (WORD)icci.dwSyncMode;
  593. }
  594. else
  595. {
  596. // GUCCIEx CAN NEVER FAIL.
  597. ASSERT(FALSE);
  598. pTmp->iCacheUpdFrequency = WININET_SYNC_MODE_DEFAULT;
  599. pTmp->iCachePercent = 3; // YUCK, magic number.
  600. pTmp->uiCacheQuota = 0;
  601. }
  602. SetDlgItemInt(pTmp->hDlg, IDC_ADVANCED_CACHE_TEXT_PERCENT, pTmp->uiCacheQuota, FALSE);
  603. // SendDlgItemMessage(pTmp->hDlg, IDC_ADVANCED_CACHE_TEXT_PERCENT, pTmp->uiCacheQuota, FALSE);
  604. SendDlgItemMessage(pTmp->hDlg, IDC_ADVANCED_CACHE_TEXT_PERCENT, EM_SETLIMITTEXT, 6, 0);
  605. // update cache fields
  606. SendMessage( pTmp->hwndTrack, TBM_SETTICFREQ, 5, 0 );
  607. SendMessage( pTmp->hwndTrack, TBM_SETRANGE, FALSE, MAKELONG(0, 100) );
  608. SendMessage( pTmp->hwndTrack, TBM_SETPAGESIZE, 0, 5 );
  609. DWORDLONG cbTotal;
  610. pTmp->uiDiskSpaceTotal = 0;
  611. if (GetDiskInfo(pTmp->szCacheLocation, NULL, NULL, &cbTotal))
  612. {
  613. pTmp->uiDiskSpaceTotal = (UINT)(cbTotal / (DWORDLONG)CONSTANT_MEGABYTE);
  614. }
  615. UpdateCacheQuotaInfo(pTmp, FALSE);
  616. AdjustCacheRange(pTmp);
  617. // set the rest of the dialog's items
  618. TCHAR szBuf[MAX_PATH];
  619. // Is the following line necessary?
  620. ExpandEnvironmentStrings(pTmp->szCacheLocation,szBuf, ARRAYSIZE(szBuf));
  621. // NOTE NOTE NOTE The following code might have to be altered if we start using
  622. // shfolder.dll to gather the location of the cache
  623. // pszEnd = szBuf + 3 because UNCs are "\\x*" and local drives are "C:\*"
  624. // Move to the end of the string, before the traiiling slash. (This is how wininet works.)
  625. PTSTR pszLast = szBuf + lstrlen(szBuf) - 2;
  626. while ((pszLast>=szBuf) && (*pszLast!=DIR_SEPARATOR_CHAR))
  627. {
  628. pszLast--;
  629. }
  630. // The terminator should always be placed between the \Temporary Internet Files and the
  631. // \Content.IE?. This must always be present.
  632. *(pszLast+1) = TEXT('\0');
  633. SetDlgItemText( hDlg, IDC_ADVANCED_CACHE_LOCATION, szBuf );
  634. MLLoadString(IDS_STATUS_FOLDER_CURRENT, szBuf, ARRAYSIZE(szBuf));
  635. SetDlgItemText( hDlg, IDC_ADVANCED_CACHE_STATUS, szBuf );
  636. // activate the correct radio button
  637. bAlways = bOnce = bNever = bAuto = FALSE;
  638. if (pTmp->iCacheUpdFrequency == WININET_SYNC_MODE_AUTOMATIC)
  639. bAuto = TRUE;
  640. else if (pTmp->iCacheUpdFrequency == WININET_SYNC_MODE_NEVER)
  641. bNever = TRUE;
  642. else if (pTmp->iCacheUpdFrequency == WININET_SYNC_MODE_ALWAYS)
  643. bAlways = TRUE;
  644. else
  645. bOnce = TRUE; // if something got messed up... reset to Once Per Session
  646. CheckDlgButton(hDlg, IDC_ADVANCED_CACHE_ALWAYS, bAlways);
  647. CheckDlgButton(hDlg, IDC_ADVANCED_CACHE_ONCEPERSESS, bOnce);
  648. CheckDlgButton(hDlg, IDC_ADVANCED_CACHE_AUTOMATIC, bAuto);
  649. CheckDlgButton(hDlg, IDC_ADVANCED_CACHE_NEVER, bNever);
  650. // nothing has chagned yet...
  651. pTmp->bChanged = pTmp->bChangedLocation = FALSE;
  652. if( g_restrict.fCache )
  653. {
  654. EnableWindow( GetDlgItem(hDlg, IDC_ADVANCED_CACHE_ALWAYS), FALSE );
  655. EnableWindow( GetDlgItem(hDlg, IDC_ADVANCED_CACHE_ONCEPERSESS), FALSE );
  656. EnableWindow( GetDlgItem(hDlg, IDC_ADVANCED_CACHE_AUTOMATIC), FALSE );
  657. EnableWindow( GetDlgItem(hDlg, IDC_ADVANCED_CACHE_NEVER), FALSE );
  658. EnableWindow( GetDlgItem(hDlg, IDC_ADVANCED_CACHE_PERCENT), FALSE );
  659. EnableWindow( GetDlgItem(hDlg, IDC_ADVANCED_CACHE_PERCENT_ACC), FALSE );
  660. EnableWindow( GetDlgItem(hDlg, IDC_ADVANCED_CACHE_TEXT_PERCENT), FALSE );
  661. EnableWindow( GetDlgItem(hDlg, IDC_ADVANCED_CACHE_SIZE_SPIN), FALSE );
  662. EnableWindow( GetDlgItem(hDlg, IDC_ADVANCED_MOVE_CACHE_LOCATION), FALSE );
  663. EnableWindow( GetDlgItem(hDlg, IDC_ADVANCED_CACHE_EMPTY), FALSE );
  664. }
  665. return TRUE; // worked!
  666. }
  667. //
  668. // TemporaryOnCommand()
  669. //
  670. // Handles Temporary Files dialogs WM_COMMAND messages
  671. //
  672. // History:
  673. //
  674. // 6/13/96 t-gpease created
  675. //
  676. void TemporaryOnCommand(LPTEMPDLG pTmp, UINT id, UINT nCmd)
  677. {
  678. switch (id) {
  679. case IDC_ADVANCED_CACHE_TEXT_PERCENT:
  680. case IDC_ADVANCED_CACHE_SIZE_SPIN:
  681. if (pTmp && nCmd == EN_CHANGE)
  682. {
  683. UINT uiVal;
  684. BOOL fSuccess;
  685. uiVal = GetDlgItemInt(pTmp->hDlg, IDC_ADVANCED_CACHE_TEXT_PERCENT, &fSuccess, FALSE);
  686. if (fSuccess)
  687. {
  688. pTmp->uiCacheQuota = uiVal;
  689. UpdateCacheQuotaInfo(pTmp, FALSE);
  690. pTmp->bChanged = TRUE;
  691. }
  692. }
  693. break;
  694. case IDC_ADVANCED_CACHE_ALWAYS:
  695. case IDC_ADVANCED_CACHE_ONCEPERSESS:
  696. case IDC_ADVANCED_CACHE_AUTOMATIC:
  697. case IDC_ADVANCED_CACHE_NEVER:
  698. pTmp->bChanged = TRUE;
  699. break;
  700. case IDOK:
  701. // save it
  702. if (!SaveTemporarySettings(pTmp))
  703. {
  704. break;
  705. }
  706. // Fall through
  707. case IDCANCEL:
  708. EndDialog(pTmp->hDlg, id);
  709. break; // IDCANCEL
  710. case IDC_ADVANCED_CACHE_BROWSE:
  711. InvokeCachevu(pTmp->hDlg);
  712. break;
  713. case IDC_ADVANCED_MOVE_CACHE_LOCATION:
  714. MoveFolder(pTmp);
  715. break; // IDC_ADVANCED_MOVE_CACHE_LOCATION
  716. case IDC_ADVANCED_DOWNLOADED_CONTROLS:
  717. {
  718. TCHAR szPath[MAX_PATH];
  719. #ifdef UNIX
  720. TCHAR szExpPath[MAX_PATH];
  721. #endif
  722. DWORD cb=SIZEOF(szPath);
  723. if (SHGetValue(HKEY_LOCAL_MACHINE, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings"),
  724. TEXT("ActiveXCache"), NULL, szPath, &cb) == ERROR_SUCCESS)
  725. {
  726. SHELLEXECUTEINFO ei;
  727. #ifdef UNIX
  728. int cbExp = ExpandEnvironmentStrings(szPath,szExpPath,MAX_PATH);
  729. #endif
  730. ei.cbSize = sizeof(SHELLEXECUTEINFO);
  731. ei.hwnd = pTmp->hDlg;
  732. ei.lpVerb = NULL;
  733. #ifndef UNIX
  734. ei.lpFile = szPath;
  735. #else
  736. if( cbExp > 0 && cbExp < MAX_PATH )
  737. ei.lpFile = szExpPath;
  738. else
  739. ei.lpFile = szPath;
  740. #endif
  741. ei.lpParameters = NULL;
  742. ei.lpDirectory = NULL;
  743. ei.nShow = SW_SHOWNORMAL;
  744. ei.fMask = 0;
  745. ShellExecuteEx(&ei);
  746. }
  747. break;
  748. }
  749. } // switch
  750. } // TemporaryOnCommand()
  751. //
  752. // TemporaryDlgProc
  753. //
  754. // Take care of "Temporary Files" (Cache)
  755. //
  756. // History:
  757. //
  758. // ??/??/?? God created
  759. // 6/13/96 t-gpease cleaned up code, separated functions, and
  760. // changed it into a Dialog (was property
  761. // sheet).
  762. //
  763. INT_PTR CALLBACK TemporaryDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam,
  764. LPARAM lParam)
  765. {
  766. LPTEMPDLG pTmp = (LPTEMPDLG) GetWindowLongPtr(hDlg, DWLP_USER);
  767. switch (uMsg) {
  768. case WM_INITDIALOG:
  769. return TemporaryInit(hDlg);
  770. case WM_HSCROLL:
  771. pTmp->iCachePercent = (WORD)SendMessage( pTmp->hwndTrack, TBM_GETPOS, 0, 0 );
  772. UpdateCacheQuotaInfo(pTmp, TRUE);
  773. pTmp->bChanged = TRUE;
  774. return TRUE;
  775. case WM_COMMAND:
  776. TemporaryOnCommand(pTmp, LOWORD(wParam), HIWORD(wParam));
  777. return TRUE;
  778. case WM_HELP: // F1
  779. ResWinHelp( (HWND)((LPHELPINFO)lParam)->hItemHandle, IDS_HELPFILE,
  780. HELP_WM_HELP, (DWORD_PTR)(LPSTR)mapIDCsToIDHs);
  781. break;
  782. case WM_CONTEXTMENU: // right mouse click
  783. ResWinHelp( (HWND) wParam, IDS_HELPFILE,
  784. HELP_CONTEXTMENU, (DWORD_PTR)(LPSTR)mapIDCsToIDHs);
  785. break;
  786. case WM_DESTROY:
  787. ASSERT(pTmp);
  788. LocalFree(pTmp);
  789. break;
  790. }
  791. return FALSE;
  792. }
  793. INT_PTR CALLBACK EmptyCacheDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam,
  794. LPARAM lParam)
  795. {
  796. switch (uMsg) {
  797. case WM_COMMAND:
  798. switch (LOWORD(wParam)) {
  799. case IDCANCEL:
  800. EndDialog(hDlg, 0);
  801. break;
  802. case IDOK:
  803. #ifndef UNIX
  804. if (Button_GetCheck(GetDlgItem(hDlg, IDC_DELETE_SUB)))
  805. EndDialog(hDlg, 3);
  806. else
  807. EndDialog(hDlg, 1);
  808. #else
  809. // On Unix we alway return from this dialog with delete channel content
  810. // option set, though we have removed this option from the UI.
  811. EndDialog(hDlg, 3);
  812. #endif
  813. break;
  814. }
  815. return TRUE;
  816. }
  817. return FALSE;
  818. }
  819. INT_PTR CALLBACK EmptyCacheCookiesDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam,
  820. LPARAM lParam)
  821. {
  822. switch (uMsg) {
  823. case WM_COMMAND:
  824. switch (LOWORD(wParam)) {
  825. case IDCANCEL:
  826. EndDialog(hDlg, 0);
  827. break;
  828. case IDOK:
  829. EndDialog(hDlg, 1);
  830. break;
  831. }
  832. return TRUE;
  833. }
  834. return FALSE;
  835. }
  836. BOOL DeleteCacheCookies()
  837. {
  838. BOOL bRetval = TRUE;
  839. DWORD dwEntrySize, dwLastEntrySize;
  840. LPINTERNET_CACHE_ENTRY_INFOA lpCacheEntry;
  841. HANDLE hCacheDir = NULL;
  842. dwEntrySize = dwLastEntrySize = MAX_CACHE_ENTRY_INFO_SIZE;
  843. lpCacheEntry = (LPINTERNET_CACHE_ENTRY_INFOA) new BYTE[dwEntrySize];
  844. if( lpCacheEntry == NULL)
  845. {
  846. bRetval = FALSE;
  847. goto Exit;
  848. }
  849. lpCacheEntry->dwStructSize = dwEntrySize;
  850. Again:
  851. if (!(hCacheDir = FindFirstUrlCacheEntryA("cookie:",lpCacheEntry,&dwEntrySize)))
  852. {
  853. delete [] lpCacheEntry;
  854. switch(GetLastError())
  855. {
  856. case ERROR_NO_MORE_ITEMS:
  857. goto Exit;
  858. case ERROR_INSUFFICIENT_BUFFER:
  859. lpCacheEntry = (LPINTERNET_CACHE_ENTRY_INFOA)
  860. new BYTE[dwEntrySize];
  861. if( lpCacheEntry == NULL)
  862. {
  863. bRetval = FALSE;
  864. goto Exit;
  865. }
  866. lpCacheEntry->dwStructSize = dwLastEntrySize = dwEntrySize;
  867. goto Again;
  868. default:
  869. bRetval = FALSE;
  870. goto Exit;
  871. }
  872. }
  873. do
  874. {
  875. if (lpCacheEntry->CacheEntryType & COOKIE_CACHE_ENTRY)
  876. DeleteUrlCacheEntryA(lpCacheEntry->lpszSourceUrlName);
  877. dwEntrySize = dwLastEntrySize;
  878. Retry:
  879. if (!FindNextUrlCacheEntryA(hCacheDir,lpCacheEntry, &dwEntrySize))
  880. {
  881. delete [] lpCacheEntry;
  882. switch(GetLastError())
  883. {
  884. case ERROR_NO_MORE_ITEMS:
  885. goto Exit;
  886. case ERROR_INSUFFICIENT_BUFFER:
  887. lpCacheEntry = (LPINTERNET_CACHE_ENTRY_INFOA)
  888. new BYTE[dwEntrySize];
  889. if( lpCacheEntry == NULL)
  890. {
  891. bRetval = FALSE;
  892. goto Exit;
  893. }
  894. lpCacheEntry->dwStructSize = dwLastEntrySize = dwEntrySize;
  895. goto Retry;
  896. default:
  897. bRetval = FALSE;
  898. goto Exit;
  899. }
  900. }
  901. }
  902. while (TRUE);
  903. Exit:
  904. if (hCacheDir)
  905. FindCloseUrlCache(hCacheDir);
  906. return bRetval;
  907. }