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.

401 lines
12 KiB

  1. /*****************************************************************************\
  2. FILE: Dialogs.cpp
  3. DESCRIPTION:
  4. This file exists to display dialogs needed during FTP operations.
  5. \*****************************************************************************/
  6. #include "priv.h"
  7. #include <mshtmhst.h>
  8. #include "dialogs.h"
  9. #ifdef ADD_ABOUTBOX
  10. /*****************************************************************************\
  11. FUNCTION: DisplayAboutBox
  12. DESCRIPTION:
  13. The about box is now an HTML dialog. It is sent a ~ (tilde)
  14. delimited BSTR that has, in this order, version number,
  15. person software is licensed to, company software is licensed to, and
  16. whether 40, 56, or 128 bit ie is installed.
  17. \*****************************************************************************/
  18. HRESULT DisplayAboutBox(HWND hWnd)
  19. {
  20. TCHAR szInfo[512];
  21. szInfo[0] = 0;
  22. SHAboutInfo(szInfo, ARRAYSIZE(szInfo)); // from shlwapi
  23. BSTR bstrVal = TCharSysAllocString(szInfo);
  24. if (bstrVal)
  25. {
  26. VARIANT var = {0}; // variant containing version and user info
  27. var.vt = VT_BSTR;
  28. var.bstrVal = bstrVal;
  29. IMoniker *pmk;
  30. if (SUCCEEDED(CreateURLMoniker(NULL, L"res://msieftp.dll/about.htm", &pmk)))
  31. {
  32. ShowHTMLDialog(hWnd, pmk, &var, NULL, NULL);
  33. pmk->Release();
  34. }
  35. SysFreeString(bstrVal);
  36. }
  37. return S_OK;
  38. }
  39. #endif // ADD_ABOUTBOX
  40. // This function exists to see if the FTP version of the Copy To Folder
  41. // feature's target is valid. The shell has "Copy To Folder" in the toolbar
  42. // that accomplishes the copy by using Drag and Drop. FTP has it's own
  43. // version of this feature in the context menu and file menu that doesn't
  44. // use drag and drop. This exists because the type of drag and drop
  45. // that we need (CFSTR_FILECONTENTS) isn't correctly implemented on
  46. // old shells and our implmentation is 3 times faster!!! However,
  47. // we only support file system targets so let's see if this is one
  48. // of those.
  49. BOOL IsValidFTPCopyToFolderTarget(LPCITEMIDLIST pidl)
  50. {
  51. BOOL fAllowed = FALSE;
  52. if (pidl)
  53. {
  54. TCHAR szPath[MAX_PATH];
  55. if (SHGetPathFromIDList((LPITEMIDLIST)pidl, szPath))
  56. {
  57. fAllowed = TRUE;
  58. }
  59. }
  60. return fAllowed;
  61. }
  62. int BrowseCallback(HWND hwnd, UINT msg, LPARAM lParam, LPARAM lpData)
  63. {
  64. int nResult = 0;
  65. switch (msg)
  66. {
  67. case BFFM_INITIALIZED:
  68. if (lpData) // Documentation says it will be NULL but other code does this.
  69. {
  70. // we passed ppidl as lpData so pass on just pidl
  71. // Notice I pass BFFM_SETSELECTIONA which would normally indicate ANSI.
  72. // I do this because Win95 requires it, but it doesn't matter because I'm
  73. // only passing a pidl
  74. SendMessage(hwnd, BFFM_SETSELECTIONA, FALSE, (LPARAM)((LPITEMIDLIST)lpData));
  75. }
  76. break;
  77. // NT #282886: Need to verify if the path is supported. (A:\ with floppy inserted w/o cancel)
  78. // I verified this works shortly after Win2k but we need to test for it in the future.
  79. case BFFM_SELCHANGED:
  80. // We need to make sure that the selected item is valid for us to
  81. // accept. This is because the tree will contain items that don't
  82. // pass the filter (file sys only) because they have non-filtered
  83. // children. We need to disable the OK button when this happens
  84. // to prevent getting
  85. SendMessage(hwnd, BFFM_ENABLEOK, 0, (LPARAM)IsValidFTPCopyToFolderTarget((LPCITEMIDLIST) lParam));
  86. break;
  87. case BFFM_VALIDATEFAILEDA:
  88. AssertMsg(0, TEXT("How can we get this? That's not the structure I sent them."));
  89. break;
  90. case BFFM_VALIDATEFAILEDW:
  91. // If we return zero, then we are saying it's OK. We only want to do this with
  92. // file paths.
  93. nResult = !PathIsRoot((LPCWSTR) lParam);
  94. // Is this invalid?
  95. if (nResult)
  96. {
  97. TCHAR szErrorTitle[MAX_PATH];
  98. TCHAR szErrorMsg[MAX_PATH];
  99. // Yes, so we need to inform the user so they know why the dialog doesn't
  100. // close.
  101. EVAL(LoadString(HINST_THISDLL, IDS_HELP_MSIEFTPTITLE, szErrorTitle, ARRAYSIZE(szErrorTitle)));
  102. EVAL(LoadString(HINST_THISDLL, IDS_FTPERR_BAD_DL_TARGET, szErrorMsg, ARRAYSIZE(szErrorMsg)));
  103. MessageBox(hwnd, szErrorMsg, szErrorTitle, (MB_OK | MB_ICONERROR));
  104. }
  105. break;
  106. }
  107. return nResult;
  108. }
  109. /*****************************************************************************\
  110. FUNCTION: BrowseForDir
  111. DESCRIPTION:
  112. Let the user browser for a directory on the local file system
  113. in order to chose a destination for the FTP transfer.
  114. S_FALSE will be returned if the user cancelled the action.
  115. \*****************************************************************************/
  116. HRESULT BrowseForDir(HWND hwndParent, LPCTSTR pszTitle, LPCITEMIDLIST pidlDefaultSelect, LPITEMIDLIST * ppidlSelected)
  117. {
  118. HRESULT hr = S_OK;
  119. if (ppidlSelected)
  120. {
  121. ASSERT(hwndParent);
  122. BROWSEINFO bi = {0};
  123. bi.hwndOwner = hwndParent;
  124. bi.lpszTitle = pszTitle;
  125. bi.lpfn = BrowseCallback;
  126. bi.lParam = (LPARAM) pidlDefaultSelect;
  127. bi.ulFlags = (BIF_RETURNONLYFSDIRS | BIF_RETURNFSANCESTORS | BIF_EDITBOX | BIF_USENEWUI | BIF_VALIDATE);
  128. *ppidlSelected = SHBrowseForFolder(&bi);
  129. if (!*ppidlSelected)
  130. hr = S_FALSE;
  131. }
  132. return hr;
  133. }
  134. /****************************************************\
  135. FUNCTION: ShowDialog
  136. DESCRIPTION:
  137. \****************************************************/
  138. HRESULT CDownloadDialog::ShowDialog(HWND hwndOwner, LPTSTR pszDir, DWORD cchSize, DWORD * pdwDownloadType)
  139. {
  140. HRESULT hr = S_OK;
  141. if (DialogBoxParam(HINST_THISDLL, MAKEINTRESOURCE(IDD_DOWNLOADDIALOG), hwndOwner, DownloadDialogProc, (LPARAM)this))
  142. {
  143. StrCpyN(pszDir, HANDLE_NULLSTR(m_pszDir), cchSize);
  144. *pdwDownloadType = m_dwDownloadType;
  145. hr = S_OK;
  146. }
  147. else
  148. hr = S_FALSE;
  149. return hr;
  150. }
  151. /****************************************************\
  152. FUNCTION: DownloadDialogProc
  153. DESCRIPTION:
  154. \****************************************************/
  155. INT_PTR CALLBACK CDownloadDialog::DownloadDialogProc(HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam)
  156. {
  157. CDownloadDialog * ppd = (CDownloadDialog *)GetWindowLongPtr(hDlg, GWLP_USERDATA);
  158. if (WM_INITDIALOG == wMsg)
  159. {
  160. SetWindowLongPtr(hDlg, GWLP_USERDATA, lParam);
  161. ppd = (CDownloadDialog *)lParam;
  162. }
  163. if (ppd)
  164. return ppd->_DownloadDialogProc(hDlg, wMsg, wParam, lParam);
  165. return TRUE;
  166. }
  167. /****************************************************\
  168. FUNCTION: _DownloadDialogProc
  169. DESCRIPTION:
  170. \****************************************************/
  171. BOOL CDownloadDialog::_DownloadDialogProc(HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam)
  172. {
  173. switch (wMsg)
  174. {
  175. case WM_INITDIALOG:
  176. return _InitDialog(hDlg);
  177. case WM_COMMAND:
  178. return _OnCommand(hDlg, wParam, lParam);
  179. }
  180. return FALSE;
  181. }
  182. /****************************************************\
  183. FUNCTION: _OnCommand
  184. DESCRIPTION:
  185. \****************************************************/
  186. BOOL CDownloadDialog::_OnCommand(HWND hDlg, WPARAM wParam, LPARAM lParam)
  187. {
  188. UINT idc = GET_WM_COMMAND_ID(wParam, lParam);
  189. switch (idc)
  190. {
  191. case IDC_DOWNLOAD_BUTTON:
  192. if (SUCCEEDED(_DownloadButton(hDlg)))
  193. EndDialog(hDlg, TRUE);
  194. break;
  195. case IDCANCEL:
  196. EndDialog(hDlg, FALSE);
  197. break;
  198. case IDC_BROWSE_BUTTON:
  199. _BrowseButton(hDlg);
  200. break;
  201. default:
  202. return FALSE;
  203. }
  204. return TRUE;
  205. }
  206. /****************************************************\
  207. FUNCTION: _InitDialog
  208. DESCRIPTION:
  209. \****************************************************/
  210. BOOL CDownloadDialog::_InitDialog(HWND hDlg)
  211. {
  212. HRESULT hr;
  213. TCHAR szDir[MAX_PATH] = TEXT("C:\\"); // If all else fails.
  214. DWORD cbSize = sizeof(szDir);
  215. // Set the Directory
  216. if ((ERROR_SUCCESS != SHGetValue(HKEY_CURRENT_USER, SZ_REGKEY_INTERNET_EXPLORER, SZ_REGVALUE_DOWNLOAD_DIR, NULL, szDir, &cbSize)) ||
  217. (!PathFileExists(szDir)))
  218. {
  219. LPITEMIDLIST pidlMyDocuments;
  220. // Create the default dir, which should be "My Documents"
  221. hr = SHGetSpecialFolderLocation(hDlg, CSIDL_PERSONAL, &pidlMyDocuments);
  222. if (SUCCEEDED(hr) && pidlMyDocuments)
  223. {
  224. SHGetPathFromIDList(pidlMyDocuments, szDir);
  225. ILFree(pidlMyDocuments);
  226. }
  227. }
  228. SetWindowText(GetDlgItem(hDlg, IDC_DOWNLOAD_DIR), szDir);
  229. // Set the Download Type
  230. cbSize = sizeof(m_dwDownloadType);
  231. m_dwDownloadType = FTP_TRANSFER_TYPE_UNKNOWN; // Default.
  232. SHGetValue(HKEY_CURRENT_USER, SZ_REGKEY_FTPFOLDER, SZ_REGVALUE_DOWNLOAD_TYPE, NULL, &m_dwDownloadType, &cbSize);
  233. for (UINT idDownloadType = IDS_DL_TYPE_AUTOMATIC; idDownloadType <= IDS_DL_TYPE_BINARY; idDownloadType++)
  234. {
  235. LoadString(HINST_THISDLL, idDownloadType, szDir, ARRAYSIZE(szDir));
  236. SendMessage(GetDlgItem(hDlg, IDC_DOWNLOAD_AS_LIST), CB_ADDSTRING, NULL, (LPARAM) szDir);
  237. }
  238. SendMessage(GetDlgItem(hDlg, IDC_DOWNLOAD_AS_LIST), CB_SETCURSEL, (WPARAM) m_dwDownloadType, 0);
  239. hr = AutoCompleteFileSysInEditbox(GetDlgItem(hDlg, IDC_DOWNLOAD_DIR));
  240. ASSERT(SUCCEEDED(hr));
  241. return FALSE;
  242. }
  243. /****************************************************\
  244. FUNCTION: _DownloadButton
  245. DESCRIPTION:
  246. \****************************************************/
  247. HRESULT CDownloadDialog::_DownloadButton(HWND hDlg)
  248. {
  249. HRESULT hr = S_OK;
  250. TCHAR szDirOriginal[MAX_PATH]; // If all else fails.
  251. TCHAR szDir[MAX_PATH]; // If all else fails.
  252. // Get the Directory
  253. GetWindowText(GetDlgItem(hDlg, IDC_DOWNLOAD_DIR), szDirOriginal, ARRAYSIZE(szDirOriginal));
  254. EVAL(ExpandEnvironmentStrings(szDirOriginal, szDir, ARRAYSIZE(szDir)));
  255. Str_SetPtr(&m_pszDir, szDir);
  256. SHSetValue(HKEY_CURRENT_USER, SZ_REGKEY_INTERNET_EXPLORER, SZ_REGVALUE_DOWNLOAD_DIR, REG_SZ, szDir, ARRAYSIZE(szDir));
  257. // Get the Download Type
  258. m_dwDownloadType = (DWORD)SendMessage(GetDlgItem(hDlg, IDC_DOWNLOAD_AS_LIST), CB_GETCURSEL, 0, 0);
  259. SHSetValue(HKEY_CURRENT_USER, SZ_REGKEY_FTPFOLDER, SZ_REGVALUE_DOWNLOAD_TYPE, REG_DWORD, &m_dwDownloadType, sizeof(m_dwDownloadType));
  260. // Make sure this path is usable
  261. ASSERT(hDlg);
  262. if (S_OK == SHPathPrepareForWriteWrapW(hDlg, NULL, szDir, FO_COPY, SHPPFW_DEFAULT))
  263. {
  264. if (!PathIsRoot(szDir) && !PathFileExists(szDir))
  265. {
  266. TCHAR szErrorTitle[MAX_PATH];
  267. TCHAR szErrorMsg[MAX_PATH];
  268. TCHAR szErrorTemplate[MAX_PATH];
  269. hr = E_FAIL; // Until we get a valid directory, we can't do the download.
  270. EVAL(LoadString(HINST_THISDLL, IDS_HELP_MSIEFTPTITLE, szErrorTitle, ARRAYSIZE(szErrorTitle)));
  271. EVAL(LoadString(HINST_THISDLL, IDS_FTPERR_CREATEDIRPROMPT, szErrorTemplate, ARRAYSIZE(szErrorTemplate)));
  272. wnsprintf(szErrorMsg, ARRAYSIZE(szErrorMsg), szErrorTemplate, szDir);
  273. if (IDYES == MessageBox(hDlg, szErrorMsg, szErrorTitle, (MB_YESNO | MB_ICONQUESTION)))
  274. {
  275. if (CreateDirectory(szDir, NULL))
  276. hr = S_OK;
  277. else
  278. {
  279. EVAL(LoadString(HINST_THISDLL, IDS_FTPERR_CREATEFAILED, szErrorMsg, ARRAYSIZE(szErrorMsg)));
  280. MessageBox(hDlg, szErrorMsg, szErrorTitle, (MB_OK | MB_ICONERROR));
  281. }
  282. }
  283. }
  284. }
  285. return hr;
  286. }
  287. /****************************************************\
  288. FUNCTION: _BrowseButton
  289. DESCRIPTION:
  290. \****************************************************/
  291. void CDownloadDialog::_BrowseButton(HWND hDlg)
  292. {
  293. TCHAR szDefaultDir[MAX_PATH];
  294. TCHAR szTitle[MAX_PATH];
  295. GetWindowText(GetDlgItem(hDlg, IDC_DOWNLOAD_DIR), szDefaultDir, ARRAYSIZE(szDefaultDir));
  296. EVAL(LoadString(HINST_THISDLL, IDS_DLG_DOWNLOAD_TITLE, szTitle, ARRAYSIZE(szTitle)));
  297. if (S_OK == BrowseForDir(hDlg, szTitle, NULL, NULL))
  298. SetWindowText(GetDlgItem(hDlg, IDC_DOWNLOAD_DIR), szDefaultDir);
  299. }
  300. /****************************************************\
  301. Constructor
  302. \****************************************************/
  303. CDownloadDialog::CDownloadDialog()
  304. {
  305. // NOTE: This can go on the stack so it may not be zero inited.
  306. m_pszDir = NULL;
  307. m_hwnd = NULL;
  308. }
  309. /****************************************************\
  310. Destructor
  311. \****************************************************/
  312. CDownloadDialog::~CDownloadDialog()
  313. {
  314. Str_SetPtr(&m_pszDir, NULL);
  315. }