2 * Copyright 2000, International Business Machines Corporation and others.
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
11 * INCLUDES _________________________________________________________________
15 #include <afs/param.h>
21 #include "create_partition_dlg.h"
22 #include "partition_utils.h"
23 #include "salvage_results_dlg.h"
25 #include <afs\afs_vosAdmin.h>
26 #include <afs\afs_clientAdmin.h>
30 // TODO: Add context menu to fastlist
34 * DEFINITIONS _________________________________________________________________
37 #define MAX_PARTITIONS 26
40 static HWND hPartitionList = 0;
41 static HLISTITEM hSelectedItem;
43 static TCHAR szYes[cchRESOURCE];
44 static TCHAR szNo[cchRESOURCE];
46 static const UINT DISK_DRIVE_IMAGE = 0;
47 //static const UINT DISABLED_DISK_DRIVE_IMAGE = 1;
48 //static const UINT DISK_DRIVE_WITH_WARNING_IMAGE = 2;
50 // Remember the config state of the FS so we can detect when it changes.
51 // When it changes we must redisplay the partition info.
52 static CONFIG_STATE configFS;
57 * PROTOTYPES _________________________________________________________________
60 BOOL ShowSalvageDlg(HWND hParent, LPCTSTR pszPartitionName);
62 static void OnCreatePartitions();
63 static void OnInitDialog(HWND hwndDlg);
64 static void SetupListCols();
65 static void AddColumn(int nWidth, LPCTSTR pszTitle, DWORD dwFlags = FLCF_JUSTIFY_LEFT);
66 static void ShowPartitions();
67 cfg_partitionEntry_t *GetPartitionTableFromRegistry(int& cEntries);
68 static vos_partitionEntry_t *GetPartitionTableFromVos(int &nNumPartitions);
69 static void OnListSelection(LPFLN_ITEMSELECT_PARAMS pItemParms);
70 static void SetupImageLists();
71 static void OnRemove();
72 static BOOL CheckShowPartitions();
73 static void OnSalvage();
74 static void CheckEnableSalvage();
78 * EXPORTED FUNCTIONS _________________________________________________________________
82 * Dialog Proc _________________________________________________________________
85 BOOL CALLBACK PartitionsPageDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
87 if (AfsAppLib_HandleHelp(IDD_PARTITIONS_PAGE, hwndDlg, uMsg, wParam, lParam))
91 case WM_INITDIALOG: OnInitDialog(hwndDlg);
94 case WM_COMMAND: switch (LOWORD(wParam)) {
95 case IDINIT: CheckShowPartitions();
98 case IDC_CREATE_PARTITIONS:
102 case IDC_REMOVE: OnRemove();
105 case IDC_SALVAGE: OnSalvage();
110 case WM_NOTIFY: if ((((LPNMHDR)lParam)->code) == FLN_ITEMSELECT)
111 OnListSelection((LPFLN_ITEMSELECT_PARAMS)lParam);
118 void UpdatePartitionList()
121 CheckEnableSalvage();
126 * STATIC FUNCTIONS _________________________________________________________________
131 * Event Handler Functions _________________________________________________________________
134 static void OnInitDialog(HWND hwndDlg)
138 // PropSheet_CancelToClose(GetParent(hDlg));
142 hPartitionList = GetDlgItem(hDlg, IDC_PARTITION_LIST);
143 _ASSERTE(hPartitionList);
147 GetString(szYes, IDS_YES);
148 GetString(szNo, IDS_NO);
152 configFS = g_CfgData.configFS;
156 CheckEnableSalvage();
159 static void OnCreatePartitions()
161 if (CreatePartition(hDlg))
165 static void OnListSelection(LPFLN_ITEMSELECT_PARAMS pItemParms)
169 hSelectedItem = pItemParms->hItem;
171 ENABLE_STATE es = pItemParms->hItem ? ES_ENABLE : ES_DISABLE;
173 SetEnable(hDlg, IDC_REMOVE, es);
174 SetEnable(hDlg, IDC_REMOVE_MSG, es);
177 static void OnRemove()
179 ASSERT(hSelectedItem);
182 afs_status_t nStatus;
184 BOOL bExported = (BOOL)FastList_GetItemParam(hPartitionList, hSelectedItem);
186 MsgBox(hDlg, IDS_CANT_DELETE_EXPORTED_PARTITION, GetAppTitleID(), MB_OK | MB_ICONSTOP);
190 LPCTSTR pszPartitionName = FastList_GetItemText(hPartitionList, hSelectedItem, 0);
191 ASSERT(pszPartitionName);
193 int nResult = Message(MB_ICONQUESTION | MB_YESNO, GetAppTitleID(), IDS_DELETE_PARTITION_PROMPT, TEXT("%s"), pszPartitionName);
197 g_LogFile.Write("Removing partition '%s'.\r\n", (char *)S2A(pszPartitionName));
198 nResult = cfg_HostPartitionTableRemoveEntry(g_hServer, S2A(pszPartitionName), &nStatus);
200 ShowError(hDlg, nStatus, IDS_REMOVE_PARTITION_ERROR);
204 FastList_RemoveItem(hPartitionList, hSelectedItem);
206 CheckEnableSalvage();
209 static void OnSalvage()
211 // Can't salvage if the file server is not configured
212 if (!Configured(g_CfgData.configFS)) {
213 ShowError(hDlg, 0, IDS_CANT_SALVAGE_WHEN_FS_NOT_CONFIGURED);
217 LPCTSTR pszPartitionName = TEXT("");
220 pszPartitionName = FastList_GetItemText(hPartitionList, hSelectedItem, 0);
221 ASSERT(pszPartitionName);
224 if (!ShowSalvageDlg(hDlg, pszPartitionName))
227 ShowSalvageResults(hDlg);
229 // Since a salvage was performed, there may be partitions exported that were
230 // not exported before the salvage. Salvage may stop and restart the file
231 // server, which will pick up the previously unexported partitions. We will
232 // update our partition list in case this has happened.
233 UpdatePartitionList();
238 * Utility Functions _________________________________________________________________
241 static BOOL CheckShowPartitions()
243 if (configFS != g_CfgData.configFS) {
244 configFS = g_CfgData.configFS;
245 UpdatePartitionList();
252 static void SetupImageLists()
254 HIMAGELIST hiList = ImageList_Create(16, 16, TRUE, 1, 1);
256 AfsAppLib_AddToImageList(hiList, IDI_AGGREGATE, FALSE);
257 AfsAppLib_AddToImageList(hiList, IDI_DISABLED_DISK_DRIVE, FALSE);
259 FastList_SetImageLists(hPartitionList, hiList, 0);
262 static void AddColumn(int nWidth, LPCTSTR pszTitle, DWORD dwFlags)
267 col.dwFlags = dwFlags;
268 col.cxWidth = nWidth;
269 lstrcpy(col.szText, pszTitle);
271 FastList_SetColumn(hPartitionList, nCol++, &col);
274 static void SetupListCols()
276 TCHAR szMsg[cchRESOURCE];
278 AddColumn(75, GetResString(IDS_NAME, szMsg));
279 AddColumn(55, GetResString(IDS_DRIVE, szMsg));
280 AddColumn(60, GetResString(IDS_EXPORTED, szMsg));
281 AddColumn(75, GetResString(IDS_TOTAL, szMsg), FLCF_JUSTIFY_RIGHT);
282 AddColumn(75, GetResString(IDS_FREE, szMsg), FLCF_JUSTIFY_RIGHT);
285 cfg_partitionEntry_t *GetPartitionTableFromRegistry(int& cEntries)
287 afs_status_t nStatus;
289 // Read the parition table out of the registry
290 int nResult = ReadPartitionTable(&nStatus);
292 ShowError(hDlg, nStatus, IDS_READ_PARTITIONS_ERROR);
296 return GetPartitionTable(cEntries);
299 static vos_partitionEntry_t *GetPartitionTableFromVos(int &nNumPartitions)
302 ASSERT(g_CfgData.szHostname[0]);
306 if (g_CfgData.configFS != CS_ALREADY_CONFIGURED)
309 static vos_partitionEntry_t aPartitions[MAX_PARTITIONS];
310 afs_status_t nStatus, nIgnore;
315 g_LogFile.Write("Opening server %s.\r\n", GetHostnameA());
316 int nResult = vos_ServerOpen(g_hCell, GetHostnameA(), &hServer, &nStatus);
319 // Read the partition info
320 g_LogFile.Write("Reading paritition information for this server.\r\n");
323 nResult = vos_PartitionGetBegin(g_hCell, hServer, 0, &iterID, &nStatus);
325 while (nNumParts < MAX_PARTITIONS) {
326 nResult = vos_PartitionGetNext(iterID, &aPartitions[nNumParts], &nStatus);
328 if (nStatus == ADMITERATORDONE) {
337 vos_PartitionGetDone(iterID, &nIgnore);
339 vos_ServerClose(hServer, &nIgnore);
343 ShowError(hDlg, nStatus, IDS_GET_PARTITION_LIST_ERROR);
347 nNumPartitions = nNumParts;
352 // Convert a disk space value in Kbytes into a string
353 static LPTSTR DiskSpaceToString(int nSpace)
355 const float oneMB = 1024; // in K bytes
356 const double oneGB = oneMB * 1024;
357 const double oneTB = oneGB * 1024;
359 static TCHAR szSpace[64];
365 if (space >= oneTB) {
367 pszUnits = TEXT(" TB");
368 } else if (space >= oneGB) {
370 pszUnits = TEXT(" GB");
371 } else if (space >= oneMB) {
373 pszUnits = TEXT(" MB");
375 pszUnits = TEXT(" KB");
377 int nNumDecimals = 0;
378 if (space - double(int(space)) > 0)
381 _stprintf(szSpace, TEXT("%3.*f%s"), nNumDecimals, space, pszUnits);
386 static void ShowPartitions()
388 FastList_RemoveAll(hPartitionList);
390 int cRegParts = 0, cVosParts = 0;
392 // If we got nothing from the registry, then leave the list empty
393 cfg_partitionEntry_t *pRegParts = GetPartitionTableFromRegistry(cRegParts);
397 // If we failed to get vos info, then only show the registry info
398 vos_partitionEntry_t *pVosParts = GetPartitionTableFromVos(cVosParts);
402 // We have two partition tables, one from the registry and one from the vos
403 // library. The one from the vos library tells us the partitions that are
404 // currently exported. The one from the registry tells us the partitions
405 // that will be exported after the file server restarts. The registry list
406 // should always be at least as big as the vos list. The vos list can be
407 // smaller if one of the disks could not be exported. To add a new partition,
408 // an entry must be added to the registry table and then the file server must
409 // be restarted. To remove an entry, the partition must not be exported (due
410 // to an error) or the file server must not be running, in which case nothing
413 // To display the partitions to the user, we use the list from the registry,
414 // looking up each of its entries in the vos list to see if it is exported,
415 // and if it is, to get its size info.
418 for (int nCurRegPart = 0; nCurRegPart < cRegParts; nCurRegPart++) {
419 LPTSTR pPartNameAsString = AnsiToString(pRegParts[nCurRegPart].partitionName);
421 // Show the partition in the list
422 FASTLISTADDITEM ai = { 0, DISK_DRIVE_IMAGE, IMAGE_NOIMAGE, pPartNameAsString, 0, 0 };
423 HLISTITEM hItem = FastList_AddItem(hPartitionList, &ai);
425 FreeString(pPartNameAsString);
427 FastList_SetItemText(hPartitionList, hItem, 1, pRegParts[nCurRegPart].deviceName);
429 // For the rest of the info we need to know if this guy is exported.
430 // Look him up in the vos table.
431 BOOL bExported = FALSE;
435 for (int nCurVosPart = 0; nCurVosPart < cVosParts; nCurVosPart++) {
436 if (stricmp(pVosParts[nCurVosPart].name, pRegParts[nCurRegPart].partitionName) == 0) {
438 nTotalSpace = pVosParts[nCurVosPart].totalSpace;
439 nFreeSpace = pVosParts[nCurVosPart].totalFreeSpace;
444 FastList_SetItemText(hPartitionList, hItem, 2, bExported ? szYes : szNo);
445 FastList_SetItemText(hPartitionList, hItem, 3, bExported ? DiskSpaceToString(nTotalSpace) : TEXT(""));
446 FastList_SetItemText(hPartitionList, hItem, 4, bExported ? DiskSpaceToString(nFreeSpace) : TEXT(""));
448 // Set the item param to indicate that this partition is exported or not
449 FastList_SetItemParam(hPartitionList, hItem, bExported);
455 static void CheckEnableSalvage()
457 ENABLE_STATE es = (FastList_GetItemCount(hPartitionList) > 0) ? ES_ENABLE : ES_DISABLE;
459 SetEnable(hDlg, IDC_SALVAGE, es);
460 SetEnable(hDlg, IDC_SALVAGE_MSG, es);