Windows: Mount Point and Symlink Overlay Icons
[openafs.git] / src / WINNT / client_exp / set_afs_acl.cpp
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  *
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 #include "stdafx.h"
11 #include <winsock2.h>
12 #include <ws2tcpip.h>
13
14 extern "C" {
15 #include <afs/param.h>
16 #include <afs/stds.h>
17 }
18
19 #include "afs_shl_ext.h"
20 #include "set_afs_acl.h"
21 #include "clear_acl_dlg.h"
22 #include "add_acl_entry_dlg.h"
23 #include "copy_acl_dlg.h"
24 #include "gui2fs.h"
25
26 #ifdef _DEBUG
27 #define new DEBUG_NEW
28 #undef THIS_FILE
29 static char THIS_FILE[] = __FILE__;
30 #endif
31
32 /////////////////////////////////////////////////////////////////////////////
33 // CSetAfsAcl dialog
34
35
36 CSetAfsAcl::CSetAfsAcl(CWnd* pParent /*=NULL*/)
37         : CDialog()
38 {
39         InitModalIndirect (TaLocale_GetDialogResource (CSetAfsAcl::IDD), pParent);
40
41         //{{AFX_DATA_INIT(CSetAfsAcl)
42         //}}AFX_DATA_INIT
43
44         m_bChanges = FALSE;
45         m_nCurSel = -1;
46 }
47
48 void CSetAfsAcl::DoDataExchange(CDataExchange* pDX)
49 {
50         CDialog::DoDataExchange(pDX);
51         //{{AFX_DATA_MAP(CSetAfsAcl)
52         DDX_Control(pDX, IDC_REMOVE, m_Remove);
53         DDX_Control(pDX, IDC_ADMINISTER, m_AdminPerm);
54         DDX_Control(pDX, IDC_LOCK, m_LockPerm);
55         DDX_Control(pDX, IDC_INSERT, m_InsertPerm);
56         DDX_Control(pDX, IDC_DELETE, m_DeletePerm);
57         DDX_Control(pDX, IDC_LOOKUP, m_LookupPerm);
58         DDX_Control(pDX, IDC_WRITE, m_WritePerm);
59         DDX_Control(pDX, IDC_READ, m_ReadPerm);
60         DDX_Control(pDX, IDC_DIR_NAME, m_DirName);
61         DDX_Control(pDX, IDC_NEGATIVE_ENTRIES, m_NegativeRights);
62         DDX_Control(pDX, IDC_NORMAL_RIGHTS, m_NormalRights);
63         //}}AFX_DATA_MAP
64 }
65
66 BEGIN_MESSAGE_MAP(CSetAfsAcl, CDialog)
67         //{{AFX_MSG_MAP(CSetAfsAcl)
68         ON_BN_CLICKED(IDC_CLEAR, OnClear)
69         ON_BN_CLICKED(IDC_ADD, OnAdd)
70         ON_BN_CLICKED(IDC_COPY, OnCopy)
71         ON_LBN_SELCHANGE(IDC_NORMAL_RIGHTS, OnSelChangeNormalRights)
72         ON_LBN_SELCHANGE(IDC_NEGATIVE_ENTRIES, OnSelChangeNegativeEntries)
73         ON_BN_CLICKED(IDC_ADMINISTER, OnPermChange)
74         ON_BN_CLICKED(IDC_REMOVE, OnRemove)
75         ON_BN_CLICKED(IDC_CLEAN, OnClean)
76         ON_BN_CLICKED(IDC_DELETE, OnPermChange)
77         ON_BN_CLICKED(IDC_INSERT, OnPermChange)
78         ON_BN_CLICKED(IDC_LOCK, OnPermChange)
79         ON_BN_CLICKED(IDC_LOOKUP, OnPermChange)
80         ON_BN_CLICKED(IDC_READ, OnPermChange)
81         ON_BN_CLICKED(IDC_WRITE, OnPermChange)
82         ON_BN_CLICKED(IDHELP, OnHelp)
83         //}}AFX_MSG_MAP
84 END_MESSAGE_MAP()
85
86 /////////////////////////////////////////////////////////////////////////////
87 // CSetAfsAcl message handlers
88
89 BOOL CSetAfsAcl::OnInitDialog()
90 {
91         CDialog::OnInitDialog();
92
93         if (!GetRights(m_strDir, m_Normal, m_Negative)) {
94                 EndDialog(0);
95                 return TRUE;
96         }
97
98         m_DirName.SetWindowText(m_strDir);
99
100         EnablePermChanges(FALSE);
101
102         m_NormalRights.SetTabStops(58);
103         m_NegativeRights.SetTabStops(58);
104
105         int i;
106         for (i = 0; i < m_Normal.GetSize(); i += 2)
107                 m_NormalRights.AddString(m_Normal[i + 1] + _T("\t") + m_Normal[i]);
108
109         for (i = 0; i < m_Negative.GetSize(); i += 2)
110                 m_NegativeRights.AddString(m_Negative[i + 1] + _T("\t") + m_Negative[i]);
111
112         CenterWindow();
113
114         return TRUE;  // return TRUE unless you set the focus to a control
115                       // EXCEPTION: OCX Property Pages should return FALSE
116 }
117
118 void CSetAfsAcl::OnClear()
119 {
120         CClearAclDlg dlg;
121
122         if (dlg.DoModal() == IDCANCEL)
123                 return;
124
125         BOOL bNormal, bNegative, bClearRights = FALSE;
126
127         dlg.GetSettings(bNormal, bNegative);
128
129         if (bNormal) {
130                 m_Normal.RemoveAll();
131                 m_NormalRights.ResetContent();
132                 if (m_bShowingNormal)
133                         bClearRights = TRUE;
134         }
135
136         if (bNegative) {
137                 m_Negative.RemoveAll();
138                 m_NegativeRights.ResetContent();
139                 if (!m_bShowingNormal)
140                         bClearRights = TRUE;
141         }
142
143         if (bClearRights)
144                 OnNothingSelected();
145 }
146
147 void CSetAfsAcl::OnAdd()
148 {
149         CAddAclEntryDlg dlg;
150
151         dlg.SetAclDlg(this);
152
153         if (dlg.DoModal() == IDCANCEL)
154                 return;
155
156         OnNothingSelected();
157
158         CString name = dlg.GetName();
159         CString rights = dlg.GetRights();
160         BOOL bNormal = dlg.IsNormal();
161
162         if (bNormal) {
163                 m_Normal.Add(name);
164                 m_Normal.Add(rights);
165                 m_nCurSel = m_NormalRights.AddString(rights + _T("\t") + name);
166                 m_NormalRights.SetSel(m_nCurSel);
167                 m_bShowingNormal = TRUE;
168         } else {
169                 m_Negative.Add(name);
170                 m_Negative.Add(rights);
171                 m_nCurSel = m_NegativeRights.AddString(rights + _T("\t") + name);
172                 m_NegativeRights.SetSel(m_nCurSel);
173                 m_bShowingNormal = FALSE;
174         }
175
176         ShowRights(rights);
177         EnablePermChanges(TRUE);
178
179         m_bChanges = TRUE;
180 }
181
182 void CSetAfsAcl::OnCopy()
183 {
184         CCopyAclDlg dlg;
185
186         dlg.SetFromDir(m_strDir);
187
188         if (dlg.DoModal() == IDCANCEL)
189                 return;
190
191         CString strToDir = dlg.GetToDir();
192         BOOL bClear = dlg.GetClear();
193
194         CopyACL(strToDir, m_Normal, m_Negative, bClear);
195 }
196
197 void CSetAfsAcl::ShowRights(const CString& strRights)
198 {
199         m_ReadPerm.SetCheck((strRights.Find(_T("r")) == -1) ? UNCHECKED : CHECKED);
200         m_WritePerm.SetCheck((strRights.Find(_T("w")) == -1) ? UNCHECKED : CHECKED);
201         m_LookupPerm.SetCheck((strRights.Find(_T("l")) == -1) ? UNCHECKED : CHECKED);
202         m_DeletePerm.SetCheck((strRights.Find(_T("d")) == -1) ? UNCHECKED : CHECKED);
203         m_InsertPerm.SetCheck((strRights.Find(_T("i")) == -1) ? UNCHECKED : CHECKED);
204         m_LockPerm.SetCheck((strRights.Find(_T("k")) == -1) ? UNCHECKED : CHECKED);
205         m_AdminPerm.SetCheck((strRights.Find(_T("a")) == -1) ? UNCHECKED : CHECKED);
206 }
207
208 void CSetAfsAcl::OnSelChangeNormalRights()
209 {
210         m_NegativeRights.SetSel(-1, FALSE);
211
212         m_bShowingNormal = TRUE;
213
214         int nNum = m_NormalRights.GetSelCount();
215         if (nNum != 1) {
216                 ShowRights(_T(""));
217                 EnablePermChanges(FALSE);
218                 return;
219         }
220
221         ASSERT(nNum == 1);              // I'm paranoid
222
223         VERIFY(m_NormalRights.GetSelItems(1, &m_nCurSel) == 1);
224
225         CString strRights = m_Normal[(m_nCurSel * 2) + 1];
226         ShowRights(strRights);
227
228         OnSelection();
229 }
230
231 void CSetAfsAcl::OnSelChangeNegativeEntries()
232 {
233         m_NormalRights.SetSel(-1, FALSE);
234
235         m_bShowingNormal = FALSE;
236
237         int nNum = m_NegativeRights.GetSelCount();
238         if (nNum != 1) {
239                 ShowRights(_T(""));
240                 EnablePermChanges(FALSE);
241                 return;
242         }
243
244         ASSERT(nNum == 1);              // I'm paranoid
245
246         VERIFY(m_NegativeRights.GetSelItems(1, &m_nCurSel) == 1);
247
248         CString strRights = m_Negative[(m_nCurSel * 2) + 1];
249         ShowRights(strRights);
250
251         OnSelection();
252 }
253
254 CString CSetAfsAcl::MakeRightsString()
255 {
256         CString str;
257
258         if (m_ReadPerm.GetCheck() == CHECKED)
259                 str += _T("r");
260         if (m_LookupPerm.GetCheck() == CHECKED)
261                 str += _T("l");
262         if (m_InsertPerm.GetCheck() == CHECKED)
263                 str += _T("i");
264         if (m_DeletePerm.GetCheck() == CHECKED)
265                 str += _T("d");
266         if (m_WritePerm.GetCheck() == CHECKED)
267                 str += _T("w");
268         if (m_LockPerm.GetCheck() == CHECKED)
269                 str += _T("k");
270         if (m_AdminPerm.GetCheck() == CHECKED)
271                 str += _T("a");
272
273         return str;
274 }
275
276 void CSetAfsAcl::OnPermChange()
277 {
278         CListBox *pRightsList;
279         CStringArray *pRights;
280
281         if (m_bShowingNormal) {
282                 pRightsList = &m_NormalRights;
283                 pRights = &m_Normal;
284         } else {
285                 pRightsList = &m_NegativeRights;
286                 pRights = &m_Negative;
287         }
288
289         ASSERT(m_nCurSel >= 0);
290
291         CString str = MakeRightsString();
292         (*pRights)[(2 * m_nCurSel) + 1] = str;
293         str += _T("\t") + (*pRights)[(2 * m_nCurSel)];
294
295         pRightsList->DeleteString(m_nCurSel);
296         pRightsList->InsertString(m_nCurSel, str);
297         pRightsList->SetSel(m_nCurSel);
298
299         m_bChanges = TRUE;
300 }
301
302 void CSetAfsAcl::OnRemove()
303 {
304         CListBox *pRightsList;
305         CStringArray *pRights;
306
307         if (m_bShowingNormal) {
308                 pRightsList = &m_NormalRights;
309                 pRights = &m_Normal;
310         } else {
311                 pRightsList = &m_NegativeRights;
312                 pRights = &m_Negative;
313         }
314
315         int nNum = pRightsList->GetSelCount();
316         if (nNum < 0) {
317                 ASSERT(FALSE);
318                 return;
319         }
320
321         if (nNum == 0) {
322                 ASSERT(FALSE);          // How can this ever be 0?
323                 ASSERT(m_nCurSel >= 0);
324                 pRightsList->DeleteString(m_nCurSel);
325                 pRights->RemoveAt(m_nCurSel * 2, 2);
326         } else {
327                 int *pIndexes = new int[nNum];
328                 VERIFY(pRightsList->GetSelItems(nNum, pIndexes) != LB_ERR);
329
330                 for (int i = nNum - 1; i >= 0; i--) {
331                         pRightsList->DeleteString(pIndexes[i]);
332                         pRights->RemoveAt(pIndexes[i] * 2, 2);
333                 }
334
335                 delete [] pIndexes;
336         }
337
338         OnNothingSelected();
339
340         m_bChanges = TRUE;
341 }
342
343 void CSetAfsAcl::EnablePermChanges(BOOL bEnable)
344 {
345         m_ReadPerm.EnableWindow(bEnable);
346         m_WritePerm.EnableWindow(bEnable);
347         m_LookupPerm.EnableWindow(bEnable);
348         m_DeletePerm.EnableWindow(bEnable);
349         m_InsertPerm.EnableWindow(bEnable);
350         m_LockPerm.EnableWindow(bEnable);
351         m_AdminPerm.EnableWindow(bEnable);
352 }
353
354 void CSetAfsAcl::OnNothingSelected()
355 {
356     //m_NormalRights.SetSel(-1,FALSE);  // Unselect any selected normal rights
357     //m_NegativeRights.SetSel(-1,FALSE);        // Unselect any selected negative rights
358
359     for (int i=0;i < m_NormalRights.GetCount();i++)
360     {
361         m_NormalRights.SetSel(i, FALSE);
362     }
363     for (int i=0;i < m_NegativeRights.GetCount();i++)
364     {
365         m_NegativeRights.SetSel(i, FALSE);
366     }
367     ShowRights(_T(""));                         // Show no rights
368     EnablePermChanges(FALSE);           // Allow no rights changes
369     m_Remove.EnableWindow(FALSE);               // Disable remove button
370 }
371
372 void CSetAfsAcl::OnSelection()
373 {
374         EnablePermChanges(TRUE);
375         m_Remove.EnableWindow(TRUE);
376 }
377
378 void CSetAfsAcl::OnOK()
379 {
380         if (m_bChanges && !SaveACL(m_strCellName, m_strDir, m_Normal, m_Negative))
381                 return;
382
383         CDialog::OnOK();
384 }
385
386 void CSetAfsAcl::OnClean()
387 {
388         CStringArray dirs;
389
390         dirs.Add(m_strDir);
391
392         CleanACL(dirs);
393 }
394
395 BOOL CSetAfsAcl::IsNameInUse(BOOL bNormal, const CString& strName)
396 {
397         if (bNormal) {
398                 for (int i = 0; i < m_Normal.GetSize(); i += 2)
399                         if (m_Normal[i] == strName)
400                                 return TRUE;
401
402                 return FALSE;
403         }
404
405         for (int i = 0; i < m_Negative.GetSize(); i += 2)
406                 if (m_Negative[i] == strName)
407                         return TRUE;
408
409         return FALSE;
410 }
411
412 void CSetAfsAcl::OnHelp()
413 {
414         ShowHelp(m_hWnd, SET_AFS_ACL_HELP_ID);
415 }
416