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.

328 lines
9.2 KiB

  1. //=============================================================================
  2. // The CExpandDlg class is designed to give the user a GUI for running the
  3. // EXPAND program.
  4. //=============================================================================
  5. #include "stdafx.h"
  6. #include <atlhost.h>
  7. #include "msconfig.h"
  8. #include "msconfigstate.h"
  9. #include "ExpandDlg.h"
  10. #include <regstr.h>
  11. #ifdef _DEBUG
  12. #define new DEBUG_NEW
  13. #undef THIS_FILE
  14. static char THIS_FILE[] = __FILE__;
  15. #endif
  16. /////////////////////////////////////////////////////////////////////////////
  17. // CExpandDlg dialog
  18. CExpandDlg::CExpandDlg(CWnd* pParent /*=NULL*/) : CDialog(CExpandDlg::IDD, pParent)
  19. {
  20. //{{AFX_DATA_INIT(CExpandDlg)
  21. // NOTE: the ClassWizard will add member initialization here
  22. //}}AFX_DATA_INIT
  23. }
  24. void CExpandDlg::DoDataExchange(CDataExchange* pDX)
  25. {
  26. CDialog::DoDataExchange(pDX);
  27. //{{AFX_DATA_MAP(CExpandDlg)
  28. // NOTE: the ClassWizard will add DDX and DDV calls here
  29. //}}AFX_DATA_MAP
  30. }
  31. BEGIN_MESSAGE_MAP(CExpandDlg, CDialog)
  32. //{{AFX_MSG_MAP(CExpandDlg)
  33. ON_BN_CLICKED(IDC_EXPANDBROWSEFILE, OnBrowseFile)
  34. ON_BN_CLICKED(IDC_EXPANDBROWSEFROM, OnBrowseFrom)
  35. ON_BN_CLICKED(IDC_EXPANDBROWSETO, OnBrowseTo)
  36. //}}AFX_MSG_MAP
  37. END_MESSAGE_MAP()
  38. //-----------------------------------------------------------------------------
  39. // When the dialog box is initializing, we should load the last paths used
  40. // from the registry into the From and To combo boxes.
  41. //-----------------------------------------------------------------------------
  42. BOOL CExpandDlg::OnInitDialog()
  43. {
  44. CDialog::OnInitDialog();
  45. TCHAR szValueName[3];
  46. TCHAR szValue[MAX_PATH];
  47. CRegKey regkey;
  48. DWORD dwCount;
  49. // Add the setup path to the Exand from combo box.
  50. const TCHAR szRegValue[] = REGSTR_VAL_SRCPATH;
  51. const TCHAR szRegPath[] = REGSTR_PATH_SETUP REGSTR_KEY_SETUP;
  52. HKEY hkey;
  53. if (::RegOpenKeyEx(HKEY_LOCAL_MACHINE, szRegPath, 0, KEY_QUERY_VALUE, &hkey) == ERROR_SUCCESS)
  54. {
  55. dwCount = MAX_PATH;
  56. if (::RegQueryValueEx(hkey, szRegValue, NULL, NULL, (LPBYTE)szValue, &dwCount) == ERROR_SUCCESS)
  57. {
  58. m_listFromStrings.AddHead(CString(szValue));
  59. ::SendMessage(GetDlgItem(IDC_COMBOFROM)->m_hWnd, CB_INSERTSTRING, 0, (LPARAM)szValue);
  60. }
  61. RegCloseKey(hkey);
  62. }
  63. // Read the most recently used string for the From and To combo boxes.
  64. regkey.Attach(GetRegKey(_T("ExpandFrom")));
  65. for (int index = 9; index >= 0; index--)
  66. {
  67. _itot(index, szValueName, 10);
  68. dwCount = MAX_PATH;
  69. if (ERROR_SUCCESS == regkey.QueryValue(szValue, szValueName, &dwCount))
  70. {
  71. m_listFromStrings.AddHead(CString(szValue));
  72. ::SendMessage(GetDlgItem(IDC_COMBOFROM)->m_hWnd, CB_INSERTSTRING, 0, (LPARAM)szValue);
  73. }
  74. }
  75. regkey.Detach();
  76. regkey.Attach(GetRegKey(_T("ExpandTo")));
  77. for (index = 9; index >= 0; index--)
  78. {
  79. _itot(index, szValueName, 10);
  80. dwCount = MAX_PATH;
  81. if (ERROR_SUCCESS == regkey.QueryValue(szValue, szValueName, &dwCount))
  82. {
  83. m_listToStrings.AddHead(CString(szValue));
  84. ::SendMessage(GetDlgItem(IDC_COMBOTO)->m_hWnd, CB_INSERTSTRING, 0, (LPARAM)szValue);
  85. }
  86. }
  87. regkey.Detach();
  88. return TRUE; // return TRUE unless you set the focus to a control
  89. }
  90. //-----------------------------------------------------------------------------
  91. // When the user clicks OK, we should take the values from the controls and
  92. // actually perform the EXPAND command:
  93. //
  94. // EXPAND <source-dir>\*.cab -F:<filename> <destination-dir>
  95. //-----------------------------------------------------------------------------
  96. void CExpandDlg::OnOK()
  97. {
  98. CString strSource, strFile, strDestination, strParams;
  99. GetDlgItemText(IDC_EDITFILE, strFile);
  100. GetDlgItemText(IDC_COMBOFROM, strSource);
  101. GetDlgItemText(IDC_COMBOTO, strDestination);
  102. strFile.TrimRight();
  103. strSource.TrimRight();
  104. strDestination.TrimRight();
  105. // If any of the strings are empty, inform the user and don't exit.
  106. if (strFile.IsEmpty() || strSource.IsEmpty() || strDestination.IsEmpty())
  107. {
  108. Message(IDS_EXPANDEMPTYFIELD, m_hWnd);
  109. return;
  110. }
  111. // Validate the strings as much as possible:
  112. //
  113. // strFile - check to see if this looks like a real file name
  114. // strSource - make sure this file exists
  115. // strDestination - make sure this directory exists
  116. if (strFile.FindOneOf(_T("*?\\/")) != -1)
  117. {
  118. Message(IDS_EXPANDBADFILE, m_hWnd);
  119. return;
  120. }
  121. if (!FileExists(strSource))
  122. {
  123. Message(IDS_EXPANDSOURCEDOESNTEXIST, m_hWnd);
  124. return;
  125. }
  126. CString strTemp(strDestination);
  127. strTemp.TrimRight(_T("\\"));
  128. if (strTemp.GetLength() == 2 && strTemp[1] == _T(':'))
  129. {
  130. // The user has just specified a drive. Check to see if the drive letter
  131. // exists.
  132. UINT nType = ::GetDriveType(strTemp);
  133. if (DRIVE_UNKNOWN == nType || DRIVE_NO_ROOT_DIR == nType)
  134. {
  135. Message(IDS_EXPANDDESTDOESNTEXIST, m_hWnd);
  136. return;
  137. }
  138. }
  139. else if (!FileExists(strDestination))
  140. {
  141. Message(IDS_EXPANDDESTDOESNTEXIST, m_hWnd);
  142. return;
  143. }
  144. // Add the strings from the To and From combo boxes to the history lists
  145. // (if they aren't already in them) and write those lists to the registry.
  146. TCHAR szValueName[3];
  147. int index;
  148. if (!strSource.IsEmpty() && NULL == m_listFromStrings.Find(strSource))
  149. {
  150. m_listFromStrings.AddHead(strSource);
  151. CRegKey regkey;
  152. HKEY hkey = GetRegKey(_T("ExpandFrom"));
  153. if (hkey != NULL)
  154. {
  155. regkey.Attach(hkey);
  156. index = 0;
  157. while (!m_listFromStrings.IsEmpty() && index < 10)
  158. {
  159. _itot(index++, szValueName, 10);
  160. regkey.SetValue(m_listFromStrings.RemoveHead(), szValueName);
  161. }
  162. }
  163. }
  164. if (!strDestination.IsEmpty() && NULL == m_listToStrings.Find(strDestination))
  165. {
  166. m_listToStrings.AddHead(strDestination);
  167. CRegKey regkey;
  168. HKEY hkey = GetRegKey(_T("ExpandTo"));
  169. if (hkey != NULL)
  170. {
  171. regkey.Attach(hkey);
  172. index = 0;
  173. while (!m_listToStrings.IsEmpty() && index < 10)
  174. {
  175. _itot(index++, szValueName, 10);
  176. regkey.SetValue(m_listToStrings.RemoveHead(), szValueName);
  177. }
  178. }
  179. }
  180. // If any of the strings contain spaces, it will need quotes around it.
  181. if (strDestination.Find(_T(' ')) != -1)
  182. strDestination = _T("\"") + strDestination + _T("\"");
  183. if (strSource.Find(_T(' ')) != -1)
  184. strSource = _T("\"") + strSource + _T("\"");
  185. if (strFile.Find(_T(' ')) != -1)
  186. strFile = _T("\"") + strFile + _T("\"");
  187. TCHAR szCommand[MAX_PATH];
  188. if (::GetSystemDirectory(szCommand, MAX_PATH))
  189. {
  190. _tcscat(szCommand, _T("\\expand.exe"));
  191. strParams.Format(_T("%s -f:%s %s"), strSource, strFile, strDestination);
  192. ::ShellExecute(NULL, _T("open"), szCommand, strParams, strDestination, SW_HIDE);
  193. // Useful for debugging:
  194. //
  195. // strParams = _T("Executed:\n\n") + CString(szCommand) + _T(" ") + strParams;
  196. // ::AfxMessageBox(strParams);
  197. }
  198. CDialog::OnOK();
  199. }
  200. //-----------------------------------------------------------------------------
  201. // Allow the user to browse for the file to be expanded. Once the file is
  202. // found, put the name of the file in the edit control and the path of the
  203. // file in the To combo box (since the user is likely to want to expand to
  204. // that location).
  205. //-----------------------------------------------------------------------------
  206. void CExpandDlg::OnBrowseFile()
  207. {
  208. CFileDialog dlg(TRUE, NULL, NULL, OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST);
  209. if (IDOK == dlg.DoModal())
  210. {
  211. CString strFile(dlg.GetFileName());
  212. SetDlgItemText(IDC_EDITFILE, strFile);
  213. CString strPath(dlg.GetPathName());
  214. strPath = strPath.Left(strPath.GetLength() - strFile.GetLength());
  215. SetDlgItemText(IDC_COMBOTO, strPath);
  216. }
  217. }
  218. //-----------------------------------------------------------------------------
  219. // This lets the user browse for the CAB file to be used in the expand.
  220. //-----------------------------------------------------------------------------
  221. void CExpandDlg::OnBrowseFrom()
  222. {
  223. CFileDialog dlg(TRUE, NULL, NULL, OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST, _T("*.cab|*.cab||"));
  224. if (IDOK == dlg.DoModal())
  225. SetDlgItemText(IDC_COMBOFROM, dlg.GetPathName());
  226. }
  227. //-----------------------------------------------------------------------------
  228. // This is a general purpose routine to allow the user to pick a folder (since
  229. // there is no common dialog for this, it uses SHBrowseForFolder()).
  230. //-----------------------------------------------------------------------------
  231. BOOL BrowseForFolder(CString & strPath, UINT uiPromptID, HWND hwnd)
  232. {
  233. BOOL fReturn = FALSE;
  234. CString strPrompt(_T(""));
  235. IMalloc * pMalloc;
  236. if (FAILED(::SHGetMalloc(&pMalloc)))
  237. return FALSE;
  238. if (uiPromptID != 0)
  239. strPrompt.LoadString(uiPromptID);
  240. BROWSEINFO bi;
  241. bi.hwndOwner = hwnd;
  242. bi.pidlRoot = NULL;
  243. bi.pszDisplayName = NULL;
  244. bi.lpszTitle = (strPrompt.IsEmpty()) ? NULL : (LPCTSTR)strPrompt;
  245. bi.ulFlags = BIF_RETURNONLYFSDIRS;
  246. bi.lpfn = NULL;
  247. bi.lParam = 0;
  248. LPITEMIDLIST pItemList = ::SHBrowseForFolder(&bi);
  249. if (pItemList != NULL)
  250. {
  251. TCHAR szPath[MAX_PATH];
  252. if (::SHGetPathFromIDList(pItemList, szPath))
  253. {
  254. strPath = szPath;
  255. fReturn = TRUE;
  256. }
  257. pMalloc->Free((void *)pItemList);
  258. }
  259. pMalloc->Release();
  260. return fReturn;
  261. }
  262. //-----------------------------------------------------------------------------
  263. // This button allows the user to select the location for the expanded file.
  264. //-----------------------------------------------------------------------------
  265. void CExpandDlg::OnBrowseTo()
  266. {
  267. CString strPath;
  268. if (BrowseForFolder(strPath, IDS_SELECTTO, m_hWnd))
  269. SetDlgItemText(IDC_COMBOTO, strPath);
  270. }