4b30e1362ba27397bf8ddc29d201417283aabbb6
[openafs.git] / src / WINNT / afssvrcfg / salvage_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 /*
11  * INCLUDES ___________________________________________________________________
12  *
13  */
14 extern "C" {
15 #include <afs/param.h>
16 #include <afs/stds.h>
17 }
18
19 #include "afscfg.h"             // Main header for this application
20 #include "resource.h"
21 extern "C" {
22 #include "afs_bosAdmin.h"
23 }
24 #include "admin_info_dlg.h"
25
26
27 /*
28  * DEFINITIONS _________________________________________________________________
29  *
30  */
31 static const int DEFAULT_NUM_PROCESSES          = 4;
32 static const char *DEFAULT_LOG_FILE                     = "";
33 static const int NUM_PROCS_BUF_SIZE                     = 5;
34 static const int MIN_NUM_PROCESSES                      = 1;
35 static const int MAX_NUM_PROCESSES                      = 32;
36
37 static HWND hDlg = 0;                                           // HWND for this page's dialog
38 static BOOL bAdvanced;
39 static TCHAR szPartitionName[25];
40 static TCHAR szVolumeName[cchRESOURCE];
41 static TCHAR szNumProcesses[NUM_PROCS_BUF_SIZE];
42 static TCHAR szTempDir[_MAX_PATH];
43 static LPTSTR pszPartitionName;
44 static LPTSTR pszVolumeName;
45 static int nNumProcesses;
46
47
48 /*
49  * PROTOTYPES _________________________________________________________________
50  *
51  */
52 static void OnInitDialog(HWND hwndDlg);
53 static void OnAdvanced();
54 static void UpdateControls();
55 static BOOL OnSalvage();
56 static DWORD WINAPI Salvage(LPVOID param);
57
58 BOOL CALLBACK SalvageDlgProc(HWND hDlg, UINT msg, WPARAM wp, LPARAM lp);
59
60
61 /*
62  * EXPORTED FUNCTIONS _________________________________________________________
63  *
64  */
65 BOOL ShowSalvageDlg(HWND hParent, LPCTSTR pszPartitionName)
66 {       
67         ASSERT(pszPartitionName);
68
69         lstrcpy(szPartitionName, pszPartitionName);
70
71         int nResult = ModalDialog(IDD_SALVAGE, hParent, (DLGPROC)SalvageDlgProc);
72
73     if (nResult != IDOK)
74         return FALSE;
75
76         // Create a thread to perform the salvage
77         DWORD dwThreadID;
78         g_CfgData.hSalvageThread = CreateThread(0, 0, Salvage, 0, 0, &dwThreadID);
79
80         return (g_CfgData.hSalvageThread != 0);
81 }
82
83
84 /*
85  * Dialog Proc _________________________________________________________________
86  *
87  */
88 BOOL CALLBACK SalvageDlgProc(HWND hwndDlg, UINT msg, WPARAM wp, LPARAM lp)
89 {
90         if (AfsAppLib_HandleHelp(IDD_SALVAGE, hwndDlg, msg, wp, lp))
91                 return TRUE;
92
93         switch (msg) {
94                 case WM_INITDIALOG:
95                         OnInitDialog(hwndDlg);
96                         break;
97
98                 case WM_COMMAND:
99                         switch (LOWORD(wp)) {
100                                 case IDC_VOLUME_NAME:
101                                 case IDC_NUM_PROCESSES:
102                                 case IDC_LOG_FILE:
103                                 case IDC_TEMP_DIR:
104                                         if (HIWORD(wp) == EN_CHANGE)
105                                                 UpdateControls();
106                                         break;
107
108                                 case IDC_SERVER:
109                                 case IDC_PARTITION:
110                                 case IDC_VOLUME:
111                                 case IDC_NUM_PROCESSES_CHECKBOX:
112                                         UpdateControls();
113                                         break;
114
115                                 case IDC_ADVANCED:
116                                         OnAdvanced();
117                                         break;
118
119                                 case IDCANCEL:
120                                         EndDialog(hDlg, IDCANCEL);
121                                         break;
122
123                                 case IDOK:
124                     if (OnSalvage())
125                                                 EndDialog(hDlg, IDOK);
126                                         break;
127                         }
128                 break;
129     }
130
131     return FALSE;
132 }
133
134
135 /*
136  * STATIC FUNCTIONS _________________________________________________________________
137  *
138  */
139
140 /*
141  * Event Handler Functions _________________________________________________________________
142  *
143  */
144 static void OnInitDialog(HWND hwndDlg)
145 {
146         hDlg = hwndDlg;
147
148         bAdvanced = TRUE;
149
150         TCHAR szNumProcesses[32];
151         _itot(DEFAULT_NUM_PROCESSES, szNumProcesses, 10);
152
153         SetWndText(hDlg, IDC_NUM_PROCESSES, szNumProcesses);
154         SetCheck(hDlg, IDC_NUM_PROCESSES_CHECKBOX);
155         SetWndText(hDlg, IDC_LOG_FILE, A2S(DEFAULT_LOG_FILE));
156
157         // If a partition name isn't selected, then only allow the salvage server option
158         if (szPartitionName[0] == 0) {
159                 SetEnable(hDlg, IDC_PARTITION, ES_DISABLE);
160                 SetEnable(hDlg, IDC_VOLUME, ES_DISABLE);
161                 SetCheck(hDlg, IDC_SERVER);
162         } else
163                 SetCheck(hDlg, IDC_PARTITION);
164         
165         // Close the Advanced portion of the dialog
166         OnAdvanced();
167 }
168
169 static void OnAdvanced()
170 {
171     static int nOffset = 0;
172
173         bAdvanced = !bAdvanced;
174
175         ShowAndEnable(hDlg, IDC_ADVANCED_FRAME, bAdvanced);     
176         ShowAndEnable(hDlg, IDC_LOG_FILE, bAdvanced);
177         ShowAndEnable(hDlg, IDC_LOG_FILE_LABEL, bAdvanced);
178         ShowAndEnable(hDlg, IDC_NUM_PROCESSES, bAdvanced);
179         ShowAndEnable(hDlg, IDC_TEMP_DIR, bAdvanced);
180         ShowAndEnable(hDlg, IDC_TEMP_DIR_LABEL, bAdvanced);
181         ShowAndEnable(hDlg, IDC_NUM_PROCESSES_CHECKBOX, bAdvanced);
182         ShowAndEnable(hDlg, IDC_DAMAGED_VOLUMES, bAdvanced);
183         ShowAndEnable(hDlg, IDC_SMALL_BLOCK_READS, bAdvanced);
184         ShowAndEnable(hDlg, IDC_FORCE_SALVAGE, bAdvanced);
185         ShowAndEnable(hDlg, IDC_FORCE_REBUILD, bAdvanced);
186         ShowAndEnable(hDlg, IDC_LIST_DAMAGED_INODES, bAdvanced);
187         ShowAndEnable(hDlg, IDC_LIST_OWNED_INDOES, bAdvanced);
188
189     // To show or hide the advanced section, we have to resize the dialog
190
191     // Get current position of the dialog
192     RECT rectDlg;
193     GetWindowRect(hDlg, &rectDlg);
194
195     // Figure out offset between full dialog and short dialog
196     if (nOffset == 0) {
197         // Find the frame containing the things we will hide or show
198         HWND hFrame = GetDlgItem(hDlg, IDC_ADVANCED_FRAME);
199     
200         // Get its dimensions
201         RECT rectFrame;
202         GetWindowRect(hFrame, &rectFrame);
203
204         // Find the distance between the bottom of the dialog and the top of the frame    
205         nOffset = rectDlg.bottom - rectFrame.top - 3;
206     }
207
208         int nCurOffset = nOffset;
209
210     if (!bAdvanced)
211                 nCurOffset *= -1;
212         
213     // Adjust dialog position
214         MoveWindow(hDlg, rectDlg.left, rectDlg.top, rectDlg.right - rectDlg.left, rectDlg.bottom - rectDlg.top + nCurOffset, TRUE);
215
216         SetWndText(hDlg, IDC_ADVANCED, bAdvanced ? IDS_ADVANCED_OPEN : IDS_ADVANCED_CLOSED);
217 }
218
219 static void UpdateControls()
220 {
221         // Update volume name controls
222         BOOL bVolume = IsButtonChecked(hDlg, IDC_VOLUME);
223         ENABLE_STATE es = bVolume ? ES_ENABLE : ES_DISABLE;
224         SetEnable(hDlg, IDC_VOLUME_NAME, es);
225         SetEnable(hDlg, IDC_VOLUME_NAME_LABEL, es);
226         GetWndText(hDlg, IDC_VOLUME_NAME, szVolumeName);
227
228         // Num processes edit control
229         BOOL bParallel = IsButtonChecked(hDlg, IDC_NUM_PROCESSES_CHECKBOX);
230         SetEnable(hDlg, IDC_NUM_PROCESSES, (ENABLE_STATE)bParallel);
231         GetWndText(hDlg, IDC_NUM_PROCESSES, szNumProcesses, NUM_PROCS_BUF_SIZE);
232
233         GetWndText(hDlg, IDC_LOG_FILE, g_CfgData.szSalvageLogFileName, _MAX_PATH);
234         GetWndText(hDlg, IDC_TEMP_DIR, szTempDir, _MAX_PATH);
235
236         // Should OK button be enabled or disabled?
237         BOOL bEnable = TRUE;
238
239         if (bVolume)
240                 bEnable = !!lstrlen(szVolumeName);
241
242         if (bEnable && bParallel)
243                 bEnable = !!lstrlen(szNumProcesses);
244
245         SetEnable(hDlg, IDOK, (ENABLE_STATE)bEnable);
246 }
247
248 /*
249  * Utility Functions _________________________________________________________________
250  *
251  */
252 static BOOL OnSalvage()
253 {
254         if (IsButtonChecked(hDlg, IDC_SERVER)) {
255                 pszPartitionName = 0;
256                 pszVolumeName = 0;
257         } else if (IsButtonChecked(hDlg, IDC_PARTITION)) {
258                 pszPartitionName = szPartitionName;
259                 pszVolumeName = 0;
260         } else if (IsButtonChecked(hDlg, IDC_VOLUME)) {
261                 pszPartitionName = szPartitionName;
262                 pszVolumeName = szVolumeName;
263         }
264
265         nNumProcesses = DEFAULT_NUM_PROCESSES;
266         if (IsButtonChecked(hDlg, IDC_NUM_PROCESSES_CHECKBOX)) {
267                 nNumProcesses = _ttoi(szNumProcesses);
268                 if ((nNumProcesses < MIN_NUM_PROCESSES) || (nNumProcesses > MAX_NUM_PROCESSES)) {
269                         ShowError(hDlg, 0, IDS_INVALID_NUM_SALVAGE_PROCESSSES);
270                         return FALSE;
271                 }
272         }
273
274         if (!g_CfgData.bReuseAdminInfo) {
275         if (!GetAdminInfo(hDlg, GAIO_LOGIN_ONLY))
276                 return FALSE;
277
278         if (!GetHandles(hDlg))
279             return FALSE;
280     }
281
282         return TRUE;
283 }
284
285 static DWORD WINAPI Salvage(LPVOID param)
286 {
287         afs_status_t nStatus;
288         void *hServer;
289         int nResult; 
290
291         nResult = bos_ServerOpen(g_hCell, GetHostnameA(), &hServer, &nStatus);
292         if (!nResult) {
293                 ShowError(hDlg, nStatus, IDS_BOS_OPEN_FAILED);
294                 return FALSE;
295         }
296
297         nResult = bos_Salvage(g_hCell, hServer, S2A(pszPartitionName), S2A(pszVolumeName), nNumProcesses, S2A(szTempDir), 0, VOS_NORMAL,
298                                                                 BOS_SALVAGE_DAMAGED_VOLUMES, BOS_SALVAGE_DONT_WRITE_INODES, BOS_SALVAGE_DONT_WRITE_ROOT_INODES,
299                                                                 BOS_SALVAGE_DONT_FORCE_DIRECTORIES, BOS_SALVAGE_DONT_FORCE_BLOCK_READS, &nStatus);
300         if (!nResult)
301         ShowError(hDlg, nStatus, IDS_SALVAGE_ERROR);
302
303     bos_ServerClose(hServer, &nStatus);
304     
305     g_CfgData.bReuseAdminInfo = nResult;
306
307         return nResult;
308 }
309