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.

467 lines
12 KiB

  1. /*++
  2. Copyright (c) 2001 Microsoft Corporation
  3. Module Name :
  4. MappingPage.cpp
  5. Abstract:
  6. App config mapping page implementation
  7. Author:
  8. Sergei Antonov (sergeia)
  9. Project:
  10. Internet Services Manager
  11. Revision History:
  12. --*/
  13. #include "stdafx.h"
  14. #include "MappingPage.h"
  15. enum
  16. {
  17. COL_EXTENSION = 0,
  18. COL_PATH,
  19. COL_EXCLUSIONS
  20. };
  21. #define EXT_WIDTH 58
  22. #define PATH_WIDTH 204
  23. #define EXCLUSIONS_WIDTH 72
  24. LRESULT
  25. CAppMappingPage::OnInitDialog(HWND hDlg, LPARAM lParam)
  26. {
  27. CString str;
  28. CError err;
  29. DoDataExchange();
  30. DWORD dwStyle = m_list.GetExtendedListViewStyle();
  31. m_list.SetExtendedListViewStyle(
  32. dwStyle | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_HEADERDRAGDROP | LVS_EX_LABELTIP);
  33. str.LoadString(_Module.GetResourceInstance(), IDS_EXTENSION);
  34. m_list.InsertColumn(COL_EXTENSION, str, LVCFMT_LEFT, EXT_WIDTH, 0);
  35. str.LoadString(_Module.GetResourceInstance(), IDS_EXECUTABLE_PATH);
  36. m_list.InsertColumn(COL_PATH, str, LVCFMT_LEFT, PATH_WIDTH, 1);
  37. str.LoadString(_Module.GetResourceInstance(), IDS_VERBS);
  38. m_list.InsertColumn(COL_EXCLUSIONS, str, LVCFMT_LEFT, EXCLUSIONS_WIDTH, 2);
  39. ASSERT(m_pData != NULL);
  40. CMappings::iterator it;
  41. int idx = 0;
  42. CString all_verbs;
  43. VERIFY(all_verbs.LoadString(_Module.GetResourceInstance(), IDS_ALL));
  44. for (it = m_pData->m_Mappings.begin(); it != m_pData->m_Mappings.end(); it++, idx++)
  45. {
  46. Mapping map = (*it).second;
  47. VERIFY(-1 != m_list.InsertItem(idx, map.ext));
  48. VERIFY(m_list.SetItemText(idx, COL_PATH, map.path));
  49. VERIFY(m_list.SetItemData(idx, map.flags));
  50. VERIFY(m_list.SetItemText(idx, COL_EXCLUSIONS,
  51. map.verbs.IsEmpty() ? all_verbs : map.verbs));
  52. }
  53. CString remainder;
  54. CMetabasePath::GetRootPath(m_pData->m_MetaPath, str, &remainder);
  55. ::EnableWindow(GetDlgItem(IDC_CACHE_ISAPI), remainder.IsEmpty());
  56. int count = m_list.GetItemCount();
  57. if (count > 0)
  58. {
  59. m_list.SelectItem(0);
  60. }
  61. ::EnableWindow(GetDlgItem(IDC_EDIT), count > 0);
  62. ::EnableWindow(GetDlgItem(IDC_REMOVE), count > 0);
  63. return 0;
  64. }
  65. void
  66. CAppMappingPage::OnAdd(UINT nCode, UINT nID, HWND hWnd)
  67. {
  68. CEditMap dlg;
  69. dlg.m_new = TRUE;
  70. dlg.m_flags = MD_SCRIPTMAPFLAG_SCRIPT | MD_SCRIPTMAPFLAG_CHECK_PATH_INFO;
  71. dlg.m_pData = m_pData;
  72. if (dlg.DoModal() == IDOK)
  73. {
  74. CString all_verbs;
  75. VERIFY(all_verbs.LoadString(_Module.GetResourceInstance(), IDS_ALL));
  76. Mapping map;
  77. map.ext = dlg.m_ext;
  78. map.path = dlg.m_exec;
  79. map.verbs = dlg.m_verbs;
  80. map.flags = dlg.m_flags;
  81. m_pData->m_Mappings.insert(CMappings::value_type(map.ext, map));
  82. int count = m_list.GetItemCount();
  83. VERIFY(-1 != m_list.InsertItem(count, map.ext));
  84. VERIFY(m_list.SetItemText(count, COL_PATH, dlg.m_exec));
  85. VERIFY(m_list.SetItemData(count, dlg.m_flags));
  86. VERIFY(m_list.SetItemText(count, COL_EXCLUSIONS,
  87. dlg.m_verbs[0] == 0 ? all_verbs : dlg.m_verbs));
  88. m_list.SelectItem(count);
  89. SET_MODIFIED(TRUE);
  90. ::EnableWindow(GetDlgItem(IDC_REMOVE), TRUE);
  91. ::EnableWindow(GetDlgItem(IDC_EDIT), TRUE);
  92. }
  93. }
  94. void
  95. CAppMappingPage::OnEdit(UINT nCode, UINT nID, HWND hWnd)
  96. {
  97. int idx = m_list.GetSelectedIndex();
  98. if (idx != -1)
  99. {
  100. CEditMap dlg;
  101. dlg.m_new = FALSE;
  102. dlg.m_pData = m_pData;
  103. TCHAR buf[MAX_PATH];
  104. VERIFY(0 != m_list.GetItemText(idx, 0, buf, MAX_PATH));
  105. CMappings::iterator it = m_pData->m_Mappings.find(buf);
  106. ASSERT(it != m_pData->m_Mappings.end());
  107. StrCpyN(dlg.m_ext, buf, MAX_PATH);
  108. StrCpyN(dlg.m_exec, (*it).second.path, MAX_PATH);
  109. StrCpyN(dlg.m_verbs, (*it).second.verbs, MAX_PATH);
  110. dlg.m_flags = (*it).second.flags;
  111. if (dlg.DoModal() == IDOK)
  112. {
  113. CString all_verbs;
  114. VERIFY(all_verbs.LoadString(_Module.GetResourceInstance(), IDS_ALL));
  115. (*it).second.path = dlg.m_exec;
  116. (*it).second.verbs = dlg.m_verbs;
  117. (*it).second.flags = dlg.m_flags;
  118. VERIFY(m_list.SetItemText(idx, COL_PATH, dlg.m_exec));
  119. VERIFY(m_list.SetItemData(idx, dlg.m_flags));
  120. VERIFY(m_list.SetItemText(idx, COL_EXCLUSIONS,
  121. dlg.m_verbs[0] == 0 ? all_verbs : dlg.m_verbs));
  122. SET_MODIFIED(TRUE);
  123. }
  124. }
  125. }
  126. void
  127. CAppMappingPage::OnRemove(UINT nCode, UINT nID, HWND hWnd)
  128. {
  129. int idx = m_list.GetSelectedIndex();
  130. if (idx != LB_ERR)
  131. {
  132. CString msg, caption;
  133. msg.LoadString(_Module.GetResourceInstance(), IDS_CONFIRM_REMOVE_MAP);
  134. caption.LoadString(_Module.GetResourceInstance(), IDS_SHEET_TITLE);
  135. if (MessageBox(msg, caption, MB_ICONQUESTION|MB_YESNO) == IDYES)
  136. {
  137. int i = m_list.GetSelectedIndex();
  138. int count;
  139. TCHAR buf[MAX_PATH];
  140. VERIFY(0 != m_list.GetItemText(i, 0, buf, MAX_PATH));
  141. m_pData->m_Mappings.erase(buf);
  142. m_list.DeleteItem(i);
  143. SET_MODIFIED(TRUE);
  144. if ((count = m_list.GetItemCount()) > 0)
  145. {
  146. if (i >= count)
  147. i = count - 1;
  148. m_list.SelectItem(i);
  149. }
  150. else
  151. {
  152. ::EnableWindow(GetDlgItem(IDC_REMOVE), FALSE);
  153. ::EnableWindow(GetDlgItem(IDC_EDIT), FALSE);
  154. ::SetFocus(GetDlgItem(IDC_ADD));
  155. }
  156. }
  157. }
  158. }
  159. void
  160. CAppMappingPage::OnCacheISAPI(UINT nCode, UINT nID, HWND hWnd)
  161. {
  162. SET_MODIFIED(TRUE);
  163. }
  164. BOOL
  165. CAppMappingPage::OnKillActive()
  166. {
  167. DoDataExchange(TRUE);
  168. return SUCCEEDED(m_pData->Save());
  169. }
  170. LRESULT
  171. CAppMappingPage::OnDblClickList(LPNMHDR pHdr)
  172. {
  173. OnEdit(BN_CLICKED, pHdr->idFrom, pHdr->hwndFrom);
  174. return TRUE;
  175. }
  176. void
  177. CAppMappingPage::OnHelp()
  178. {
  179. WinHelp(m_pData->m_HelpPath, HELP_CONTEXT, CAppMappingPage::IDD + WINHELP_NUMBER_BASE);
  180. }
  181. //---------------- CEditMap dialog --------------------------
  182. #define CHECK_VERBS()\
  183. m_bVerbsValid = \
  184. (m_verbs_index > 0 && lstrlen(m_verbs) != 0) || (m_verbs_index == 0)
  185. _inline BOOL CheckExt(LPCTSTR ext)
  186. {
  187. return (ext[0] != 0) && (ext[0] == _T('.'));
  188. }
  189. #define CHECK_EXT()\
  190. m_bExtValid = CheckExt(m_ext)
  191. _inline BOOL ExecValid(LPCTSTR exec)
  192. {
  193. return lstrlen(exec) != 0 && !PathIsUNC(exec);
  194. }
  195. #define CHECK_EXEC(buf)\
  196. m_bExecValid = ExecValid(buf)
  197. #define ENABLE_OK()\
  198. ::EnableWindow(GetDlgItem(IDOK), m_bExtValid && m_bExecValid && m_bVerbsValid)
  199. #define TYPE_BIT_SET(t,b)\
  200. ((t)&(b)) != 0
  201. LRESULT
  202. CEditMap::OnInitDialog(HWND hDlg, LPARAM lParam)
  203. {
  204. if (!m_new && m_ext[0] != 0)
  205. {
  206. if (m_ext[0] == _T('*') && m_ext[1] == 0)
  207. {
  208. m_prev_ext[0] = _T('.');
  209. m_prev_ext[1] = _T('*');
  210. m_prev_ext[2] = 0;
  211. StrCpy(m_ext, m_prev_ext);
  212. }
  213. else
  214. {
  215. StrCpyN(m_prev_ext, m_ext, sizeof(m_ext) - 1);
  216. }
  217. }
  218. DWORD style = FC_COMMANDLINE;
  219. if (m_pData->IsLocal())
  220. {
  221. style |= FC_PATH_CHECK|FC_DEFAULT_READ|FC_AUTOCOMPLETION;
  222. }
  223. ::EnableWindow(GetDlgItem(IDC_BROWSE), m_pData->IsLocal());
  224. m_FileChooser.Init(this, style, IDC_EXECUTABLE, IDC_BROWSE);
  225. m_FileChooser.AddExtension(_Module.GetResourceInstance(),
  226. IDS_EXECUTABLE_FILES, IDS_EXECUTABLE_EXT);
  227. m_FileChooser.AddExtension(_Module.GetResourceInstance(),
  228. IDS_DLL_FILES, IDS_DLL_EXT);
  229. m_FileChooser.AddExtension(_Module.GetResourceInstance(),
  230. IDS_ALL_FILES, IDS_ALL_EXT);
  231. m_FileChooser.SetPath(m_exec);
  232. m_verbs_index = lstrlen(m_verbs) == 0 ? 0 : 1;
  233. ::EnableWindow(GetDlgItem(IDC_VERBS), m_verbs_index > 0);
  234. m_script_engine = ((m_flags & MD_SCRIPTMAPFLAG_SCRIPT) != 0);
  235. m_file_exists = ((m_flags & MD_SCRIPTMAPFLAG_CHECK_PATH_INFO) != 0);
  236. ::EnableWindow(GetDlgItem(IDC_EXTENSION), m_new);
  237. CHECK_EXT();
  238. CHECK_EXEC(m_exec);
  239. CHECK_VERBS();
  240. ENABLE_OK();
  241. DoDataExchange();
  242. return FALSE;
  243. }
  244. void
  245. CEditMap::OnVerbs(UINT nCode, UINT nID, HWND hWnd)
  246. {
  247. DoDataExchange(TRUE);
  248. ::EnableWindow(GetDlgItem(IDC_VERBS), m_verbs_index > 0);
  249. CHECK_VERBS();
  250. ENABLE_OK();
  251. }
  252. void
  253. CEditMap::OnVerbsChanged(UINT nCode, UINT nID, HWND hWnd)
  254. {
  255. DoDataExchange(TRUE, IDC_VERBS);
  256. CHECK_VERBS();
  257. ENABLE_OK();
  258. }
  259. void
  260. CEditMap::OnHelp(UINT nCode, UINT nID, HWND hWnd)
  261. {
  262. WinHelp(m_pData->m_HelpPath, HELP_CONTEXT, CEditMap::IDD + WINHELP_NUMBER_BASE);
  263. }
  264. #define BAIL_WITH_MESSAGE(msg, focus)\
  265. idmsg = msg;\
  266. idfocus = focus;\
  267. break
  268. void
  269. CEditMap::OnOK(UINT nCode, UINT nID, HWND hWnd)
  270. {
  271. UINT idmsg = 0, idfocus = 0;
  272. DoDataExchange(TRUE);
  273. // When All is selected, verbs string is empty
  274. do
  275. {
  276. if (m_verbs_index == 0)
  277. {
  278. m_verbs[0] = 0;
  279. }
  280. else if (m_verbs[0] == 0)
  281. {
  282. BAIL_WITH_MESSAGE(IDS_ERR_NOVERBS, IDC_VERBS);
  283. }
  284. CString ext = m_ext;
  285. if (ext.ReverseFind(_T('.')) > 0)
  286. {
  287. BAIL_WITH_MESSAGE(IDS_ERR_BADEXT, IDC_EXTENSION);
  288. }
  289. // Ext should be unique, if new or changed
  290. if ( (m_new || StrCmpI(m_prev_ext, ext) != 0)
  291. && m_pData->m_Mappings.find(ext) != m_pData->m_Mappings.end()
  292. )
  293. {
  294. BAIL_WITH_MESSAGE(IDS_ERR_USEDEXT, IDC_EXTENSION);
  295. }
  296. if (ext.GetAt(0) == _T('*'))
  297. ext.erase(1);
  298. else if (ext.Compare(_T(".*")) == 0)
  299. ext = _T("*");
  300. else if (ext.GetAt(0) != _T('.'))
  301. ext = _T('.') + ext;
  302. StrCpyN(m_ext, ext, sizeof(m_ext)-1);
  303. CString buf;
  304. if (FC_SUCCESS != m_FileChooser.GetFileName(buf))
  305. {
  306. BAIL_WITH_MESSAGE(IDS_ERR_BADEXECFORMAT, IDC_EXECUTABLE);
  307. }
  308. int pos;
  309. CString path;
  310. if (buf[0] == _T('\"'))
  311. {
  312. if ((pos = buf.find_last_of(_T('\"'))) != CString::npos)
  313. {
  314. path = buf.substr(1, pos);
  315. }
  316. else
  317. {
  318. BAIL_WITH_MESSAGE(IDS_ERR_BADEXECFORMAT, IDC_EXECUTABLE);
  319. }
  320. }
  321. else if (CString::npos != (pos = buf.find(_T(' '))))
  322. {
  323. // in case there are parameters after the file name, just take it to the first space
  324. path = buf.substr(0, --pos);
  325. }
  326. if (PathIsUNC(path))
  327. {
  328. BAIL_WITH_MESSAGE(IDS_ERR_NOUNC, IDC_EXECUTABLE);
  329. }
  330. // perform extra local-machine tests
  331. if (m_pData->IsLocal())
  332. {
  333. // if local, the drive can't be redirected
  334. // test the drive and only accept valid, non-remote drives
  335. if (PathIsNetworkPath(path))
  336. {
  337. BAIL_WITH_MESSAGE(IDS_ERR_NOREMOTE, IDC_EXECUTABLE);
  338. }
  339. // check that the file exists
  340. if (PathIsDirectory(path))
  341. {
  342. BAIL_WITH_MESSAGE(IDS_ERR_FILENOTEXISTS, IDC_EXECUTABLE);
  343. }
  344. }
  345. m_flags = 0;
  346. if (m_script_engine)
  347. m_flags |= MD_SCRIPTMAPFLAG_SCRIPT;
  348. if (m_file_exists)
  349. m_flags |= MD_SCRIPTMAPFLAG_CHECK_PATH_INFO;
  350. StrCpy(m_exec, buf);
  351. }
  352. while (FALSE);
  353. if (idmsg != 0)
  354. {
  355. CString msg;
  356. CString cap;
  357. msg.LoadString(_Module.GetResourceInstance(), idmsg);
  358. cap.LoadString(_Module.GetResourceInstance(), IDS_SHEET_TITLE);
  359. MessageBox(msg, cap);
  360. ::SetFocus(GetDlgItem(idfocus));
  361. SendDlgItemMessage(idfocus, EM_SETSEL, 0, -1);
  362. return;
  363. }
  364. EndDialog(nID);
  365. }
  366. void
  367. CEditMap::OnCancel(UINT nCode, UINT nID, HWND hWnd)
  368. {
  369. EndDialog(nID);
  370. }
  371. void
  372. CEditMap::OnExtChanged(UINT nCode, UINT nID, HWND hWnd)
  373. {
  374. DoDataExchange(TRUE, IDC_EXTENSION);
  375. CHECK_EXT();
  376. if (m_bExtValid)
  377. {
  378. int l = lstrlen(m_ext);
  379. int i = 0;
  380. while (i < l)
  381. {
  382. TCHAR c = m_ext[i];
  383. UINT type = PathGetCharType(c);
  384. if ( TYPE_BIT_SET(type, GCT_INVALID)
  385. // || TYPE_BIT_SET(type, GCT_WILD)
  386. || TYPE_BIT_SET(type, GCT_SEPARATOR)
  387. || (TYPE_BIT_SET(type, GCT_LFNCHAR) && !TYPE_BIT_SET(type, GCT_SHORTCHAR))
  388. || c == _T('/') || c == _T('<') || c == _T('|') || c == _T('>') || c == _T('?')
  389. )
  390. {
  391. m_bExtValid = FALSE;
  392. break;
  393. }
  394. i++;
  395. }
  396. if (!m_bExtValid)
  397. {
  398. SendDlgItemMessage(IDC_EXTENSION, EM_SETSEL, i, l);
  399. }
  400. }
  401. ENABLE_OK();
  402. }
  403. void
  404. CEditMap::OnExecChanged(UINT nCode, UINT nID, HWND hWnd)
  405. {
  406. m_FileChooser.OnEditChange();
  407. CString str;
  408. if (FC_SUCCESS == m_FileChooser.GetFileName(str))
  409. {
  410. TCHAR buff[MAX_PATH];
  411. StrCpyN(buff, str, MAX_PATH - 1);
  412. PathRemoveArgs(buff);
  413. CHECK_EXEC(buff);
  414. ENABLE_OK();
  415. }
  416. }