c1b9c9499137f14404696b72b106bddd731a71c0
[openafs.git] / src / WINNT / client_exp / submounts_dlg.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 extern "C" {
11 #include <afs/param.h>
12 #include <afs/stds.h>
13 }
14
15 #include "stdafx.h"
16 #include "submounts_dlg.h"
17 #include "add_submount_dlg.h"
18 #include "msgs.h"
19 #include "submount_info.h"
20 #include "hourglass.h"
21 #include <WINNT\afsreg.h>
22
23 #ifdef _DEBUG
24 #define new DEBUG_NEW
25 #undef THIS_FILE
26 static char THIS_FILE[] = __FILE__;
27 #endif
28
29 #define PCCHAR(str)             ((char *)(const char *)(str))
30
31
32 /////////////////////////////////////////////////////////////////////////////
33 // CSubmountsDlg property page
34
35 IMPLEMENT_DYNCREATE(CSubmountsDlg, CDialog)
36
37 static CSubmountInfo *ReadSubmtInfo(const CString& strShareName)
38 {
39         HOURGLASS hourglass;
40
41         CSubmountInfo *pInfo = 0;
42
43         DWORD len;
44
45         char pathName[1024];
46
47     HKEY hkSubmounts;
48     RegCreateKeyEx( HKEY_LOCAL_MACHINE, 
49                     AFSREG_CLT_OPENAFS_SUBKEY "\\Submounts",
50                     0, 
51                     "AFS", 
52                     REG_OPTION_NON_VOLATILE,
53                     (IsWow64()?KEY_WOW64_64KEY:0)|KEY_READ,
54                     NULL, 
55                     &hkSubmounts,
56                     NULL );
57
58     DWORD dwType;
59     DWORD status;
60     len = sizeof(pathName);
61     status = RegQueryValueEx( hkSubmounts, (LPCSTR)PCCHAR(strShareName), 0,
62                               &dwType, (LPBYTE)pathName, &len);
63     RegCloseKey( hkSubmounts );
64
65         if (status || len == 0)
66                 return pInfo;
67
68         pInfo = new CSubmountInfo();
69         pInfo->SetShareName(strShareName);
70         pInfo->SetPathName(pathName);
71
72         return pInfo;
73 }
74
75 CSubmountsDlg::CSubmountsDlg() : CDialog()
76 {
77         InitModalIndirect (TaLocale_GetDialogResource (CSubmountsDlg::IDD));
78
79         //{{AFX_DATA_INIT(CSubmountsDlg)
80                 // NOTE: the ClassWizard will add member initialization here
81         //}}AFX_DATA_INIT
82
83         m_bAddOnlyMode = FALSE;
84 }
85
86 CSubmountsDlg::~CSubmountsDlg()
87 {
88         for (int i = 0; i < m_ToDo.GetSize(); i++)
89                 delete m_ToDo[i];
90
91         m_ToDo.RemoveAll();
92 }
93
94 void CSubmountsDlg::DoDataExchange(CDataExchange* pDX)
95 {
96         CDialog::DoDataExchange(pDX);
97         //{{AFX_DATA_MAP(CSubmountsDlg)
98         DDX_Control(pDX, IDC_DELETE, m_Delete);
99         DDX_Control(pDX, IDC_CHANGE, m_Change);
100         DDX_Control(pDX, IDC_LIST, m_SubmtList);
101         //}}AFX_DATA_MAP
102 }
103
104
105 BEGIN_MESSAGE_MAP(CSubmountsDlg, CDialog)
106         //{{AFX_MSG_MAP(CSubmountsDlg)
107         ON_BN_CLICKED(IDC_ADD, OnAdd)
108         ON_BN_CLICKED(IDC_CHANGE, OnChange)
109         ON_BN_CLICKED(IDC_DELETE, OnDelete)
110         ON_LBN_SELCHANGE(IDC_LIST, OnSelChangeList)
111         ON_BN_CLICKED(IDOK, OnOk)
112         //}}AFX_MSG_MAP
113 END_MESSAGE_MAP()
114
115 /////////////////////////////////////////////////////////////////////////////
116 // CSubmountsDlg message handlers
117
118 BOOL CSubmountsDlg::OnInitDialog() 
119 {
120         CDialog::OnInitDialog();
121
122         if (m_bAddOnlyMode) {
123                 TCHAR szRemoteName[MAX_PATH];
124                 ULONG nBufSize = sizeof(szRemoteName);
125
126                 if (WNetGetConnection(m_strAddOnlyPath.Left(2), szRemoteName, &nBufSize) == ERROR_SUCCESS) {
127                         CString strAfsShare(szRemoteName);
128                         int nSlashPos = strAfsShare.ReverseFind('\\');
129                         if (nSlashPos > -1) {
130                                 strAfsShare = strAfsShare.Mid(nSlashPos + 1);
131
132                                 // Get the submount info for this share name
133                                 CSubmountInfo *pInfo = ReadSubmtInfo(strAfsShare);
134                                 CString strSharePath;
135                                 if (pInfo != 0) {
136                                         ASSERT_VALID(pInfo);
137                                         strSharePath = pInfo->GetPathName();
138                                 }
139
140                                 m_strAddOnlyPath = strSharePath + m_strAddOnlyPath.Mid(2);
141                         }
142                 }
143
144                 OnAdd();
145                 OnOk();
146
147                 return TRUE;
148         }
149
150         if (!FillSubmtList()) {
151 //              ShowMessageBox(IDS_GET_CELL_LIST_ERROR);
152 //              EndDialog(0);
153 //              return TRUE;
154         }
155
156         return TRUE;  // return TRUE unless you set the focus to a control
157                       // EXCEPTION: OCX Property Pages should return FALSE
158 }
159
160 BOOL CSubmountsDlg::FillSubmtList()
161 {
162         HOURGLASS hourglass;
163
164     HKEY hkSubmounts;
165     DWORD dwType;
166     DWORD dwIndex;
167     DWORD dwSubmounts;
168
169     RegCreateKeyEx( HKEY_LOCAL_MACHINE, 
170                     AFSREG_CLT_OPENAFS_SUBKEY "\\Submounts",
171                     0, 
172                     "AFS", 
173                     REG_OPTION_NON_VOLATILE,
174                     (IsWow64()?KEY_WOW64_64KEY:0)|KEY_READ|KEY_WRITE|KEY_QUERY_VALUE,
175                     NULL, 
176                     &hkSubmounts,
177                     NULL );
178
179     RegQueryInfoKey( hkSubmounts,
180                  NULL,  /* lpClass */
181                  NULL,  /* lpcClass */
182                  NULL,  /* lpReserved */
183                  NULL,  /* lpcSubKeys */
184                  NULL,  /* lpcMaxSubKeyLen */
185                  NULL,  /* lpcMaxClassLen */
186                  &dwSubmounts, /* lpcValues */
187                  NULL,  /* lpcMaxValueNameLen */
188                  NULL,  /* lpcMaxValueLen */
189                  NULL,  /* lpcbSecurityDescriptor */
190                  NULL   /* lpftLastWriteTime */
191                  );
192
193
194     for ( dwIndex = 0; dwIndex < dwSubmounts; dwIndex ++ ) {
195         char submountName[256];
196         DWORD submountNameLen = sizeof(submountName);
197
198         RegEnumValue( hkSubmounts, dwIndex, submountName, &submountNameLen, NULL,
199               &dwType, NULL, NULL);
200
201         m_SubmtList.AddString(submountName);
202     }
203
204     RegCloseKey( hkSubmounts );
205
206         return TRUE;
207 }
208
209 void CSubmountsDlg::OnDelete() 
210 {
211         HOURGLASS hourglass;
212         
213         int nIndex = m_SubmtList.GetCurSel();
214         ASSERT(nIndex >= 0);
215
216         CString strSubmt;
217         CString strShareName;
218         m_SubmtList.GetText(nIndex, strSubmt);
219
220         ASSERT(!strSubmt.IsEmpty());
221
222         strShareName = strSubmt.SpanExcluding("=");
223
224         if (ShowMessageBox(IDS_REALLY_DELETE_SUBMT, MB_YESNO | MB_ICONQUESTION, IDS_REALLY_DELETE_SUBMT, strShareName) != IDYES)
225                 return;
226
227         m_SubmtList.DeleteString(nIndex);
228
229         if (m_SubmtList.GetCount() == 0) {
230                 m_Delete.EnableWindow(FALSE);
231                 m_Change.EnableWindow(FALSE);
232         }
233
234         CSubmountInfo *pInfo = new CSubmountInfo();
235         pInfo->SetShareName(strShareName);
236         pInfo->SetStatus(SIS_DELETED);
237         AddWork(pInfo);
238 }
239
240 void CSubmountsDlg::OnSelChangeList() 
241 {
242         m_Delete.EnableWindow(TRUE);
243         m_Change.EnableWindow(TRUE);
244 }
245
246 static BOOL AddSubmt(CSubmountInfo *pInfo)
247 {
248         HOURGLASS hourglass;
249
250     HKEY hkSubmounts;
251     RegCreateKeyEx( HKEY_LOCAL_MACHINE, 
252                     AFSREG_CLT_OPENAFS_SUBKEY "\\Submounts",
253                     0, 
254                     "AFS", 
255                     REG_OPTION_NON_VOLATILE,
256                     (IsWow64()?KEY_WOW64_64KEY:0)|KEY_WRITE,
257                     NULL, 
258                     &hkSubmounts,
259                     NULL );
260
261     DWORD status = RegSetValueEx( hkSubmounts, PCCHAR(pInfo->GetShareName()), 0, REG_SZ,
262                    (const BYTE *)PCCHAR(pInfo->GetPathName()), strlen(PCCHAR(pInfo->GetPathName())) + 1);
263
264     RegCloseKey(hkSubmounts);
265         return (status == ERROR_SUCCESS);
266 }
267
268 static BOOL DeleteSubmt(CSubmountInfo *pInfo)
269 {
270         HOURGLASS hourglass;
271
272     HKEY hkSubmounts;
273     RegCreateKeyEx( HKEY_LOCAL_MACHINE, 
274                     AFSREG_CLT_OPENAFS_SUBKEY "\\Submounts",
275                     0, 
276                     "AFS", 
277                     REG_OPTION_NON_VOLATILE,
278                     (IsWow64()?KEY_WOW64_64KEY:0)|KEY_WRITE,
279                     NULL, 
280                     &hkSubmounts,
281                     NULL );
282
283     DWORD status = RegDeleteValue( hkSubmounts, PCCHAR(pInfo->GetShareName()));
284
285     RegCloseKey(hkSubmounts);
286         return (status == ERROR_SUCCESS);
287 }
288
289 void CSubmountsDlg::OnAdd() 
290 {
291         CAddSubmtDlg dlg;
292
293         if (m_bAddOnlyMode) {
294                 CSubmountInfo info("", m_strAddOnlyPath, SIS_ADDED);
295                 dlg.SetSubmtInfo(&info);
296         }
297
298         dlg.DoModal();
299
300         CSubmountInfo *pInfo = dlg.GetSubmtInfo();
301         if (!pInfo)
302                 return;
303
304         m_SubmtList.AddString(pInfo->GetShareName() + "=" + pInfo->GetPathName());
305         AddWork(pInfo);
306 }
307
308 void CSubmountsDlg::OnChange() 
309 {
310         CAddSubmtDlg dlg;
311
312         HOURGLASS hourglass;
313
314         dlg.SetAddMode(FALSE);
315
316         int nIndex = m_SubmtList.GetCurSel();
317         ASSERT(nIndex >= 0);
318
319         CString strSubmt;
320         CString strShareName;
321         m_SubmtList.GetText(nIndex, strSubmt);
322
323         ASSERT(!strSubmt.IsEmpty());
324
325         strShareName = strSubmt.SpanExcluding("=");
326
327         CSubmountInfo *pInfo = FindWork(strShareName);
328         if (pInfo != 0)
329                 // Make a copy we can free below
330                 pInfo = new CSubmountInfo(*pInfo);
331         else
332                 pInfo = ReadSubmtInfo(strShareName);
333
334         if (!pInfo) {
335                 ShowMessageBox(IDS_GET_SUBMT_INFO_ERROR, MB_ICONEXCLAMATION, IDS_GET_SUBMT_INFO_ERROR, strShareName);
336                 return;
337         }
338
339         dlg.SetSubmtInfo(pInfo);
340         
341         delete pInfo;
342
343         if (dlg.DoModal() != IDOK)
344                 return;
345                 
346         pInfo = dlg.GetSubmtInfo();
347
348         m_SubmtList.DeleteString(nIndex);
349         m_SubmtList.InsertString(nIndex,
350                 pInfo->GetShareName() + "=" + pInfo->GetPathName());
351
352         AddWork(pInfo);
353 }
354
355 void CSubmountsDlg::AddWork(CSubmountInfo *pInfo)
356 {
357         ASSERT_VALID(pInfo);
358
359         HOURGLASS hourglass;
360
361         BOOL bAdd = TRUE;
362
363         for (int i = 0; i < m_ToDo.GetSize(); i++) {
364                 if (m_ToDo[i]->GetShareName() == pInfo->GetShareName()) {
365                         if ((pInfo->GetStatus() == SIS_DELETED) && (m_ToDo[i]->GetStatus() == SIS_ADDED))
366                                 bAdd = FALSE;
367                         delete m_ToDo[i];
368                         m_ToDo.RemoveAt(i);
369                         break;  
370                 }
371         }
372
373         if (bAdd)
374                 m_ToDo.Add(pInfo);
375 }
376
377 BOOL CSubmountsDlg::FixSubmts()
378 {
379         for (int i = 0; i < m_ToDo.GetSize(); i++) {
380                 SUBMT_INFO_STATUS status = m_ToDo[i]->GetStatus();
381                 if ((status == SIS_ADDED) || (status == SIS_CHANGED))
382                         if (!AddSubmt(m_ToDo[i]))
383                                 return FALSE;
384                 if (status == SIS_DELETED)
385                         if (!DeleteSubmt(m_ToDo[i]))
386                                 return FALSE;
387         }
388
389         return TRUE;
390 }
391
392 CSubmountInfo *CSubmountsDlg::FindWork(const CString& strShareName)
393 {
394         for (int i = 0; i < m_ToDo.GetSize(); i++)
395                 if (m_ToDo[i]->GetShareName() == strShareName)
396                         return m_ToDo[i];
397
398         return 0;
399 }
400
401 void CSubmountsDlg::WinHelp(DWORD dwData, UINT nCmd) 
402 {
403         CDialog::WinHelp(dwData, nCmd);
404 }
405
406 void CSubmountsDlg::OnOk() 
407 {
408         if (!FixSubmts())
409                 ShowMessageBox(IDS_SUBMT_SAVE_FAILED);
410
411         CDialog::OnOK();
412 }
413
414 void CSubmountsDlg::SetAddOnlyMode(const CString& strAddOnlyPath)
415 {
416         m_bAddOnlyMode = TRUE;
417         m_strAddOnlyPath = strAddOnlyPath;
418 }
419