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 _________________________________________________________________
18 #include <afsconfig.h>
19 #include <afs/param.h>
26 #include "create_partition_dlg.h"
27 #include "partition_utils.h"
28 #include "salvage_results_dlg.h"
30 #include <afs\afs_vosAdmin.h>
31 #include <afs\afs_clientAdmin.h>
35 // TODO: Add context menu to fastlist
39 * DEFINITIONS _________________________________________________________________
42 #define MAX_PARTITIONS 26
45 static HWND hPartitionList = 0;
46 static HLISTITEM hSelectedItem;
48 static TCHAR szYes[cchRESOURCE];
49 static TCHAR szNo[cchRESOURCE];
51 static const UINT DISK_DRIVE_IMAGE = 0;
52 //static const UINT DISABLED_DISK_DRIVE_IMAGE = 1;
53 //static const UINT DISK_DRIVE_WITH_WARNING_IMAGE = 2;
55 // Remember the config state of the FS so we can detect when it changes.
56 // When it changes we must redisplay the partition info.
57 static CONFIG_STATE configFS;
62 * PROTOTYPES _________________________________________________________________
65 BOOL ShowSalvageDlg(HWND hParent, LPCTSTR pszPartitionName);
67 static void OnCreatePartitions();
68 static void OnInitDialog(HWND hwndDlg);
69 static void SetupListCols();
70 static void AddColumn(int nWidth, LPCTSTR pszTitle, DWORD dwFlags = FLCF_JUSTIFY_LEFT);
71 static void ShowPartitions();
72 cfg_partitionEntry_t *GetPartitionTableFromRegistry(int& cEntries);
73 static vos_partitionEntry_t *GetPartitionTableFromVos(int &nNumPartitions);
74 static void OnListSelection(LPFLN_ITEMSELECT_PARAMS pItemParms);
75 static void SetupImageLists();
76 static void OnRemove();
77 static BOOL CheckShowPartitions();
78 static void OnSalvage();
79 static void CheckEnableSalvage();
83 * EXPORTED FUNCTIONS _________________________________________________________________
87 * Dialog Proc _________________________________________________________________
90 BOOL CALLBACK PartitionsPageDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
92 if (AfsAppLib_HandleHelp(IDD_PARTITIONS_PAGE, hwndDlg, uMsg, wParam, lParam))
97 OnInitDialog(hwndDlg);
101 switch (LOWORD(wParam)) {
103 CheckShowPartitions();
106 case IDC_CREATE_PARTITIONS:
107 OnCreatePartitions();
121 if ((((LPNMHDR)lParam)->code) == FLN_ITEMSELECT)
122 OnListSelection((LPFLN_ITEMSELECT_PARAMS)lParam);
129 void UpdatePartitionList()
132 CheckEnableSalvage();
137 * STATIC FUNCTIONS _________________________________________________________________
142 * Event Handler Functions _________________________________________________________________
145 static void OnInitDialog(HWND hwndDlg)
149 // PropSheet_CancelToClose(GetParent(hDlg));
153 hPartitionList = GetDlgItem(hDlg, IDC_PARTITION_LIST);
154 _ASSERTE(hPartitionList);
158 GetString(szYes, IDS_YES);
159 GetString(szNo, IDS_NO);
163 configFS = g_CfgData.configFS;
167 CheckEnableSalvage();
170 static void OnCreatePartitions()
172 if (CreatePartition(hDlg))
176 static void OnListSelection(LPFLN_ITEMSELECT_PARAMS pItemParms)
180 hSelectedItem = pItemParms->hItem;
182 ENABLE_STATE es = pItemParms->hItem ? ES_ENABLE : ES_DISABLE;
184 SetEnable(hDlg, IDC_REMOVE, es);
185 SetEnable(hDlg, IDC_REMOVE_MSG, es);
188 static void OnRemove()
190 ASSERT(hSelectedItem);
193 afs_status_t nStatus;
195 BOOL bExported = (BOOL)FastList_GetItemParam(hPartitionList, hSelectedItem);
197 MsgBox(hDlg, IDS_CANT_DELETE_EXPORTED_PARTITION, GetAppTitleID(), MB_OK | MB_ICONSTOP);
201 LPCTSTR pszPartitionName = FastList_GetItemText(hPartitionList, hSelectedItem, 0);
202 ASSERT(pszPartitionName);
204 int nResult = Message(MB_ICONQUESTION | MB_YESNO, GetAppTitleID(), IDS_DELETE_PARTITION_PROMPT, TEXT("%s"), pszPartitionName);
208 g_LogFile.Write("Removing partition '%s'.\r\n", (char *)S2A(pszPartitionName));
209 nResult = cfg_HostPartitionTableRemoveEntry(g_hServer, S2A(pszPartitionName), &nStatus);
211 ShowError(hDlg, nStatus, IDS_REMOVE_PARTITION_ERROR);
215 FastList_RemoveItem(hPartitionList, hSelectedItem);
217 CheckEnableSalvage();
220 static void OnSalvage()
222 // Can't salvage if the file server is not configured
223 if (!Configured(g_CfgData.configFS)) {
224 ShowError(hDlg, 0, IDS_CANT_SALVAGE_WHEN_FS_NOT_CONFIGURED);
228 LPCTSTR pszPartitionName = TEXT("");
231 pszPartitionName = FastList_GetItemText(hPartitionList, hSelectedItem, 0);
232 ASSERT(pszPartitionName);
235 if (!ShowSalvageDlg(hDlg, pszPartitionName))
238 ShowSalvageResults(hDlg);
240 // Since a salvage was performed, there may be partitions exported that were
241 // not exported before the salvage. Salvage may stop and restart the file
242 // server, which will pick up the previously unexported partitions. We will
243 // update our partition list in case this has happened.
244 UpdatePartitionList();
249 * Utility Functions _________________________________________________________________
252 static BOOL CheckShowPartitions()
254 if (configFS != g_CfgData.configFS) {
255 configFS = g_CfgData.configFS;
256 UpdatePartitionList();
263 static void SetupImageLists()
265 HIMAGELIST hiList = ImageList_Create(16, 16, TRUE, 1, 1);
267 AfsAppLib_AddToImageList(hiList, IDI_AGGREGATE, FALSE);
268 AfsAppLib_AddToImageList(hiList, IDI_DISABLED_DISK_DRIVE, FALSE);
270 FastList_SetImageLists(hPartitionList, hiList, 0);
273 static void AddColumn(int nWidth, LPCTSTR pszTitle, DWORD dwFlags)
278 col.dwFlags = dwFlags;
279 col.cxWidth = nWidth;
280 lstrcpy(col.szText, pszTitle);
282 FastList_SetColumn(hPartitionList, nCol++, &col);
285 static void SetupListCols()
287 TCHAR szMsg[cchRESOURCE];
289 AddColumn(75, GetResString(IDS_NAME, szMsg));
290 AddColumn(55, GetResString(IDS_DRIVE, szMsg));
291 AddColumn(60, GetResString(IDS_EXPORTED, szMsg));
292 AddColumn(75, GetResString(IDS_TOTAL, szMsg), FLCF_JUSTIFY_RIGHT);
293 AddColumn(75, GetResString(IDS_FREE, szMsg), FLCF_JUSTIFY_RIGHT);
296 cfg_partitionEntry_t *GetPartitionTableFromRegistry(int& cEntries)
298 afs_status_t nStatus;
300 // Read the parition table out of the registry
301 int nResult = ReadPartitionTable(&nStatus);
303 ShowError(hDlg, nStatus, IDS_READ_PARTITIONS_ERROR);
307 return GetPartitionTable(cEntries);
310 static vos_partitionEntry_t *GetPartitionTableFromVos(int &nNumPartitions)
313 ASSERT(g_CfgData.szHostname[0]);
317 if (g_CfgData.configFS != CS_ALREADY_CONFIGURED)
320 static vos_partitionEntry_t aPartitions[MAX_PARTITIONS];
321 afs_status_t nStatus, nIgnore;
326 g_LogFile.Write("Opening server %s.\r\n", GetHostnameA());
327 int nResult = vos_ServerOpen(g_hCell, GetHostnameA(), &hServer, &nStatus);
330 // Read the partition info
331 g_LogFile.Write("Reading paritition information for this server.\r\n");
334 nResult = vos_PartitionGetBegin(g_hCell, hServer, 0, &iterID, &nStatus);
336 while (nNumParts < MAX_PARTITIONS) {
337 nResult = vos_PartitionGetNext(iterID, &aPartitions[nNumParts], &nStatus);
339 if (nStatus == ADMITERATORDONE) {
348 vos_PartitionGetDone(iterID, &nIgnore);
350 vos_ServerClose(hServer, &nIgnore);
354 ShowError(hDlg, nStatus, IDS_GET_PARTITION_LIST_ERROR);
358 nNumPartitions = nNumParts;
363 // Convert a disk space value in Kbytes into a string
364 static LPTSTR DiskSpaceToString(int nSpace)
366 const float oneMB = 1024; // in K bytes
367 const double oneGB = oneMB * 1024;
368 const double oneTB = oneGB * 1024;
370 static TCHAR szSpace[64];
376 if (space >= oneTB) {
378 pszUnits = TEXT(" TB");
379 } else if (space >= oneGB) {
381 pszUnits = TEXT(" GB");
382 } else if (space >= oneMB) {
384 pszUnits = TEXT(" MB");
386 pszUnits = TEXT(" KB");
388 int nNumDecimals = 0;
389 if (space - double(int(space)) > 0)
392 _stprintf(szSpace, TEXT("%3.*f%s"), nNumDecimals, space, pszUnits);
397 static void ShowPartitions()
399 FastList_RemoveAll(hPartitionList);
401 int cRegParts = 0, cVosParts = 0;
403 // If we got nothing from the registry, then leave the list empty
404 cfg_partitionEntry_t *pRegParts = GetPartitionTableFromRegistry(cRegParts);
408 // If we failed to get vos info, then only show the registry info
409 vos_partitionEntry_t *pVosParts = GetPartitionTableFromVos(cVosParts);
413 // We have two partition tables, one from the registry and one from the vos
414 // library. The one from the vos library tells us the partitions that are
415 // currently exported. The one from the registry tells us the partitions
416 // that will be exported after the file server restarts. The registry list
417 // should always be at least as big as the vos list. The vos list can be
418 // smaller if one of the disks could not be exported. To add a new partition,
419 // an entry must be added to the registry table and then the file server must
420 // be restarted. To remove an entry, the partition must not be exported (due
421 // to an error) or the file server must not be running, in which case nothing
424 // To display the partitions to the user, we use the list from the registry,
425 // looking up each of its entries in the vos list to see if it is exported,
426 // and if it is, to get its size info.
429 for (int nCurRegPart = 0; nCurRegPart < cRegParts; nCurRegPart++) {
430 LPTSTR pPartNameAsString = AnsiToString(pRegParts[nCurRegPart].partitionName);
432 // Show the partition in the list
433 FASTLISTADDITEM ai = { 0, DISK_DRIVE_IMAGE, IMAGE_NOIMAGE, pPartNameAsString, 0, 0 };
434 HLISTITEM hItem = FastList_AddItem(hPartitionList, &ai);
436 FreeString(pPartNameAsString);
438 FastList_SetItemText(hPartitionList, hItem, 1, pRegParts[nCurRegPart].deviceName);
440 // For the rest of the info we need to know if this guy is exported.
441 // Look him up in the vos table.
442 BOOL bExported = FALSE;
446 for (int nCurVosPart = 0; nCurVosPart < cVosParts; nCurVosPart++) {
447 if (stricmp(pVosParts[nCurVosPart].name, pRegParts[nCurRegPart].partitionName) == 0) {
449 nTotalSpace = pVosParts[nCurVosPart].totalSpace;
450 nFreeSpace = pVosParts[nCurVosPart].totalFreeSpace;
455 FastList_SetItemText(hPartitionList, hItem, 2, bExported ? szYes : szNo);
456 FastList_SetItemText(hPartitionList, hItem, 3, bExported ? DiskSpaceToString(nTotalSpace) : TEXT(""));
457 FastList_SetItemText(hPartitionList, hItem, 4, bExported ? DiskSpaceToString(nFreeSpace) : TEXT(""));
459 // Set the item param to indicate that this partition is exported or not
460 FastList_SetItemParam(hPartitionList, hItem, bExported);
464 static void CheckEnableSalvage()
466 ENABLE_STATE es = (FastList_GetItemCount(hPartitionList) > 0) ? ES_ENABLE : ES_DISABLE;
468 SetEnable(hDlg, IDC_SALVAGE, es);
469 SetEnable(hDlg, IDC_SALVAGE_MSG, es);