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;
49 // Remember the config state of the FS so we can detect when it changes.
50 // When it changes we must redisplay the partition info.
51 static CONFIG_STATE configFS;
56 * PROTOTYPES _________________________________________________________________
59 BOOL ShowSalvageDlg(HWND hParent, LPCTSTR pszPartitionName);
61 static void OnCreatePartitions();
62 static void OnInitDialog(HWND hwndDlg);
63 static void SetupListCols();
64 static void AddColumn(int nWidth, LPCTSTR pszTitle, DWORD dwFlags = FLCF_JUSTIFY_LEFT);
65 static void ShowPartitions();
66 cfg_partitionEntry_t *GetPartitionTableFromRegistry(int& cEntries);
67 static vos_partitionEntry_t *GetPartitionTableFromVos(int &nNumPartitions);
68 static void OnListSelection(LPFLN_ITEMSELECT_PARAMS pItemParms);
69 static void SetupImageLists();
70 static void OnRemove();
71 static BOOL CheckShowPartitions();
72 static void OnSalvage();
73 static void CheckEnableSalvage();
77 * EXPORTED FUNCTIONS _________________________________________________________________
81 * Dialog Proc _________________________________________________________________
84 BOOL CALLBACK PartitionsPageDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
86 if (AfsAppLib_HandleHelp(IDD_PARTITIONS_PAGE, hwndDlg, uMsg, wParam, lParam))
90 case WM_INITDIALOG: OnInitDialog(hwndDlg);
93 case WM_COMMAND: switch (LOWORD(wParam)) {
94 case IDINIT: CheckShowPartitions();
97 case IDC_CREATE_PARTITIONS:
101 case IDC_REMOVE: OnRemove();
104 case IDC_SALVAGE: OnSalvage();
109 case WM_NOTIFY: if ((((LPNMHDR)lParam)->code) == FLN_ITEMSELECT)
110 OnListSelection((LPFLN_ITEMSELECT_PARAMS)lParam);
117 void UpdatePartitionList()
120 CheckEnableSalvage();
125 * STATIC FUNCTIONS _________________________________________________________________
130 * Event Handler Functions _________________________________________________________________
133 static void OnInitDialog(HWND hwndDlg)
137 // PropSheet_CancelToClose(GetParent(hDlg));
141 hPartitionList = GetDlgItem(hDlg, IDC_PARTITION_LIST);
142 _ASSERTE(hPartitionList);
146 GetString(szYes, IDS_YES);
147 GetString(szNo, IDS_NO);
151 configFS = g_CfgData.configFS;
155 CheckEnableSalvage();
158 static void OnCreatePartitions()
160 if (CreatePartition(hDlg))
164 static void OnListSelection(LPFLN_ITEMSELECT_PARAMS pItemParms)
168 hSelectedItem = pItemParms->hItem;
170 ENABLE_STATE es = pItemParms->hItem ? ES_ENABLE : ES_DISABLE;
172 SetEnable(hDlg, IDC_REMOVE, es);
173 SetEnable(hDlg, IDC_REMOVE_MSG, es);
176 static void OnRemove()
178 ASSERT(hSelectedItem);
181 afs_status_t nStatus;
183 BOOL bExported = (BOOL)FastList_GetItemParam(hPartitionList, hSelectedItem);
185 MsgBox(hDlg, IDS_CANT_DELETE_EXPORTED_PARTITION, GetAppTitleID(), MB_OK | MB_ICONSTOP);
189 LPCTSTR pszPartitionName = FastList_GetItemText(hPartitionList, hSelectedItem, 0);
190 ASSERT(pszPartitionName);
192 int nResult = Message(MB_ICONQUESTION | MB_YESNO, GetAppTitleID(), IDS_DELETE_PARTITION_PROMPT, TEXT("%s"), pszPartitionName);
196 g_LogFile.Write("Removing partition '%s'.\r\n", (char *)S2A(pszPartitionName));
197 nResult = cfg_HostPartitionTableRemoveEntry(g_hServer, S2A(pszPartitionName), &nStatus);
199 ShowError(hDlg, nStatus, IDS_REMOVE_PARTITION_ERROR);
203 FastList_RemoveItem(hPartitionList, hSelectedItem);
205 CheckEnableSalvage();
208 static void OnSalvage()
210 // Can't salvage if the file server is not configured
211 if (!Configured(g_CfgData.configFS)) {
212 ShowError(hDlg, 0, IDS_CANT_SALVAGE_WHEN_FS_NOT_CONFIGURED);
216 LPCTSTR pszPartitionName = TEXT("");
219 pszPartitionName = FastList_GetItemText(hPartitionList, hSelectedItem, 0);
220 ASSERT(pszPartitionName);
223 if (!ShowSalvageDlg(hDlg, pszPartitionName))
226 ShowSalvageResults(hDlg);
228 // Since a salvage was performed, there may be partitions exported that were
229 // not exported before the salvage. Salvage may stop and restart the file
230 // server, which will pick up the previously unexported partitions. We will
231 // update our partition list in case this has happened.
232 UpdatePartitionList();
237 * Utility Functions _________________________________________________________________
240 static BOOL CheckShowPartitions()
242 if (configFS != g_CfgData.configFS) {
243 configFS = g_CfgData.configFS;
244 UpdatePartitionList();
251 static void SetupImageLists()
253 HIMAGELIST hiList = ImageList_Create(16, 16, TRUE, 1, 1);
255 AfsAppLib_AddToImageList(hiList, IDI_AGGREGATE, FALSE);
256 AfsAppLib_AddToImageList(hiList, IDI_DISABLED_DISK_DRIVE, FALSE);
258 FastList_SetImageLists(hPartitionList, hiList, 0);
261 static void AddColumn(int nWidth, LPCTSTR pszTitle, DWORD dwFlags)
266 col.dwFlags = dwFlags;
267 col.cxWidth = nWidth;
268 lstrcpy(col.szText, pszTitle);
270 FastList_SetColumn(hPartitionList, nCol++, &col);
273 static void SetupListCols()
275 TCHAR szMsg[cchRESOURCE];
277 AddColumn(75, GetResString(IDS_NAME, szMsg));
278 AddColumn(55, GetResString(IDS_DRIVE, szMsg));
279 AddColumn(60, GetResString(IDS_EXPORTED, szMsg));
280 AddColumn(75, GetResString(IDS_TOTAL, szMsg), FLCF_JUSTIFY_RIGHT);
281 AddColumn(75, GetResString(IDS_FREE, szMsg), FLCF_JUSTIFY_RIGHT);
284 cfg_partitionEntry_t *GetPartitionTableFromRegistry(int& cEntries)
286 afs_status_t nStatus;
288 // Read the parition table out of the registry
289 int nResult = ReadPartitionTable(&nStatus);
291 ShowError(hDlg, nStatus, IDS_READ_PARTITIONS_ERROR);
295 return GetPartitionTable(cEntries);
298 static vos_partitionEntry_t *GetPartitionTableFromVos(int &nNumPartitions)
301 ASSERT(g_CfgData.szHostname[0]);
305 if (g_CfgData.configFS != CS_ALREADY_CONFIGURED)
308 static vos_partitionEntry_t aPartitions[MAX_PARTITIONS];
309 afs_status_t nStatus, nIgnore;
314 g_LogFile.Write("Opening server %s.\r\n", GetHostnameA());
315 int nResult = vos_ServerOpen(g_hCell, GetHostnameA(), &hServer, &nStatus);
318 // Read the partition info
319 g_LogFile.Write("Reading paritition information for this server.\r\n");
322 nResult = vos_PartitionGetBegin(g_hCell, hServer, 0, &iterID, &nStatus);
324 while (nNumParts < MAX_PARTITIONS) {
325 nResult = vos_PartitionGetNext(iterID, &aPartitions[nNumParts], &nStatus);
327 if (nStatus == ADMITERATORDONE) {
336 vos_PartitionGetDone(iterID, &nIgnore);
338 vos_ServerClose(hServer, &nIgnore);
342 ShowError(hDlg, nStatus, IDS_GET_PARTITION_LIST_ERROR);
346 nNumPartitions = nNumParts;
351 // Convert a disk space value in Kbytes into a string
352 static LPTSTR DiskSpaceToString(int nSpace)
354 const float oneMB = 1024; // in K bytes
355 const double oneGB = oneMB * 1024;
356 const double oneTB = oneGB * 1024;
358 static TCHAR szSpace[64];
364 if (space >= oneTB) {
366 pszUnits = TEXT(" TB");
367 } else if (space >= oneGB) {
369 pszUnits = TEXT(" GB");
370 } else if (space >= oneMB) {
372 pszUnits = TEXT(" MB");
374 pszUnits = TEXT(" KB");
376 int nNumDecimals = 0;
377 if (space - double(int(space)) > 0)
380 _stprintf(szSpace, TEXT("%3.*f%s"), nNumDecimals, space, pszUnits);
385 static void ShowPartitions()
387 FastList_RemoveAll(hPartitionList);
389 int cRegParts = 0, cVosParts = 0;
391 // If we got nothing from the registry, then leave the list empty
392 cfg_partitionEntry_t *pRegParts = GetPartitionTableFromRegistry(cRegParts);
396 // If we failed to get vos info, then only show the registry info
397 vos_partitionEntry_t *pVosParts = GetPartitionTableFromVos(cVosParts);
401 // We have two partition tables, one from the registry and one from the vos
402 // library. The one from the vos library tells us the partitions that are
403 // currently exported. The one from the registry tells us the partitions
404 // that will be exported after the file server restarts. The registry list
405 // should always be at least as big as the vos list. The vos list can be
406 // smaller if one of the disks could not be exported. To add a new partition,
407 // an entry must be added to the registry table and then the file server must
408 // be restarted. To remove an entry, the partition must not be exported (due
409 // to an error) or the file server must not be running, in which case nothing
412 // To display the partitions to the user, we use the list from the registry,
413 // looking up each of its entries in the vos list to see if it is exported,
414 // and if it is, to get its size info.
417 for (int nCurRegPart = 0; nCurRegPart < cRegParts; nCurRegPart++) {
418 LPTSTR pPartNameAsString = AnsiToString(pRegParts[nCurRegPart].partitionName);
420 // Show the partition in the list
421 FASTLISTADDITEM ai = { 0, DISK_DRIVE_IMAGE, IMAGE_NOIMAGE, pPartNameAsString, 0, 0 };
422 HLISTITEM hItem = FastList_AddItem(hPartitionList, &ai);
424 FreeString(pPartNameAsString);
426 FastList_SetItemText(hPartitionList, hItem, 1, pRegParts[nCurRegPart].deviceName);
428 // For the rest of the info we need to know if this guy is exported.
429 // Look him up in the vos table.
430 BOOL bExported = FALSE;
434 for (int nCurVosPart = 0; nCurVosPart < cVosParts; nCurVosPart++) {
435 if (stricmp(pVosParts[nCurVosPart].name, pRegParts[nCurRegPart].partitionName) == 0) {
437 nTotalSpace = pVosParts[nCurVosPart].totalSpace;
438 nFreeSpace = pVosParts[nCurVosPart].totalFreeSpace;
443 FastList_SetItemText(hPartitionList, hItem, 2, bExported ? szYes : szNo);
444 FastList_SetItemText(hPartitionList, hItem, 3, bExported ? DiskSpaceToString(nTotalSpace) : TEXT(""));
445 FastList_SetItemText(hPartitionList, hItem, 4, bExported ? DiskSpaceToString(nFreeSpace) : TEXT(""));
447 // Set the item param to indicate that this partition is exported or not
448 FastList_SetItemParam(hPartitionList, hItem, bExported);
454 static void CheckEnableSalvage()
456 ENABLE_STATE es = (FastList_GetItemCount(hPartitionList) > 0) ? ES_ENABLE : ES_DISABLE;
458 SetEnable(hDlg, IDC_SALVAGE, es);
459 SetEnable(hDlg, IDC_SALVAGE_MSG, es);