windows-wow64-registry-20080208
[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         char pathName[1024];
49
50     HKEY hkSubmounts;
51     RegCreateKeyEx( 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, (LPCSTR)PCCHAR(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     RegCreateKeyEx( 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         char 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("=");
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     RegCreateKeyEx( 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, PCCHAR(pInfo->GetShareName()), 0, REG_SZ,
265                    (const BYTE *)PCCHAR(pInfo->GetPathName()), strlen(PCCHAR(pInfo->GetPathName())) + 1);
266
267     RegCloseKey(hkSubmounts);
268         return (status == ERROR_SUCCESS);
269 }
270
271 static BOOL DeleteSubmt(CSubmountInfo *pInfo)
272 {
273         HOURGLASS hourglass;
274
275     HKEY hkSubmounts;
276     RegCreateKeyEx( HKEY_LOCAL_MACHINE, 
277                     AFSREG_CLT_OPENAFS_SUBKEY "\\Submounts",
278                     0, 
279                     "AFS", 
280                     REG_OPTION_NON_VOLATILE,
281                     (IsWow64()?KEY_WOW64_64KEY:0)|KEY_WRITE,
282                     NULL, 
283                     &hkSubmounts,
284                     NULL );
285
286     DWORD status = RegDeleteValue( hkSubmounts, PCCHAR(pInfo->GetShareName()));
287
288     RegCloseKey(hkSubmounts);
289         return (status == ERROR_SUCCESS);
290 }
291
292 void CSubmountsDlg::OnAdd() 
293 {
294         CAddSubmtDlg dlg;
295
296         if (m_bAddOnlyMode) {
297                 CSubmountInfo info("", m_strAddOnlyPath, SIS_ADDED);
298                 dlg.SetSubmtInfo(&info);
299         }
300
301         dlg.DoModal();
302
303         CSubmountInfo *pInfo = dlg.GetSubmtInfo();
304         if (!pInfo)
305                 return;
306
307         m_SubmtList.AddString(pInfo->GetShareName() + "=" + pInfo->GetPathName());
308         AddWork(pInfo);
309 }
310
311 void CSubmountsDlg::OnChange() 
312 {
313         CAddSubmtDlg dlg;
314
315         HOURGLASS hourglass;
316
317         dlg.SetAddMode(FALSE);
318
319         int nIndex = m_SubmtList.GetCurSel();
320         ASSERT(nIndex >= 0);
321
322         CString strSubmt;
323         CString strShareName;
324         m_SubmtList.GetText(nIndex, strSubmt);
325
326         ASSERT(!strSubmt.IsEmpty());
327
328         strShareName = strSubmt.SpanExcluding("=");
329
330         CSubmountInfo *pInfo = FindWork(strShareName);
331         if (pInfo != 0)
332                 // Make a copy we can free below
333                 pInfo = new CSubmountInfo(*pInfo);
334         else
335                 pInfo = ReadSubmtInfo(strShareName);
336
337         if (!pInfo) {
338                 ShowMessageBox(IDS_GET_SUBMT_INFO_ERROR, MB_ICONEXCLAMATION, IDS_GET_SUBMT_INFO_ERROR, strShareName);
339                 return;
340         }
341
342         dlg.SetSubmtInfo(pInfo);
343         
344         delete pInfo;
345
346         if (dlg.DoModal() != IDOK)
347                 return;
348                 
349         pInfo = dlg.GetSubmtInfo();
350
351         m_SubmtList.DeleteString(nIndex);
352         m_SubmtList.InsertString(nIndex,
353                 pInfo->GetShareName() + "=" + pInfo->GetPathName());
354
355         AddWork(pInfo);
356 }
357
358 void CSubmountsDlg::AddWork(CSubmountInfo *pInfo)
359 {
360         ASSERT_VALID(pInfo);
361
362         HOURGLASS hourglass;
363
364         BOOL bAdd = TRUE;
365
366         for (int i = 0; i < m_ToDo.GetSize(); i++) {
367                 if (m_ToDo[i]->GetShareName() == pInfo->GetShareName()) {
368                         if ((pInfo->GetStatus() == SIS_DELETED) && (m_ToDo[i]->GetStatus() == SIS_ADDED))
369                                 bAdd = FALSE;
370                         delete m_ToDo[i];
371                         m_ToDo.RemoveAt(i);
372                         break;  
373                 }
374         }
375
376         if (bAdd)
377                 m_ToDo.Add(pInfo);
378 }
379
380 BOOL CSubmountsDlg::FixSubmts()
381 {
382         for (int i = 0; i < m_ToDo.GetSize(); i++) {
383                 SUBMT_INFO_STATUS status = m_ToDo[i]->GetStatus();
384                 if ((status == SIS_ADDED) || (status == SIS_CHANGED))
385                         if (!AddSubmt(m_ToDo[i]))
386                                 return FALSE;
387                 if (status == SIS_DELETED)
388                         if (!DeleteSubmt(m_ToDo[i]))
389                                 return FALSE;
390         }
391
392         return TRUE;
393 }
394
395 CSubmountInfo *CSubmountsDlg::FindWork(const CString& strShareName)
396 {
397         for (int i = 0; i < m_ToDo.GetSize(); i++)
398                 if (m_ToDo[i]->GetShareName() == strShareName)
399                         return m_ToDo[i];
400
401         return 0;
402 }
403
404 void CSubmountsDlg::WinHelp(DWORD dwData, UINT nCmd) 
405 {
406         CDialog::WinHelp(dwData, nCmd);
407 }
408
409 void CSubmountsDlg::OnOk() 
410 {
411         if (!FixSubmts())
412                 ShowMessageBox(IDS_SUBMT_SAVE_FAILED);
413
414         CDialog::OnOK();
415 }
416
417 void CSubmountsDlg::SetAddOnlyMode(const CString& strAddOnlyPath)
418 {
419         m_bAddOnlyMode = TRUE;
420         m_strAddOnlyPath = strAddOnlyPath;
421 }
422