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 <afs/param.h>
24 #include "create_partition_dlg.h"
25 #include "partition_utils.h"
26 #include "salvage_results_dlg.h"
28 #include <afs\afs_vosAdmin.h>
29 #include <afs\afs_clientAdmin.h>
33 // TODO: Add context menu to fastlist
37 * DEFINITIONS _________________________________________________________________
40 #define MAX_PARTITIONS 26
43 static HWND hPartitionList = 0;
44 static HLISTITEM hSelectedItem;
46 static TCHAR szYes[cchRESOURCE];
47 static TCHAR szNo[cchRESOURCE];
49 static const UINT DISK_DRIVE_IMAGE = 0;
50 //static const UINT DISABLED_DISK_DRIVE_IMAGE = 1;
51 //static const UINT DISK_DRIVE_WITH_WARNING_IMAGE = 2;
53 // Remember the config state of the FS so we can detect when it changes.
54 // When it changes we must redisplay the partition info.
55 static CONFIG_STATE configFS;
60 * PROTOTYPES _________________________________________________________________
63 BOOL ShowSalvageDlg(HWND hParent, LPCTSTR pszPartitionName);
65 static void OnCreatePartitions();
66 static void OnInitDialog(HWND hwndDlg);
67 static void SetupListCols();
68 static void AddColumn(int nWidth, LPCTSTR pszTitle, DWORD dwFlags = FLCF_JUSTIFY_LEFT);
69 static void ShowPartitions();
70 cfg_partitionEntry_t *GetPartitionTableFromRegistry(int& cEntries);
71 static vos_partitionEntry_t *GetPartitionTableFromVos(int &nNumPartitions);
72 static void OnListSelection(LPFLN_ITEMSELECT_PARAMS pItemParms);
73 static void SetupImageLists();
74 static void OnRemove();
75 static BOOL CheckShowPartitions();
76 static void OnSalvage();
77 static void CheckEnableSalvage();
81 * EXPORTED FUNCTIONS _________________________________________________________________
85 * Dialog Proc _________________________________________________________________
88 BOOL CALLBACK PartitionsPageDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
90 if (AfsAppLib_HandleHelp(IDD_PARTITIONS_PAGE, hwndDlg, uMsg, wParam, lParam))
95 OnInitDialog(hwndDlg);
99 switch (LOWORD(wParam)) {
101 CheckShowPartitions();
104 case IDC_CREATE_PARTITIONS:
105 OnCreatePartitions();
119 if ((((LPNMHDR)lParam)->code) == FLN_ITEMSELECT)
120 OnListSelection((LPFLN_ITEMSELECT_PARAMS)lParam);
127 void UpdatePartitionList()
130 CheckEnableSalvage();
135 * STATIC FUNCTIONS _________________________________________________________________
140 * Event Handler Functions _________________________________________________________________
143 static void OnInitDialog(HWND hwndDlg)
147 // PropSheet_CancelToClose(GetParent(hDlg));
151 hPartitionList = GetDlgItem(hDlg, IDC_PARTITION_LIST);
152 _ASSERTE(hPartitionList);
156 GetString(szYes, IDS_YES);
157 GetString(szNo, IDS_NO);
161 configFS = g_CfgData.configFS;
165 CheckEnableSalvage();
168 static void OnCreatePartitions()
170 if (CreatePartition(hDlg))
174 static void OnListSelection(LPFLN_ITEMSELECT_PARAMS pItemParms)
178 hSelectedItem = pItemParms->hItem;
180 ENABLE_STATE es = pItemParms->hItem ? ES_ENABLE : ES_DISABLE;
182 SetEnable(hDlg, IDC_REMOVE, es);
183 SetEnable(hDlg, IDC_REMOVE_MSG, es);
186 static void OnRemove()
188 ASSERT(hSelectedItem);
191 afs_status_t nStatus;
193 BOOL bExported = (BOOL)FastList_GetItemParam(hPartitionList, hSelectedItem);
195 MsgBox(hDlg, IDS_CANT_DELETE_EXPORTED_PARTITION, GetAppTitleID(), MB_OK | MB_ICONSTOP);
199 LPCTSTR pszPartitionName = FastList_GetItemText(hPartitionList, hSelectedItem, 0);
200 ASSERT(pszPartitionName);
202 int nResult = Message(MB_ICONQUESTION | MB_YESNO, GetAppTitleID(), IDS_DELETE_PARTITION_PROMPT, TEXT("%s"), pszPartitionName);
206 g_LogFile.Write("Removing partition '%s'.\r\n", (char *)S2A(pszPartitionName));
207 nResult = cfg_HostPartitionTableRemoveEntry(g_hServer, S2A(pszPartitionName), &nStatus);
209 ShowError(hDlg, nStatus, IDS_REMOVE_PARTITION_ERROR);
213 FastList_RemoveItem(hPartitionList, hSelectedItem);
215 CheckEnableSalvage();
218 static void OnSalvage()
220 // Can't salvage if the file server is not configured
221 if (!Configured(g_CfgData.configFS)) {
222 ShowError(hDlg, 0, IDS_CANT_SALVAGE_WHEN_FS_NOT_CONFIGURED);
226 LPCTSTR pszPartitionName = TEXT("");
229 pszPartitionName = FastList_GetItemText(hPartitionList, hSelectedItem, 0);
230 ASSERT(pszPartitionName);
233 if (!ShowSalvageDlg(hDlg, pszPartitionName))
236 ShowSalvageResults(hDlg);
238 // Since a salvage was performed, there may be partitions exported that were
239 // not exported before the salvage. Salvage may stop and restart the file
240 // server, which will pick up the previously unexported partitions. We will
241 // update our partition list in case this has happened.
242 UpdatePartitionList();
247 * Utility Functions _________________________________________________________________
250 static BOOL CheckShowPartitions()
252 if (configFS != g_CfgData.configFS) {
253 configFS = g_CfgData.configFS;
254 UpdatePartitionList();
261 static void SetupImageLists()
263 HIMAGELIST hiList = ImageList_Create(16, 16, TRUE, 1, 1);
265 AfsAppLib_AddToImageList(hiList, IDI_AGGREGATE, FALSE);
266 AfsAppLib_AddToImageList(hiList, IDI_DISABLED_DISK_DRIVE, FALSE);
268 FastList_SetImageLists(hPartitionList, hiList, 0);
271 static void AddColumn(int nWidth, LPCTSTR pszTitle, DWORD dwFlags)
276 col.dwFlags = dwFlags;
277 col.cxWidth = nWidth;
278 lstrcpy(col.szText, pszTitle);
280 FastList_SetColumn(hPartitionList, nCol++, &col);
283 static void SetupListCols()
285 TCHAR szMsg[cchRESOURCE];
287 AddColumn(75, GetResString(IDS_NAME, szMsg));
288 AddColumn(55, GetResString(IDS_DRIVE, szMsg));
289 AddColumn(60, GetResString(IDS_EXPORTED, szMsg));
290 AddColumn(75, GetResString(IDS_TOTAL, szMsg), FLCF_JUSTIFY_RIGHT);
291 AddColumn(75, GetResString(IDS_FREE, szMsg), FLCF_JUSTIFY_RIGHT);
294 cfg_partitionEntry_t *GetPartitionTableFromRegistry(int& cEntries)
296 afs_status_t nStatus;
298 // Read the parition table out of the registry
299 int nResult = ReadPartitionTable(&nStatus);
301 ShowError(hDlg, nStatus, IDS_READ_PARTITIONS_ERROR);
305 return GetPartitionTable(cEntries);
308 static vos_partitionEntry_t *GetPartitionTableFromVos(int &nNumPartitions)
311 ASSERT(g_CfgData.szHostname[0]);
315 if (g_CfgData.configFS != CS_ALREADY_CONFIGURED)
318 static vos_partitionEntry_t aPartitions[MAX_PARTITIONS];
319 afs_status_t nStatus, nIgnore;
324 g_LogFile.Write("Opening server %s.\r\n", GetHostnameA());
325 int nResult = vos_ServerOpen(g_hCell, GetHostnameA(), &hServer, &nStatus);
328 // Read the partition info
329 g_LogFile.Write("Reading paritition information for this server.\r\n");
332 nResult = vos_PartitionGetBegin(g_hCell, hServer, 0, &iterID, &nStatus);
334 while (nNumParts < MAX_PARTITIONS) {
335 nResult = vos_PartitionGetNext(iterID, &aPartitions[nNumParts], &nStatus);
337 if (nStatus == ADMITERATORDONE) {
346 vos_PartitionGetDone(iterID, &nIgnore);
348 vos_ServerClose(hServer, &nIgnore);
352 ShowError(hDlg, nStatus, IDS_GET_PARTITION_LIST_ERROR);
356 nNumPartitions = nNumParts;
361 // Convert a disk space value in Kbytes into a string
362 static LPTSTR DiskSpaceToString(int nSpace)
364 const float oneMB = 1024; // in K bytes
365 const double oneGB = oneMB * 1024;
366 const double oneTB = oneGB * 1024;
368 static TCHAR szSpace[64];
374 if (space >= oneTB) {
376 pszUnits = TEXT(" TB");
377 } else if (space >= oneGB) {
379 pszUnits = TEXT(" GB");
380 } else if (space >= oneMB) {
382 pszUnits = TEXT(" MB");
384 pszUnits = TEXT(" KB");
386 int nNumDecimals = 0;
387 if (space - double(int(space)) > 0)
390 _stprintf(szSpace, TEXT("%3.*f%s"), nNumDecimals, space, pszUnits);
395 static void ShowPartitions()
397 FastList_RemoveAll(hPartitionList);
399 int cRegParts = 0, cVosParts = 0;
401 // If we got nothing from the registry, then leave the list empty
402 cfg_partitionEntry_t *pRegParts = GetPartitionTableFromRegistry(cRegParts);
406 // If we failed to get vos info, then only show the registry info
407 vos_partitionEntry_t *pVosParts = GetPartitionTableFromVos(cVosParts);
411 // We have two partition tables, one from the registry and one from the vos
412 // library. The one from the vos library tells us the partitions that are
413 // currently exported. The one from the registry tells us the partitions
414 // that will be exported after the file server restarts. The registry list
415 // should always be at least as big as the vos list. The vos list can be
416 // smaller if one of the disks could not be exported. To add a new partition,
417 // an entry must be added to the registry table and then the file server must
418 // be restarted. To remove an entry, the partition must not be exported (due
419 // to an error) or the file server must not be running, in which case nothing
422 // To display the partitions to the user, we use the list from the registry,
423 // looking up each of its entries in the vos list to see if it is exported,
424 // and if it is, to get its size info.
427 for (int nCurRegPart = 0; nCurRegPart < cRegParts; nCurRegPart++) {
428 LPTSTR pPartNameAsString = AnsiToString(pRegParts[nCurRegPart].partitionName);
430 // Show the partition in the list
431 FASTLISTADDITEM ai = { 0, DISK_DRIVE_IMAGE, IMAGE_NOIMAGE, pPartNameAsString, 0, 0 };
432 HLISTITEM hItem = FastList_AddItem(hPartitionList, &ai);
434 FreeString(pPartNameAsString);
436 FastList_SetItemText(hPartitionList, hItem, 1, pRegParts[nCurRegPart].deviceName);
438 // For the rest of the info we need to know if this guy is exported.
439 // Look him up in the vos table.
440 BOOL bExported = FALSE;
444 for (int nCurVosPart = 0; nCurVosPart < cVosParts; nCurVosPart++) {
445 if (stricmp(pVosParts[nCurVosPart].name, pRegParts[nCurRegPart].partitionName) == 0) {
447 nTotalSpace = pVosParts[nCurVosPart].totalSpace;
448 nFreeSpace = pVosParts[nCurVosPart].totalFreeSpace;
453 FastList_SetItemText(hPartitionList, hItem, 2, bExported ? szYes : szNo);
454 FastList_SetItemText(hPartitionList, hItem, 3, bExported ? DiskSpaceToString(nTotalSpace) : TEXT(""));
455 FastList_SetItemText(hPartitionList, hItem, 4, bExported ? DiskSpaceToString(nFreeSpace) : TEXT(""));
457 // Set the item param to indicate that this partition is exported or not
458 FastList_SetItemParam(hPartitionList, hItem, bExported);
462 static void CheckEnableSalvage()
464 ENABLE_STATE es = (FastList_GetItemCount(hPartitionList) > 0) ? ES_ENABLE : ES_DISABLE;
466 SetEnable(hDlg, IDC_SALVAGE, es);
467 SetEnable(hDlg, IDC_SALVAGE_MSG, es);