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.

373 lines
11 KiB

  1. // EdDir.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "EdDir.h"
  5. #include "mbobjs.h"
  6. #include "resource.h"
  7. #include <shlobj.h>
  8. #ifdef _DEBUG
  9. #define new DEBUG_NEW
  10. #undef THIS_FILE
  11. static char THIS_FILE[] = __FILE__;
  12. #endif
  13. /////////////////////////////////////////////////////////////////////////////
  14. // CEditDirectory dialog
  15. CEditDirectory::CEditDirectory(CWnd* pParent /*=NULL*/)
  16. : CDialog(CEditDirectory::IDD, pParent),
  17. m_fHome( FALSE ),
  18. m_fNewItem( FALSE ),
  19. m_idsTitle( 0 )
  20. {
  21. //{{AFX_DATA_INIT(CEditDirectory)
  22. m_sz_alias = _T("");
  23. m_sz_path = _T("");
  24. m_bool_read = FALSE;
  25. m_bool_source = FALSE;
  26. m_bool_write = FALSE;
  27. m_int_AppPerms = -1;
  28. //}}AFX_DATA_INIT
  29. m_cedit_path.LoadIllegalChars( IDS_ILLEGAL_PHYS_PATH_CHARS );
  30. m_cedit_alias.LoadIllegalChars( IDS_ILLEGAL_VIRT_DIR_CHARS );
  31. }
  32. void CEditDirectory::DoDataExchange(CDataExchange* pDX)
  33. {
  34. CDialog::DoDataExchange(pDX);
  35. //{{AFX_DATA_MAP(CEditDirectory)
  36. DDX_Control(pDX, IDC_SOURCE, m_cbtn_source);
  37. DDX_Control(pDX, IDC_PATH, m_cedit_path);
  38. DDX_Control(pDX, IDC_ALIAS, m_cedit_alias);
  39. DDX_Text(pDX, IDC_ALIAS, m_sz_alias);
  40. DDX_Text(pDX, IDC_PATH, m_sz_path);
  41. DDX_Check(pDX, IDC_READ, m_bool_read);
  42. DDX_Check(pDX, IDC_SOURCE, m_bool_source);
  43. DDX_Check(pDX, IDC_WRITE, m_bool_write);
  44. DDX_Radio(pDX, IDC_RDO_NONE, m_int_AppPerms);
  45. //}}AFX_DATA_MAP
  46. }
  47. BEGIN_MESSAGE_MAP(CEditDirectory, CDialog)
  48. ON_WM_CONTEXTMENU()
  49. //{{AFX_MSG_MAP(CEditDirectory)
  50. ON_BN_CLICKED(IDC_BROWSE, OnBrowse)
  51. ON_BN_CLICKED(IDC_READ, OnRead)
  52. ON_BN_CLICKED(IDC_SOURCE, OnSource)
  53. ON_BN_CLICKED(IDC_WRITE, OnWrite)
  54. //}}AFX_MSG_MAP
  55. END_MESSAGE_MAP()
  56. //----------------------------------------------------------------
  57. BOOL CEditDirectory::OnInitDialog()
  58. {
  59. // call the parental oninitdialog
  60. BOOL f = CDialog::OnInitDialog();
  61. // if there is a requested title for the dialog, use it
  62. if ( m_idsTitle )
  63. {
  64. CString szTitle;
  65. szTitle.LoadString( m_idsTitle );
  66. SetWindowText( szTitle );
  67. }
  68. // if this is the root directory, disable editing of the alias
  69. if ( m_fHome )
  70. m_cedit_alias.EnableWindow( FALSE );
  71. // keep a copy of the original alias for later verification
  72. m_szOrigAlias = m_sz_alias;
  73. m_bOldSourceControl = m_bool_source;
  74. EnableSourceControl();
  75. // return the answer
  76. return f;
  77. }
  78. /////////////////////////////////////////////////////////////////////////////
  79. // CEditDirectory message handlers
  80. //----------------------------------------------------------------
  81. void CEditDirectory::OnBrowse()
  82. {
  83. UpdateData( TRUE );
  84. BROWSEINFO bi;
  85. LPTSTR lpBuffer;
  86. LPITEMIDLIST pidlBrowse; // PIDL selected by user
  87. // Allocate a buffer to receive browse information.
  88. lpBuffer = (LPTSTR) GlobalAlloc( GPTR, (MAX_PATH + 1) * sizeof(TCHAR) );
  89. if ( !lpBuffer )
  90. {
  91. return;
  92. }
  93. // load the title
  94. CString szTitle;
  95. szTitle.LoadString( IDS_CHOOSE_DIR );
  96. // Fill in the BROWSEINFO structure.
  97. bi.hwndOwner = this->m_hWnd;
  98. bi.pidlRoot = NULL;
  99. bi.pszDisplayName = lpBuffer;
  100. bi.lpszTitle = szTitle;
  101. bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_RETURNFSANCESTORS | BIF_DONTGOBELOWDOMAIN;
  102. bi.lpfn = NULL;
  103. bi.lParam = 0;
  104. // Browse for a folder and return its PIDL.
  105. pidlBrowse = SHBrowseForFolder(&bi);
  106. if (pidlBrowse != NULL)
  107. {
  108. // Show the display name, title, and file system path.
  109. if (SHGetPathFromIDList(pidlBrowse, lpBuffer))
  110. {
  111. m_sz_path = lpBuffer;
  112. }
  113. // Free the PIDL returned by SHBrowseForFolder.
  114. GlobalFree(pidlBrowse);
  115. // put the string back
  116. UpdateData( FALSE );
  117. }
  118. // Clean up.
  119. GlobalFree( lpBuffer );
  120. }
  121. //----------------------------------------------------------------
  122. // we now have to test the physical path that the alias points to
  123. // 1) it must be a valid path. This prevents dumb users from entering
  124. // a garbage path. 2) it can't be a redirected hard drive. 3) (I may not
  125. // get to this part now) it would be nice if it is on a local hard drive
  126. // but doesn't exist that the user be asked if they want to create
  127. // the directory. If they say yes, create it.
  128. BOOL CEditDirectory::VerifyDirectoryPath( CString szPath )
  129. {
  130. CString sz;
  131. DWORD attrib;
  132. // first we test the drive to see if it is local or remote
  133. // but before that we need to get the drive letter
  134. _tsplitpath( (LPCTSTR)szPath, sz.GetBuffer(_MAX_DRIVE+1), NULL, NULL, NULL );
  135. sz.ReleaseBuffer();
  136. // it can't be a unc path
  137. if ( sz.IsEmpty() )
  138. {
  139. AfxMessageBox( IDS_ERR_USE_VALID_DRIVE );
  140. return FALSE;
  141. }
  142. // test the drive and only accept valid, non-remote drives
  143. attrib = GetDriveType( (LPCTSTR)sz );
  144. if ( (attrib == DRIVE_REMOTE) )
  145. {
  146. AfxMessageBox( IDS_ERR_USE_VALID_DRIVE );
  147. return FALSE;
  148. }
  149. // now that we know it is a valid drive, get the attributes of the file
  150. attrib = GetFileAttributes( szPath );
  151. // if the directory doesn't exists
  152. if ( attrib == 0xffffffff )
  153. {
  154. CString szMessage;
  155. AfxFormatString1( szMessage, IDS_MAKE_DIRECTORY, szPath );
  156. if ( AfxMessageBox( szMessage, MB_YESNO ) == IDNO )
  157. return FALSE;
  158. // create the directory
  159. if ( !CreateDirectory((LPCTSTR)szPath, NULL) )
  160. {
  161. AfxMessageBox( IDS_ERR_MAKE_DIRECTORY );
  162. return FALSE;
  163. }
  164. // reget the attibutes for the final check below
  165. attrib = GetFileAttributes( szPath );
  166. }
  167. // if the use chose a file, or something not a directory, tell them no.
  168. if ( (attrib == 0xffffffff) || ((attrib & FILE_ATTRIBUTE_DIRECTORY) == 0) )
  169. {
  170. AfxMessageBox( IDS_ERR_USE_VALID_DIR );
  171. return FALSE;
  172. }
  173. // it is OK
  174. return TRUE;
  175. }
  176. //----------------------------------------------------------------
  177. // we need to make sure that there is something in the alias field
  178. // an empty alias is not OK
  179. void CEditDirectory::OnOK()
  180. {
  181. UpdateData( TRUE );
  182. // if write and script or execute is set, it creates a potential security hole.
  183. // warn the user of this situation before continuing
  184. if ( m_bool_write && ((m_int_AppPerms==APPPERM_SCRIPTS)||(m_int_AppPerms==APPPERM_EXECUTE)) )
  185. {
  186. if ( AfxMessageBox( IDS_WRITEEXECUTE_WARNING, MB_YESNO | MB_ICONEXCLAMATION ) != IDYES )
  187. return;
  188. }
  189. // trim leading and trailing spaces
  190. m_sz_alias.TrimLeft();
  191. m_sz_alias.TrimRight();
  192. m_sz_path.TrimLeft();
  193. m_sz_path.TrimRight();
  194. // first test is to see if there is anything in the alias
  195. if ( m_sz_alias.IsEmpty() )
  196. {
  197. AfxMessageBox( IDS_EMPTY_ALIAS );
  198. return;
  199. }
  200. // we now have to test the physical path that the alias points to
  201. // 1) it must be a valid path. This prevents dumb users from entering
  202. // a garbage path. 2) it can't be a redirected hard drive. 3) (I may not
  203. // get to this part now) it would be nice if it is on a local hard drive
  204. // but doesn't exist that the user be asked if they want to create
  205. // the directory. If they say yes, create it.
  206. // VerifyDirectoryPath takes care of any error messages
  207. if ( !VerifyDirectoryPath(m_sz_path) )
  208. return;
  209. // Now we need to make sure that alias isn't already taken
  210. CString szTestPath = SZ_MB_ROOT;
  211. szTestPath += m_szMetaPath.Left( m_szMetaPath.ReverseFind('/') + 1 );
  212. szTestPath += m_sz_alias;
  213. // if we can open the metabase object, then it is already taken
  214. // create the metabase wrapper
  215. CWrapMetaBase mb;
  216. if ( !mb.FInit() )
  217. return;
  218. // try to open the object
  219. // however, if it is not a new object, and the alias has not changed, do not
  220. // see if the object is there becuase we know that it is and it is ok in this case
  221. // use a case insensitive compare because thats what the metabase uses
  222. if ( m_sz_alias.CompareNoCase(m_szOrigAlias) || m_fNewItem )
  223. {
  224. if ( mb.Open(szTestPath) )
  225. {
  226. // we did open it! Close it right away
  227. mb.Close();
  228. // tell the user to pick another name
  229. CString szMessage;
  230. AfxFormatString1( szMessage, IDS_ALIAS_IS_TAKEN, m_sz_alias );
  231. AfxMessageBox( szMessage );
  232. return;
  233. }
  234. }
  235. // make sure the string goes back
  236. UpdateData( FALSE );
  237. // do the default...
  238. CDialog::OnOK();
  239. }
  240. //----------------------------------------------------------------
  241. void CEditDirectory::WinHelp(DWORD dwData, UINT nCmd)
  242. {
  243. CDialog::WinHelp(dwData, nCmd);
  244. }
  245. /////////////////////////////////////////////////////////////////////////////
  246. //----------------------------------------------------------------
  247. void CEditDirectory::EnableSourceControl()
  248. {
  249. // get the currect button values
  250. UpdateData( TRUE );
  251. // if both read and write are unchecked, then we clear and disable source control
  252. if ( !m_bool_read && !m_bool_write )
  253. {
  254. // save the value of source control
  255. m_bOldSourceControl = m_bool_source;
  256. // clear the source control
  257. m_bool_source = FALSE;
  258. UpdateData( FALSE );
  259. // disable the source control window
  260. m_cbtn_source.EnableWindow( FALSE );
  261. }
  262. else
  263. {
  264. // we enable source control
  265. // disable the source control window
  266. m_cbtn_source.EnableWindow( TRUE );
  267. // and set the value back
  268. m_bool_source = m_bOldSourceControl;
  269. UpdateData( FALSE );
  270. }
  271. }
  272. //----------------------------------------------------------------
  273. void CEditDirectory::OnSource()
  274. {
  275. // get the currect button values
  276. UpdateData( TRUE );
  277. // save the value of source control
  278. m_bOldSourceControl = m_bool_source;
  279. }
  280. //----------------------------------------------------------------
  281. void CEditDirectory::OnRead()
  282. {
  283. EnableSourceControl();
  284. }
  285. //----------------------------------------------------------------
  286. void CEditDirectory::OnWrite()
  287. {
  288. EnableSourceControl();
  289. }
  290. /////////////////////////////////////////////////////////////////////////////
  291. //----------------------------------------------------------------
  292. void CVDEdit::LoadIllegalChars( int idChars )
  293. {
  294. szExclude.LoadString( idChars );
  295. }
  296. //----------------------------------------------------------------
  297. BOOL CVDEdit::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult)
  298. {
  299. // if it is a character
  300. if ( message == WM_CHAR )
  301. {
  302. TCHAR chCharCode = (TCHAR)wParam;
  303. // test for bad or control characters
  304. if (_tcschr(szExclude, chCharCode))
  305. {
  306. MessageBeep(0);
  307. return 1;
  308. }
  309. }
  310. // return the default answer
  311. return CEdit::OnWndMsg( message, wParam, lParam, pResult);
  312. }