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