no-more-ini-files-20040713
[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
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                     "SOFTWARE\\OpenAFS\\Client\\Submounts",
50                     0, 
51                     "AFS", 
52                     REG_OPTION_NON_VOLATILE,
53                     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, dwSize;
166     DWORD status;
167     DWORD dwIndex;
168     DWORD dwSubmounts;
169
170     RegCreateKeyEx( HKEY_LOCAL_MACHINE, 
171                     "SOFTWARE\\OpenAFS\\Client\\Submounts",
172                     0, 
173                     "AFS", 
174                     REG_OPTION_NON_VOLATILE,
175                     KEY_READ|KEY_WRITE|KEY_QUERY_VALUE,
176                     NULL, 
177                     &hkSubmounts,
178                     NULL );
179
180     RegQueryInfoKey( hkSubmounts,
181                  NULL,  /* lpClass */
182                  NULL,  /* lpcClass */
183                  NULL,  /* lpReserved */
184                  NULL,  /* lpcSubKeys */
185                  NULL,  /* lpcMaxSubKeyLen */
186                  NULL,  /* lpcMaxClassLen */
187                  &dwSubmounts, /* lpcValues */
188                  NULL,  /* lpcMaxValueNameLen */
189                  NULL,  /* lpcMaxValueLen */
190                  NULL,  /* lpcbSecurityDescriptor */
191                  NULL   /* lpftLastWriteTime */
192                  );
193
194
195     for ( dwIndex = 0; dwIndex < dwSubmounts; dwIndex ++ ) {
196         char submountName[256];
197         DWORD submountNameLen = sizeof(submountName);
198
199         RegEnumValue( hkSubmounts, dwIndex, submountName, &submountNameLen, NULL,
200               &dwType, NULL, NULL);
201
202         m_SubmtList.AddString(submountName);
203     }
204
205     RegCloseKey( hkSubmounts );
206
207         return TRUE;
208 }
209
210 void CSubmountsDlg::OnDelete() 
211 {
212         HOURGLASS hourglass;
213         
214         int nIndex = m_SubmtList.GetCurSel();
215         ASSERT(nIndex >= 0);
216
217         CString strSubmt;
218         CString strShareName;
219         m_SubmtList.GetText(nIndex, strSubmt);
220
221         ASSERT(!strSubmt.IsEmpty());
222
223         strShareName = strSubmt.SpanExcluding("=");
224
225         if (ShowMessageBox(IDS_REALLY_DELETE_SUBMT, MB_YESNO | MB_ICONQUESTION, IDS_REALLY_DELETE_SUBMT, strShareName) != IDYES)
226                 return;
227
228         m_SubmtList.DeleteString(nIndex);
229
230         if (m_SubmtList.GetCount() == 0) {
231                 m_Delete.EnableWindow(FALSE);
232                 m_Change.EnableWindow(FALSE);
233         }
234
235         CSubmountInfo *pInfo = new CSubmountInfo();
236         pInfo->SetShareName(strShareName);
237         pInfo->SetStatus(SIS_DELETED);
238         AddWork(pInfo);
239 }
240
241 void CSubmountsDlg::OnSelChangeList() 
242 {
243         m_Delete.EnableWindow(TRUE);
244         m_Change.EnableWindow(TRUE);
245 }
246
247 static BOOL AddSubmt(CSubmountInfo *pInfo)
248 {
249         HOURGLASS hourglass;
250
251     HKEY hkSubmounts;
252     RegCreateKeyEx( HKEY_LOCAL_MACHINE, 
253                     "SOFTWARE\\OpenAFS\\Client\\Submounts",
254                     0, 
255                     "AFS", 
256                     REG_OPTION_NON_VOLATILE,
257                     KEY_WRITE,
258                     NULL, 
259                     &hkSubmounts,
260                     NULL );
261
262     DWORD status = RegSetValueEx( hkSubmounts, PCCHAR(pInfo->GetShareName()), 0, REG_SZ,
263                    (const BYTE *)PCCHAR(pInfo->GetPathName()), strlen(PCCHAR(pInfo->GetPathName())) + 1);
264
265     RegCloseKey(hkSubmounts);
266         return (status == ERROR_SUCCESS);
267 }
268
269 static BOOL DeleteSubmt(CSubmountInfo *pInfo)
270 {
271         HOURGLASS hourglass;
272
273     HKEY hkSubmounts;
274     RegCreateKeyEx( HKEY_LOCAL_MACHINE, 
275                     "SOFTWARE\\OpenAFS\\Client\\Submounts",
276                     0, 
277                     "AFS", 
278                     REG_OPTION_NON_VOLATILE,
279                     KEY_WRITE,
280                     NULL, 
281                     &hkSubmounts,
282                     NULL );
283
284     DWORD status = RegDeleteValue( hkSubmounts, PCCHAR(pInfo->GetShareName()));
285
286     RegCloseKey(hkSubmounts);
287         return (status == ERROR_SUCCESS);
288 }
289
290 void CSubmountsDlg::OnAdd() 
291 {
292         CAddSubmtDlg dlg;
293
294         if (m_bAddOnlyMode) {
295                 CSubmountInfo info("", m_strAddOnlyPath, SIS_ADDED);
296                 dlg.SetSubmtInfo(&info);
297         }
298
299         dlg.DoModal();
300
301         CSubmountInfo *pInfo = dlg.GetSubmtInfo();
302         if (!pInfo)
303                 return;
304
305         m_SubmtList.AddString(pInfo->GetShareName() + "=" + pInfo->GetPathName());
306         AddWork(pInfo);
307 }
308
309 void CSubmountsDlg::OnChange() 
310 {
311         CAddSubmtDlg dlg;
312
313         HOURGLASS hourglass;
314
315         dlg.SetAddMode(FALSE);
316
317         int nIndex = m_SubmtList.GetCurSel();
318         ASSERT(nIndex >= 0);
319
320         CString strSubmt;
321         CString strShareName;
322         m_SubmtList.GetText(nIndex, strSubmt);
323
324         ASSERT(!strSubmt.IsEmpty());
325
326         strShareName = strSubmt.SpanExcluding("=");
327
328         CSubmountInfo *pInfo = FindWork(strShareName);
329         if (pInfo != 0)
330                 // Make a copy we can free below
331                 pInfo = new CSubmountInfo(*pInfo);
332         else
333                 pInfo = ReadSubmtInfo(strShareName);
334
335         if (!pInfo) {
336                 ShowMessageBox(IDS_GET_SUBMT_INFO_ERROR, MB_ICONEXCLAMATION, IDS_GET_SUBMT_INFO_ERROR, strShareName);
337                 return;
338         }
339
340         dlg.SetSubmtInfo(pInfo);
341         
342         delete pInfo;
343
344         if (dlg.DoModal() != IDOK)
345                 return;
346                 
347         pInfo = dlg.GetSubmtInfo();
348
349         m_SubmtList.DeleteString(nIndex);
350         m_SubmtList.InsertString(nIndex,
351                 pInfo->GetShareName() + "=" + pInfo->GetPathName());
352
353         AddWork(pInfo);
354 }
355
356 void CSubmountsDlg::AddWork(CSubmountInfo *pInfo)
357 {
358         ASSERT_VALID(pInfo);
359
360         HOURGLASS hourglass;
361
362         BOOL bAdd = TRUE;
363
364         for (int i = 0; i < m_ToDo.GetSize(); i++) {
365                 if (m_ToDo[i]->GetShareName() == pInfo->GetShareName()) {
366                         if ((pInfo->GetStatus() == SIS_DELETED) && (m_ToDo[i]->GetStatus() == SIS_ADDED))
367                                 bAdd = FALSE;
368                         delete m_ToDo[i];
369                         m_ToDo.RemoveAt(i);
370                         break;  
371                 }
372         }
373
374         if (bAdd)
375                 m_ToDo.Add(pInfo);
376 }
377
378 BOOL CSubmountsDlg::FixSubmts()
379 {
380         for (int i = 0; i < m_ToDo.GetSize(); i++) {
381                 SUBMT_INFO_STATUS status = m_ToDo[i]->GetStatus();
382                 if ((status == SIS_ADDED) || (status == SIS_CHANGED))
383                         if (!AddSubmt(m_ToDo[i]))
384                                 return FALSE;
385                 if (status == SIS_DELETED)
386                         if (!DeleteSubmt(m_ToDo[i]))
387                                 return FALSE;
388         }
389
390         return TRUE;
391 }
392
393 CSubmountInfo *CSubmountsDlg::FindWork(const CString& strShareName)
394 {
395         for (int i = 0; i < m_ToDo.GetSize(); i++)
396                 if (m_ToDo[i]->GetShareName() == strShareName)
397                         return m_ToDo[i];
398
399         return 0;
400 }
401
402 void CSubmountsDlg::WinHelp(DWORD dwData, UINT nCmd) 
403 {
404         CDialog::WinHelp(dwData, nCmd);
405 }
406
407 void CSubmountsDlg::OnOk() 
408 {
409         if (!FixSubmts())
410                 ShowMessageBox(IDS_SUBMT_SAVE_FAILED);
411
412         CDialog::OnOK();
413 }
414
415 void CSubmountsDlg::SetAddOnlyMode(const CString& strAddOnlyPath)
416 {
417         m_bAddOnlyMode = TRUE;
418         m_strAddOnlyPath = strAddOnlyPath;
419 }
420